Hello there,
Following a Slack conversation with @Lyrkan, I have detected an unexpected behaviour with the following scenario:
yarn watch daemon running in backgroundWhat's wrong:
Although changes in dynamic imports are properly detected by yarn watch (a compile task is triggered), it's still the old chunk that gets called during the Ajax request related to the import() function.
Steps to reproduce:
./assets/app/dynamic.js and console.log('foo') inside it./assets/app/app.js and write import('./dynamic.js')Encore.enableVersioning(true)Encore.addEntry('app', './assets/app/app.js')yarn watch and check your console log in the browser, it should display fooconsole.log('bar'): yarn watch will detect changes and compilefoo.yarn watch, launch it back again, and refresh your browser: it should now display bar.Visible cause:
runtime.js still references the old import chunk. Example:
yarn watch
Files generated:
vendors~app.e4eaffae.js
app.43ccc91a.js
0.c686782a.js
1.47b280f0.js (file that will be called by an ajax request)
runtime.23bc6e15.js (referencing 1.47b280f0.js)
_* Edit dynamically imported file *_
Files generated:
vendors~app.e4eaffae.js (unchanged)
app.43ccc91a.js (unchanged)
0.c686782a.js (unchanged)
1.58820a65.js (changed)
runtime.021c84f2.js (changed, but still referencing 1.47b280f0.js)
Additionnal Notes:
I suspect this is rather a bug in webpack than in Encore. I don't think we customize the building of the runtime file.
@stof Yep, that's @Lyrkan's opinion as well. But even if this can be solved let's keep it for the records, in case someone having the same troubles is looking for support, or if we want to document this.
Yeah, it looks like a bug in Webpack but I'm not 100% certain about it...
I tried reproducing the issue with a really basic setup (without Encore) and it seems to work fine.
// webpack.config.js
module.exports = {
mode: 'development',
output: {
filename: '[name].[contenthash:8].js',
},
optimization: {
runtimeChunk: 'single',
},
};
// src/index.js
import('./dynamic.js');
// src/dynamic.js
console.log('Foo');
$./node_modules/.bin/webpack --watch
webpack is watching the files…
Hash: 831fd1ed75b526570d79
Version: webpack 4.35.3
Time: 111ms
Built at: 07/09/2019 3:46:00 PM
Asset Size Chunks Chunk Names
0.64984b7e.js 343 bytes 0 [emitted]
main.fb4816a9.js 496 bytes main [emitted] main
runtime.bb95a825.js 8.9 KiB runtime [emitted] runtime
Entrypoint main = runtime.bb95a825.js main.fb4816a9.js
[./src/dynamic.js] 20 bytes {0} [built]
[./src/index.js] 24 bytes {main} [built]
$ grep 64984b7e dist/runtime.bb95a825.js
/******/ return __webpack_require__.p + "" + ({}[chunkId]||chunkId) + "." + {"0":"64984b7e"}[chunkId] + ".js"
After replacing console.log('Foo') by console.log('Bar'):
Hash: d88f849a462184fad5dc
Version: webpack 4.35.3
Time: 15ms
Built at: 07/09/2019 3:46:30 PM
Asset Size Chunks Chunk Names
0.dd16fd12.js 343 bytes 0 [emitted]
runtime.1f052d70.js 8.9 KiB runtime [emitted] runtime
+ 1 hidden asset
Entrypoint main = runtime.1f052d70.js main.fb4816a9.js
[./src/dynamic.js] 20 bytes {0} [built]
+ 1 hidden module
$ grep 64984b7e dist/runtime.1f052d70.js
$ grep dd16fd12 dist/runtime.1f052d70.js
/******/ return __webpack_require__.p + "" + ({}[chunkId]||chunkId) + "." + {"0":"dd16fd12"}[chunkId] + ".js"
I can however reproduce it with the following webpack.config.js file and Encore:
const Encore = require('@symfony/webpack-encore');
Encore
.enableSingleRuntimeChunk()
.setOutputPath('dist/')
.setPublicPath('/')
.addEntry('main', './src/index.js')
.enableVersioning()
;
module.exports = Encore.getWebpackConfig();
$ ./node_modules/.bin/encore dev --watch
Running webpack ...
webpack is watching the files…
DONE Compiled successfully in 697ms 4:05:01 PM
I 3 files written to dist
Entrypoint main = runtime.0293b661.js main.26cadb5f.js
$ grep 3cc0512d dist/runtime.0293b661.js
/******/ return __webpack_require__.p + "" + ({}[chunkId]||chunkId) + "." + {"0":"3cc0512d"}[chunkId] + ".js"
After replacing console.log('Foo') by console.log('Bar'):
WAIT Compiling...
DONE Compiled successfully in 19ms
I 3 files written to dist
Entrypoint main = runtime.fbcb1962.js main.26cadb5f.js
$ grep 3cc0512d dist/runtime.fbcb1962.js
/******/ return __webpack_require__.p + "" + ({}[chunkId]||chunkId) + "." + {"0":"3cc0512d"}[chunkId] + ".js"
So it looks like it's caused by WebpackChunkHash.
It is added automatically when enableVersioning() is called in order to support the [chunkhash] placeholder... but I'm not sure we need it anymore, especially since we also deprecated its use a while ago:
@bpolaszek Could you check if the following code fixes the issue on your project?
// webpack.config.js
const Encore = require('@symfony/webpack-encore');
const WebpackChunkHash = require('webpack-chunk-hash');
Encore
.enableSingleRuntimeChunk()
// (...)
;
const config = Encore.getWebpackConfig();
config.plugins = config.plugins.filter(plugin => {
return !(plugin instanceof WebpackChunkHash);
});
module.exports = config;
Good job @Lyrkan! I confirm removing this plugin actually solves the problem.
Works for me! Thanks
Most helpful comment
Good job @Lyrkan! I confirm removing this plugin actually solves the problem.