HtmlWebpackPlugin fügt relative Pfaddateien ein, die beim Laden von Nicht-Root-Website-Pfaden unterbrochen werden

113

Ich verwende Webpack und das HtmlWebpackPlugin, um gebündelte JS und CSS in eine HTML-Vorlagendatei zu injizieren.

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

Und es erzeugt die folgende HTML-Datei.

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

Dies funktioniert gut, wenn Sie das Stammverzeichnis der App localhost:3000/besuchen, schlägt jedoch fehl, wenn ich versuche, die App von einer anderen URL aus zu besuchen, z. B. localhost:3000/items/1weil den gebündelten Dateien kein absoluter Pfad zugewiesen wird. Wenn die HTML-Datei geladen wird, sucht sie nach der JS-Datei im nicht vorhandenen /itemsVerzeichnis, da der React -Router noch nicht geladen wurde.

Wie kann ich HtmlWebpackPlugin dazu bringen, die Dateien mit einem absoluten Pfad zu injizieren, sodass Express sie im Stammverzeichnis meines /distVerzeichnisses sucht und nicht unter /dist/items/main-...min.js? Oder kann ich meinen Express-Server ändern, um das Problem zu umgehen?

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

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

Im Wesentlichen muss ich nur die Zeile bekommen:

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

am Anfang der Quelle einen Schrägstrich haben.

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

Antworten:

198

Versuchen Sie, den publicPath in Ihrer Webpack-Konfiguration festzulegen:

output.publicPath = '/'

HtmlWebpackPlugin verwendet den publicPath, um die URLs der Injektionen voranzustellen.

Eine andere Möglichkeit besteht darin, die Basis-HREF in der <head>HTML-Vorlage festzulegen und die Basis-URL aller relativen URLs in Ihrem Dokument anzugeben.

<base href="http://localhost:3000/">
Magnus Sjungare
quelle
7
Vielen Dank, Hinzufügen output.publicPath = '/'war die Lösung.
aherriot
3
Dies funktioniert nicht, wenn Sie hinter einem Reverse-Proxy arbeiten.
t-my
4
Sie können auch einfach verwenden <base href="https://stackoverflow.com/">, um zu vermeiden, dass der Hostname in der HTML-Vorlage fest codiert oder Variablen interpoliert werden müssen.
Rafa
Ich musste publicPath = '' setzen und <base href = "~ / dist /"> hinzufügen, da meine Site ein ASP.Net MVC-Projekt ist, das IIS und ein virtuelles Verzeichnis verwendet.
dringenderer Scherz
16

In der Tat musste ich sagen:

output.publicPath: './';

damit es in einem Nicht-ROOT-Pfad funktioniert. Zur gleichen Zeit spritzte ich:

   baseUrl: './'

in

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

Mit beiden Parametersätzen funktionierte es wie ein Zauber.

Kevin FONTAINE
quelle
Dies zeigt den URLOn-Browser als https://localhost/myproject/%3C%=%20htmlWebpackPlugin.options.baseUrl%20%%3E#/project/1. Gibt es eine Möglichkeit, dies zu lösen?
NehaM
Wo stellen Sie baseUrl: '.'es in den HtmlWebpackPlugin-Optionen ein? { meta: { baseUrl: './' } }?
Etwas
@SomethingOn Ich habe dieses Webpack-Projekt derzeit nicht zur Hand und ich denke, viele Dinge haben sich geändert, seit ich diese Antwort gepostet habe (einschließlich des Standardwerts). Also ja, hier sollte es sicherlich eingestellt werden, aber es './'ist der richtige Wert.
Kevin FONTAINE
1
Jetzt kann es das Basis-Tag direkt injizieren. Inject Base Tag
Liang
2

in der Webpack-Konfiguration

config.output.publicPath = ''

in Ihrer index.html

<base href="/someurl/" />

das sollte es tun.

hannad rehman
quelle