HtmlWebpackPlugin inietta file di percorso relativo che si interrompono durante il caricamento di percorsi di siti Web non root


115

Sto usando webpack e HtmlWebpackPlugin per iniettare js e css in bundle in un file modello html.

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

E produce il seguente file html.

<!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>

Funziona bene quando visito la radice dell'app localhost:3000/, ma non riesce quando provo a visitare l'app da un altro URL, ad esempio, localhost:3000/items/1perché i file in bundle non vengono iniettati con un percorso assoluto. Quando il file html viene caricato, cercherà il file js all'interno della /itemsdirectory inesistente perché reatt-router non è ancora stato caricato.

Come posso fare in modo che HtmlWebpackPlugin inietti i file con un percorso assoluto, quindi Express li cercherà nella radice della mia /distdirectory e non in /dist/items/main-...min.js? O forse posso cambiare il mio server espresso per aggirare il problema?

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

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

In sostanza, ho solo bisogno di ottenere la linea:

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

per avere una barra all'inizio della sorgente.

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

Risposte:


199

Prova a impostare publicPath nella configurazione del tuo webpack:

output.publicPath = '/'

HtmlWebpackPlugin usa publicPath per anteporre gli URL degli inject.

Un'altra opzione è impostare l'href di base nel <head>tuo modello html, per specificare l'URL di base di tutti gli URL relativi nel tuo documento.

<base href="http://localhost:3000/">

7
Grazie, l'aggiunta è output.publicPath = '/'stata la soluzione.
aherriot

3
Questo non funzionerà se stai utilizzando un proxy inverso.
t-my

4
Potresti anche usarlo semplicemente <base href="https://stackoverflow.com/">per evitare di dover codificare il nome host nel modello HTML o di dover interpolare le variabili.
Rafa

Ho dovuto impostare publicPath = '' e aggiungere <base href = "~ / dist /"> poiché il mio sito è un progetto ASP.Net MVC che utilizza IIS e una directory virtuale.
scherzo più urgente

16

Infatti ho dovuto mettere:

output.publicPath: './';

in modo che funzioni in un percorso non ROOT. Allo stesso tempo stavo iniettando:

   baseUrl: './'

in

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

Con entrambi i parametri impostati, ha funzionato a meraviglia.


Questo mostra il URLbrowser attivo come https://localhost/myproject/%3C%=%20htmlWebpackPlugin.options.baseUrl%20%%3E#/project/1. C'è un modo per risolverlo?
NehaM

Dove stai impostando baseUrl: '.'è nelle opzioni HtmlWebpackPlugin? { meta: { baseUrl: './' } }?
Qualcosa il

@ QualcosaOn Non ho questo progetto webpack a portata di mano in questo momento e penso che molte cose siano cambiate da quando ho pubblicato questa risposta (incluso il valore predefinito). Quindi sì, questo è certamente dove dovrebbe essere impostato, ma './'è il valore corretto.
Kevin FONTAINE

1
Ora può iniettare direttamente il tag di base. inject base tag
Liang

2

nella configurazione del webpack

config.output.publicPath = ''

nel tuo index.html

<base href="/someurl/" />

questo dovrebbe farlo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.