diff --git a/.changeset/twenty-cougars-fall.md b/.changeset/twenty-cougars-fall.md new file mode 100644 index 0000000000..376148d6a4 --- /dev/null +++ b/.changeset/twenty-cougars-fall.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/template-webpack-plugin": patch +--- + +fix: merge different chunk groups for same output filename diff --git a/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/foo.js b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/foo.js new file mode 100644 index 0000000000..7cc7136793 --- /dev/null +++ b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/foo.js @@ -0,0 +1,3 @@ +export async function foo() { + return await Promise.resolve('**foo**'); +} diff --git a/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/index.jsx b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/index.jsx new file mode 100644 index 0000000000..6540c13d80 --- /dev/null +++ b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/index.jsx @@ -0,0 +1,9 @@ +// Extra dynamic import in background thread +if (__BACKGROUND__) { + import('./foo.js'); +} + +it('should have chunkName', async () => { + const { foo } = await import('./foo.js'); + await expect(foo()).resolves.toBe(`**foo**`); +}); diff --git a/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/rspack.config.js b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/rspack.config.js new file mode 100644 index 0000000000..ad05fbfc79 --- /dev/null +++ b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/rspack.config.js @@ -0,0 +1,60 @@ +import { + LynxEncodePlugin, + LynxTemplatePlugin, +} from '@lynx-js/template-webpack-plugin'; + +import { createConfig } from '../../../create-react-config.js'; + +const config = createConfig(); + +/** @type {import('@rspack/core').Configuration} */ +export default { + context: __dirname, + ...config, + output: { + ...config.output, + chunkFilename: '.rspeedy/async/[name].js', + }, + plugins: [ + ...config.plugins, + new LynxEncodePlugin(), + new LynxTemplatePlugin({ + ...LynxTemplatePlugin.defaultOptions, + chunks: ['main:main-thread', 'main:background'], + filename: 'main/template.js', + intermediate: '.rspeedy/main', + }), + /** + * @param {import('@rspack/core').Compiler} compiler + */ + (compiler) => { + compiler.hooks.thisCompilation.tap('test', compilation => { + const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks( + compilation, + ); + hooks.beforeEncode.tap( + 'test', + (args) => { + expect(args.encodeData.lepusCode.root.name).toBeOneOf( + [ // main entry + 'main:main-thread.js', + // foo.js lazy bundle + '.rspeedy/async/./foo.js-react:main-thread.js', + ], + ); + expect( + Object.keys(args.encodeData.manifest).length, + ).toBe(1); + expect(Object.keys(args.encodeData.manifest)[0]).toBeOneOf( + [ // main entry + 'main:background.js', + // foo.js lazy bundle + '.rspeedy/async/./foo.js-react:background.js', + ], + ); + }, + ); + }); + }, + ], +}; diff --git a/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/test.config.cjs b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/test.config.cjs new file mode 100644 index 0000000000..0b53af9a6e --- /dev/null +++ b/packages/webpack/react-webpack-plugin/test/cases/code-splitting/async-chunk-groups/test.config.cjs @@ -0,0 +1,8 @@ +/** @type {import("@lynx-js/test-tools").TConfigCaseConfig} */ +module.exports = { + bundlePath: [ + // We do not run main-thread.js since the async chunk has been modified. + // 'main:main-thread.js', + 'main:background.js', + ], +}; diff --git a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts index 294d2eb8d4..e6711d73fc 100644 --- a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts +++ b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts @@ -641,14 +641,12 @@ class LynxTemplatePluginImpl { return asyncChunkGroups; } + const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(compilation); + asyncChunkGroups = groupBy( compilation.chunkGroups .filter(cg => !cg.isInitial()), - (cg) => - cg.origins - .sort((a, b) => a.request.localeCompare(b.request)) - .map(({ request }) => request) - .join('|'), + cg => hooks.asyncChunkName.call(cg.name)!, ); LynxTemplatePluginImpl.#asyncChunkGroups.set(compilation, asyncChunkGroups);