I am trying to generate assets url in a specific format, the urls should be like this ?path=application.js instead of just application.js. So I configured publicPath to be ?path=:
module.exports = {
entry: './index.ts',
output: {
filename: 'application.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '?path='
},
module: {
// ...
},
plugins: [
new HtmlWebpackPlugin({ template: "index.placeholder.html" })
]
}
And I see it works for other loaders, for example ExtractTextPlugin generates css like this:
@font-face {
font-family: 'Glyphicons Halflings';
src: url(?path=f4769f9bdb7466be65088239c12046d1.eot); /* correct url here */
}
But HtmlWebpackPlugin adds the '/' after publicPath (application.css transforms to `/application.css``):
<link href="?path=/application.css" rel="stylesheet"></head>
Here it is in the code:
if (publicPath && publicPath.substr(-1) !== '/') {
publicPath += '/';
}
Is it correct behavior? It looks strange that different plugins treat publicPath in a different ways...
That definitely look like a bug
Although, I believe the code you pointed to, only impact favicon
Would you mind sending us a PR with a failing unit test (or even better with a fix ;) ), so we can have a better look at it
I'm trying to build my project so it can be run in a non-root path. For example, my app is going to be served at this url: https://www.example.com/somewhere/
So I use this setting in my config:
output: {
path: path.join(__dirname, 'dist'),
publicPath: './',
filename: 'myapp.[hash].bundle.js'
},
This plugin injects my javascript as
<script type="text/javascript" src="/myapp.c4769857294680bef977.bundle.js"></script>
So that means it can't load the javascript because it's looking at
https://www.example.com/myapp.c4769857294680bef977.bundle.js
instead of
https://www.example.com/somewhere/myapp.c4769857294680bef977.bundle.js
The weird part is that when I run the dev server it fails because of the extra '/' character. But when I just run webpack to build my production files it doesn't add the extra '/', so it works fine.
I worked around this problem by using an environment variable to tell the difference between dev and prod:
output: {
path: path.join(__dirname, 'dist'),
publicPath: (process.env.NODE_ENV==='dev'?'/':'./'),
filename: 'myapp.[hash].bundle.js'
},
Then in my package.json I add the environment variable to the respective scripts:
"scripts":{
"dev-server": "NODE_ENV=dev webpack-dev-server --host=0.0.0.0 --content-base dist/ --history-api-fallback",
"build": "NODE_ENV=production npm-run-all lint validate clean --parallel copy:fonts buildwp",
"buildwp": "webpack"
}
@mnebuerquo I don't thing that the same issue, just set publicPath to ''
Have a similar issue:
In production I'm serving my static assets, generated by Webpack, from聽/static/聽path, e.g.聽https://example.com/static/app[hash:7].js. I want to reproduce that behavior in development server.
Thing is, I generate聽index.html聽with injected statics with聽HtmlWebpackPlugin. And when I set聽devServer.publicPath = '/static/', it starts serving my index.html from聽localhost:8080:/static/, which is completely undesired.
webpack.config.js:
module.exports = {
...
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/static/',
filename: 'app.[hash:7].js'
},
plugins: [
new HtmlWebpackPlugin({
inject: "body",
template: "src/index.html",
filename: "index.html"
}),
],
...
devServer: {
publicPath: '/static/',
contentBase: './dist',
hot: true },
}
How do I make webpack-dev-server serve index.html from聽localhost:8080/, but serve the static assets from聽localhost:8080/static/...?
@BurkovBA This is a different issue...
I suggest you do:
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: 'static/app.[hash:7].js'
},
@mastilver
Ugly hack, but it works. Thanks! =)
I believe, this needs to be fixed, though - the way I see it, index.html isn't supposed to be affected by publicPath. Or are we supposed to use externals for it?
I'll submit a unit-test to BasicSpec.js.
I think I misunderstood your issue, because I don't believe it's an issue
Submitting a failing test, is the best way for us to understand an issue so go ahead ;)
@mastilver you see, there is a small inconsistency between devServer and build modes:
Such config that uses publicPath works while build, but not while dev mode:
output: {
path: 'dist/bundles',
publicPath: '/bundles/'
},
devServer: {
publicPath: '/bundles/'
},
plugins: [
new HtmlWebpackPlugin({
filename: '../index.html' // make index.html be placed in `dist`, not `dist/bundles`
})
]
Whle build chunks are placed to dist/bundles and index.html is placed in dist, so everything works.
But while serving with devServer, bundles are served from /bundle path, but index.html is not available at desired /index.html path.
As you mentioned, there is a workaround, without involving non-standard (non-root) publishPath:
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: 'bundles/[name].js'
},
This may work, but I think HtmlPlugin should allow consistently use standard publicPath option in build and dev modes.
I got this same problem and setting: webpackConfig.output.publicPath = '' solved my problem.
Not a bug, intentional.
It was intentional but it did not consider query strings or hash fragments
This issue had no activity for at least half a year. It's subject to automatic issue closing if there is no activity in the next 15 days.
Most helpful comment
@BurkovBA This is a different issue...
I suggest you do: