Webpack 3 and Webpack 5 projects for reproducing TypeScript require.ensure issue.
The source code is exactly the same in each folder. The only difference is one builds with Webpack 3 and one builds with Webpack 5.
The issue is that code in TypeScript files does not seem to be influenced by the chunkName argument when loaded with require.ensure in Webpack 5. Instead of going into the specified chunk, it always gets added into the chunk of the caller. This massively breaks lazy loading in our code base.
In each folder, simply do:
- npm install
- npm run build
You can open ./dist/index.html directly from the file system to see the different behaviour.
The test case is very simple:
- index.js is the entry point in the default chunk
main. It does a dynamic import of ModuleA, assigning it tochunk1. - ModuleA.js contains an object with a function that is never invoked. The function uses
require.ensureto requireModuleBandModuleCinto chunkchunk2. - ModuleB.ts does nothing but export a class. The interesting thing is that it is a TS file.
- ModuleC.js does nothing but export an object. The interesting thing is that it is a JS file.
By default you’ll see chunk1 get loaded by the browser. In WP3, you can see that chunk1 contains only code from ModuleA, as expected. In WP5, you can see that chunk1 contains code from ModuleA and ModuleB.
- If you look in
index.jsyou’ll see a commented line at the top. If you uncomment that, it will invoke a function inModuleA. Now you’ll seechunk2loaded also. In WP3,chunk2will contain bothModuleBandModuleC, as expected. In WP5,chunk2contains onlyModuleC. - In the config file for the WP5 build, you’ll also see a commented out
splitChunksdefinition where I forceModuleBinto its own chunk calledchunk3. Make sure the line inindex.jscalling theModuleAfunction is commented out before building. This means that neitherchunk2norchunk3should be loaded. But you can see thatchunk3gets loaded (becauseModuleBis actually part ofchunk1notchunk2).