Search code examples
javascriptwebpackwebpack-2html-webpack-pluginwebpack-splitchunks

htmlWebPack plugin publicPath not working as expected


My webpack output:

output: {
    publicPath: path.join(basename, '/assets/'),
    path: `${__dirname}/built/core/assets/`,
    filename: '[name].[chunkhash].js',
},

index.html template:

<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script charset="utf-8" src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>

Now the problem is when the publicPath is set to path.join(basename, '/assets'), then index.html is resolved to:

<script charset="utf-8" src="\assets/bundle.d121bf175aece5f14af6.js"></script>

which is ok, however because i haven't added trailing slash to public path, in bundle.[hash].js file, chunks

script.src = __webpack_require__.p + "" + chunkId + "." + {"0":"24692a7f9ff51c72880c...
...
__webpack_require__.p = "\\assets";

are resolved to assets[id].[hash].js without slash and they're not found. However if i add trailing comma to publicPath(path.join(basename, '/assets/')) then the index.html is resolved to

<script charset="utf-8" src="\assets\/bundle.d121bf175aece5f14af6.js"></script>

and bundle.[hash].js file is not found then.

What am i missing in config?


Solution

  • In windows environment path.join(basename, '/assets/') -> '\assets'

    html-webpack-plugin would then check if there's an forward slash at then end of publicPath and if theres was none it would add it which in turn would resolve to bundle path being src="\assets\\/bundle.[hash].js".master

    The application was working in test / prod environments because on unix / macos environments, path.join(basename, '/assets/') -> '/assets/'.

    Added check to webpack config which in turn fixed the problem:

    const environment = process.env.NODE_ENV || 'development';
    const isDevelopment = environment === 'development';
    ...
    output: {
        publicPath: isDevelopment ? '/assets/' : path.join(basename, '/assets/'),
    }