HtmlWebpackPlugin memasukkan file jalur relatif yang rusak saat memuat jalur situs web non-root

115

Saya menggunakan webpack dan HtmlWebpackPlugin untuk memasukkan js dan css yang dibundel ke dalam file template html.

new HtmlWebpackPlugin({
   template: 'client/index.tpl.html',
   inject: 'body',
   filename: 'index.html'
}),

Dan itu menghasilkan file html berikut.

<!doctype html>
<html lang="en">
  <head>
    ...
    <link href="main-295c5189923694ec44ac.min.css" rel="stylesheet">
  </head>
  <body>
    <div id="app"></div>
    <script src="main-295c5189923694ec44ac.min.js"></script>
  </body>
</html>

Ini berfungsi dengan baik saat mengunjungi root aplikasi localhost:3000/, tetapi gagal saat saya mencoba mengunjungi aplikasi dari URL lain, misalnya, localhost:3000/items/1karena file yang dibundel tidak dimasukkan dengan jalur absolut. Ketika file html dimuat, itu akan mencari file js di dalam /itemsdirektori yang tidak ada karena react-router belum dimuat.

Bagaimana saya bisa mendapatkan HtmlWebpackPlugin untuk memasukkan file dengan path absolut, jadi express akan mencarinya di root /distdirektori saya dan bukan di /dist/items/main-...min.js? Atau mungkin saya bisa mengubah server ekspres saya untuk mengatasi masalah ini?

app.use(express.static(__dirname + '/../dist'));

app.get('*', function response(req, res) {
  res.sendFile(path.join(__dirname, '../dist/index.html'));
});

Pada dasarnya, saya hanya perlu mendapatkan baris:

<script src="main...js"></script>

untuk memiliki garis miring di awal sumber.

<script src="/main...js></script>
aherriot
sumber

Jawaban:

199

Coba setel publicPath di konfigurasi webpack Anda:

output.publicPath = '/'

HtmlWebpackPlugin menggunakan publicPath untuk menambahkan url injeksi.

Pilihan lainnya adalah menyetel href dasar di <head>template html Anda, untuk menentukan url dasar dari semua url relatif dalam dokumen Anda.

<base href="http://localhost:3000/">
Magnus Sjungare
sumber
7
Terima kasih, menambahkan output.publicPath = '/'adalah solusinya.
aherriot
3
Ini tidak akan berfungsi jika Anda menggunakan reverse proxy.
t-my
4
Anda juga dapat menggunakan hanya <base href="https://stackoverflow.com/">untuk menghindari hardcode nama host di template HTML, atau harus menginterpolasi variabel.
Rafa
Saya harus menyetel publicPath = '' dan menambahkan <base href = "~ / dist /"> karena situs saya adalah proyek MVC ASP.Net menggunakan IIS dan direktori virtual.
lelucon yang lebih mendesak
16

Faktanya, saya harus meletakkan:

output.publicPath: './';

agar dapat berfungsi di jalur non-ROOT. Pada saat yang sama saya menyuntik:

   baseUrl: './'

ke

<base href="<%= htmlWebpackPlugin.options.metadata.baseUrl %>">

Dengan kedua set parameter, ini bekerja seperti pesona.

Kevin FONTAINE
sumber
Ini menunjukkan URLpada browser sebagai https://localhost/myproject/%3C%=%20htmlWebpackPlugin.options.baseUrl%20%%3E#/project/1. Apakah ada cara untuk mengatasi ini?
NehaM
Di mana Anda menyetelnya baseUrl: '.'di opsi HtmlWebpackPlugin? { meta: { baseUrl: './' } }?
Sesuatu Pada
@SomethingOn Saya tidak memiliki proyek webpack ini sekarang, dan saya pikir banyak hal telah berubah sejak saya memposting jawaban ini (termasuk nilai default). Jadi ya, ini pasti tempat yang harus ditetapkan, tetapi './'merupakan nilai yang benar.
Kevin FONTAINE
1
Sekarang dapat menyuntikkan tag dasar secara langsung. menyuntikkan tag dasar
Liang
2

dalam konfigurasi webpack

config.output.publicPath = ''

di index.html Anda

<base href="/someurl/" />

ini harus melakukannya.

hannad rehman
sumber