Search code examples
javascriptvue.jswebpackbase-path

__webpack_public_path__ does not work after reloading the page


We are working on a Vue.js application which is built with webpack. The requirement is that our application not only has to be accessible via the base path / but also via a custom path, so that the application could be accessable next to other services. With webpacks \__webpack_public_path__ I was able to set the base path on the fly regarding a specified base path, like if the current path has got /foo/ in it, the base path should start at .../foo/.

While navigating through the application everything looks good, as long as I open the app at the base path. The problem is that after I navigate to any sub path and reload the page, no files can be found. The server will first provide the index.html and there I need to use relative paths, since the base path must be determined dynamically. But if any other than the base path is opened, the relative paths in the index.html won't point to the correct bundle.js and the \__webpack_public_path__ will not be set...

Currently we have got two entry points in our webpack config. The first one is a JS file where we the global variable \__webpack_public_path__ will be set relatively based on the current visited URL. So lets say the base path should start at /foo/ and the visited URL is https://www.host.com/some/path/foo/sub/sub1. Therefore the relatively base path will be /some/path/foo/ and assets will be found at i.e. /some/path/foo/assets. All other paths used in the webpack config, like in the file-loader or any other plugin, are relative.

// webpack.config.js
...
module.exports = (env, argv) => ({
    ...
    entry: ['@babel/polyfill', './src/main/js/constants/webpack-public-path.js', './src/main/js/index.js'],
    output: {
        filename: 'assets/js/bundle.js',
        path: path.resolve(__dirname, relativeOutputPath),
        publicPath: '/'
    },
    module: {
        ...
        {
            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
            loader: 'file-loader',
            options: {
                name: 'assets/fonts/[name].[ext]'
            }
        }
        ...
    },
    ...
});


// webpack-public-path.js
__webpack_public_path__ = (() => {
    const BASE_PATH = '/foo/';
    let path = window.location.pathname;
    return path.includes(BASE_PATH) ? path.substring(0, path.indexOf(BASE_PATH) + BASE_PATH.length) : '/';
})();

Has anyone ever faced a similar problem? Is it possible, that the relative paths in the index.html can be defined afterwards or maybe are defined at build time by webpack?


Solution

  • I got a solution for my problem. What I had to do was to load all necessary assets manually in the index.html. Unfortunatly I have to maintain the determination of the dynamic base path on two different files (index.html and the webpack-public-path.js) but at least it's working now. So in the index.html I insert respective tags into the DOM manually and therefore load all needed assets based on the determined base path.