Laravel-mix: Webpack dynamic chunk loading not working because of publicPath setting

Created on 25 Jan 2017  路  12Comments  路  Source: JeffreyWay/laravel-mix

I have a single page application and use vue-router in combination with async components. Webpack therefore creates separate chunks for each page and they are loaded when the user wants to access the route.

Dynamic chunk loading is not working right now because of the output.publicPath setting. In the default Mix configuration, webpack output.publicPath is set to ./ and javascript files have the path /js/[name].js.

When webpack wants to load a new chunk, then it inserts a script tag:

script.src = __webpack_require__.p + "/js/" + chunkId + ".js";

where __webpack_require__.p = "./" because of the mentioned publicPath setting.

For chunk id 7, the resulting path is .//js/7.js and will be expanded to http://localhost:8000//js/7.js.
But the php artisan serve webserver does not deliver the public/js/7.js file because of the additional / in the url. Instead, we get a 404 error.

Even worse, when we are on a vue-router route user/17/edit and webpack wants to load chunk 7, then the resulting url is http://localhost:8000/user/17/edit/js/7.js and it will obviously not work.

We cannot just change publicPath to / (without .), because then we will get //js/7.js which is in fact http://js/7.js and makes no sense either.

The cleanest solution probably is the following:

  • Webpack's output.publicPath will be set to / in normal operation. When using HMR, then the path should be http://localhost:8080/. This can be achieved by modifying this line.
  • Script names should not start with a leading slash, i.e. the names are js/app.js, js/7.js, ...
    This can be achieved by modifying this line to .replace(this.publicPath + '/', '').
  • The Manifest.transform function will ensure that all paths in the mix-manifest.json file will start with a slash as required by laravels mix helper function.
    This can be achieved by inserting if (!path.startsWith('/')) path = '/' + path; above this line.

Please let me know what you think of my proposed solution. If you agree, then I'll create a PR.

Most helpful comment

@SebastianS90

I encountered a similar problem today, my somewhat dirty fix is:

.webpackConfig({ output: { filename: '[name].js', chunkFilename: 'js/[name].app.js', publicPath: '/' } });

Hope it helps you too.

All 12 comments

@SebastianS90

I encountered a similar problem today, my somewhat dirty fix is:

.webpackConfig({ output: { filename: '[name].js', chunkFilename: 'js/[name].app.js', publicPath: '/' } });

Hope it helps you too.

@JeffreyWay I just created a simple repo to demonstrate the problems.
With Mix 0.5.13 the behavior I get is:

  • Chunks are stored directly in /public
  • When entering the page at /foo/bar, then the chunk is loaded as /foo/1.js and fails

@rdgout your "fix" is not working with HMR enabled, because it overwrites publicPath
I temporarily fixed the problem (more or less as described in the issue), but that tends to break with updates of Mix.

I have the same issue with laravel-mix 1.2.1
Seems like the fix was removed?

I'm having the same issue too, please revert this fix

@rdgout Saved me hours of figuring out. Thank you!

I'm using this with laravel-mix 2.0.0 in order to have chunks work with HMR, dev and prod

if (mix.config.hmr) {
    mix.webpackConfig({
        output: {
            chunkFilename: '[name].js',
        }
    });
} else {
    mix.webpackConfig({
        output: {
            publicPath: '/',
            chunkFilename: '[name].[chunkhash].js',
        }
    });
}

@RichPC I had same error. And I solved problem by making it the same as your webpack.mix config.
But.. I have some question about this. I wonder why we should not use publicPach in HMR.

@MartinYounghoonKim I'm not sure what the underlying cause of the issue is, I came to that config work around from this comment https://github.com/JeffreyWay/laravel-mix/issues/164#issuecomment-275736546

I'm guessing there's a relative path problem for chunks in dev and prod builds, that doesn't exist in hmr builds.

@SebastianS90

I encountered a similar problem today, my somewhat dirty fix is:

.webpackConfig({ output: { filename: '[name].js', chunkFilename: 'js/[name].app.js', publicPath: '/' } });

Hope it helps you too.

This was the light at the end of the tunnel. THANK YOU!

@SebastianS90
I encountered a similar problem today, my somewhat dirty fix is:
.webpackConfig({ output: { filename: '[name].js', chunkFilename: 'js/[name].app.js', publicPath: '/' } });
Hope it helps you too.

This was the light at the end of the tunnel. THANK YOU!

For me the entire tunnel just lit up! :P Great fix, thanks @rdgout !

// webpack.mix.js
`mix.webpackConfig(webpack => {
return {
output: {
publicPath: '/',
filename: '[name].js',
chunkFilename: 'js/[name].js',
},
};
});

mix.babelConfig({
plugins: ['@babel/plugin-syntax-dynamic-import'],
});

mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');`

// app.js
const router = new VueRouter({ mode : 'history', routes : [ { path: '/home', name: 'admin.home', component: () => import(/* webpackChunkName : "home-component" / './components/admin/HomeComponent.vue') }, { path: '/restaurants', name: 'admin.restaurants.index', component: () => import(/ webpackChunkName : "restaurant-list" */'./components/admin/RestaurantIndexComponent.vue') }, ], });

But Still npm run dev/watch emitting 0.js, 1.js, rather than home-component.js , restaurant-list.js.

Please Help me out.

Here is the working config for Jigsaw:

const mix = require('laravel-mix');
const publicPath = 'source/assets/build'; 

require('laravel-mix-jigsaw');

mix.disableSuccessNotifications();
mix.setPublicPath(publicPath);

mix.jigsaw()
    .js('source/_assets/js/app.js', 'dist/app.js')
    .sass('source/_assets/scss/app.scss', 'dist/app.css')
    .webpackConfig({
        output: {
            publicPath: '/assets/build/',
            chunkFilename: 'dist/[name].[chunkhash].js',
        }
    })
    .version();

You can remove the stuff about dist folder.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jpmurray picture jpmurray  路  3Comments

Cheddam picture Cheddam  路  3Comments

rderimay picture rderimay  路  3Comments

mementoneli picture mementoneli  路  3Comments

nezaboravi picture nezaboravi  路  3Comments