From 4f75b9bd75ed7a0824cd75788fc4601d3d892ad5 Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Tue, 27 Jan 2026 12:14:43 +0800 Subject: [PATCH 1/7] fix: replaceAll is not a function --- .changeset/cool-peas-wait.md | 5 +++++ .../react/runtime/src/lifecycle/patch/snapshotPatchApply.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/cool-peas-wait.md diff --git a/.changeset/cool-peas-wait.md b/.changeset/cool-peas-wait.md new file mode 100644 index 0000000000..d3b44bc7f3 --- /dev/null +++ b/.changeset/cool-peas-wait.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/react": patch +--- + +Use replace instead of replaceAll for DEV_ONLY_SetSnapshotEntryName diff --git a/packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts b/packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts index 84d0e79fdc..7123364b07 100644 --- a/packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts +++ b/packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts @@ -101,7 +101,7 @@ export function snapshotPatchApply(snapshotPatch: SnapshotPatch): void { // HMR-related // Update the evaluated snapshot entryName from JS. snapshotCreatorMap[uniqID] = evaluate<(uniqId: string) => string>( - snapshotCreatorMap[uniqID]!.toString().replaceAll('globDynamicComponentEntry', JSON.stringify(entryName)), + snapshotCreatorMap[uniqID]!.toString().replace(/globDynamicComponentEntry/g, JSON.stringify(entryName)), ); } break; From c72b4330cf4b38d0fd9ac50db17516c4429e0876 Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Tue, 27 Jan 2026 19:48:09 +0800 Subject: [PATCH 2/7] fix: cannot read property 'call' of undefined --- .changeset/public-wombats-cough.md | 5 +++ .../src/LynxTemplatePlugin.ts | 33 ++++++++++++------- 2 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 .changeset/public-wombats-cough.md diff --git a/.changeset/public-wombats-cough.md b/.changeset/public-wombats-cough.md new file mode 100644 index 0000000000..dd7f0de6af --- /dev/null +++ b/.changeset/public-wombats-cough.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/template-webpack-plugin": patch +--- + +Fix "TypeError: cannot read property 'call' of undefined" error of lazy bundle HMR. diff --git a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts index f225c9a79d..36a2067f47 100644 --- a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts +++ b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts @@ -696,7 +696,9 @@ class LynxTemplatePluginImpl { const asyncAssetsInfoByGroups = this.#getAssetsInformationByFilenames( compilation, - chunkGroups.flatMap(cg => cg.getFiles()), + chunkGroups.flatMap(cg => cg.getFiles()).filter(chunkFile => + predicateNonHotModuleReplacementAsset(chunkFile, compilation) + ), ); return this.#encodeByAssetsInformation( @@ -961,17 +963,9 @@ class LynxTemplatePluginImpl { /** entryPointUnfilteredFiles - also includes hot module update files */ const entryPointUnfilteredFiles = compilation.entrypoints.get(entryName)! .getFiles(); - return entryPointUnfilteredFiles.filter((chunkFile) => { - const asset = compilation.getAsset(chunkFile); - - // Prevent hot-module files from being included: - const assetMetaInformation = asset?.info ?? {}; - - return !( - assetMetaInformation.hotModuleReplacement - ?? assetMetaInformation.development - ); - }); + return entryPointUnfilteredFiles.filter((chunkFile) => + predicateNonHotModuleReplacementAsset(chunkFile, compilation) + ); }); return this.#getAssetsInformationByFilenames(compilation, filenames); @@ -1052,3 +1046,18 @@ export function isDebug(): boolean { export function isRsdoctor(): boolean { return process.env['RSDOCTOR'] === 'true'; } + +export function predicateNonHotModuleReplacementAsset( + chunkFile: string, + compilation: Compilation, +): boolean { + const asset = compilation.getAsset(chunkFile); + + // Prevent hot-module files from being included: + const assetMetaInformation = asset?.info ?? {}; + + return !( + assetMetaInformation.hotModuleReplacement + ?? assetMetaInformation.development + ); +} From 7dd0f3278950b6dd71994264519a1bbfb1a01123 Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Wed, 28 Jan 2026 16:18:05 +0800 Subject: [PATCH 3/7] fix: failed to load CSS update file for lazy bundle --- .changeset/brave-news-sin.md | 5 + .../fixtures/lazy-bundle/LazyComponent.css | 4 + .../fixtures/lazy-bundle/LazyComponent.tsx | 9 ++ .../test/fixtures/lazy-bundle/index.css | 3 + .../test/fixtures/lazy-bundle/index.tsx | 14 ++ .../rspeedy/plugin-react/test/lazy.test.ts | 124 +++++++++++++++++- .../src/LynxTemplatePlugin.ts | 16 ++- 7 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 .changeset/brave-news-sin.md create mode 100644 packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.css create mode 100644 packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.tsx create mode 100644 packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.css create mode 100644 packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.tsx diff --git a/.changeset/brave-news-sin.md b/.changeset/brave-news-sin.md new file mode 100644 index 0000000000..42f8f71d20 --- /dev/null +++ b/.changeset/brave-news-sin.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/template-webpack-plugin": patch +--- + +Fix error "Failed to load CSS update file" error for lazy bundle diff --git a/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.css b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.css new file mode 100644 index 0000000000..a7aafb7083 --- /dev/null +++ b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.css @@ -0,0 +1,4 @@ +.LazyComponent { + font-weight: 700; + color: yellow; +} diff --git a/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.tsx b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.tsx new file mode 100644 index 0000000000..687db8a070 --- /dev/null +++ b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/LazyComponent.tsx @@ -0,0 +1,9 @@ +import './LazyComponent.css' + +export default function LazyComponent() { + return ( + + LazyComponent + + ) +} diff --git a/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.css b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.css new file mode 100644 index 0000000000..9929ab0322 --- /dev/null +++ b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.css @@ -0,0 +1,3 @@ +.Suspense { + background-color: red; +} diff --git a/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.tsx b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.tsx new file mode 100644 index 0000000000..cba1ea2cc6 --- /dev/null +++ b/packages/rspeedy/plugin-react/test/fixtures/lazy-bundle/index.tsx @@ -0,0 +1,14 @@ +import { Suspense, lazy } from '@lynx-js/react' +import './index.css' + +const LazyComponent = lazy(() => import('./LazyComponent.js')) + +export function App() { + return ( + + Loading...}> + + + + ) +} diff --git a/packages/rspeedy/plugin-react/test/lazy.test.ts b/packages/rspeedy/plugin-react/test/lazy.test.ts index 32494ebe26..2800c7e4df 100644 --- a/packages/rspeedy/plugin-react/test/lazy.test.ts +++ b/packages/rspeedy/plugin-react/test/lazy.test.ts @@ -3,9 +3,11 @@ // LICENSE file in the root directory of this source tree. import path from 'node:path' -import type { Rspack } from '@rsbuild/core' +import type { RsbuildPlugin, Rspack } from '@rsbuild/core' import { describe, expect, test, vi } from 'vitest' +import { LynxTemplatePlugin } from '@lynx-js/template-webpack-plugin' + import { createStubRspeedy as createRspeedy } from './createRspeedy.js' import { pluginStubRspeedyAPI } from './stub-rspeedy-api.plugin.js' @@ -170,4 +172,124 @@ describe('Lazy', () => { vi.unstubAllEnvs() }) }) + + test('lazy bundle beforeEncode entryNames', async () => { + vi.stubEnv('NODE_ENV', 'development') + const { pluginReactLynx } = await import('../src/pluginReactLynx.js') + + const entryNamesOfBeforeEncode: string[][] = [] + let backgroundJSContent = '' + + const rsbuild = await createRspeedy({ + rspeedyConfig: { + source: { + entry: { + main: new URL( + './fixtures/lazy-bundle/index.tsx', + import.meta.url, + ).pathname, + }, + }, + output: { + distPath: { + root: './dist/lazy-bundle', + }, + }, + plugins: [ + pluginReactLynx(), + { + name: 'test', + pre: ['lynx:react'], + setup(api) { + api.modifyBundlerChain((chain, { CHAIN_ID }) => { + const rule = chain.module + .rules.get('css:react:main-thread') + .uses.get(CHAIN_ID.USE.IGNORE_CSS) + rule.loader( + // add .ts suffix to ignore-css-loader + // this workaround is needed because vitest + // runs on our ts files. + rule.get('loader') as string + '.ts', + ) + }) + }, + } as RsbuildPlugin, + ], + tools: { + rspack: { + plugins: [ + { + name: 'extractBackgroundJSContent', + apply(compiler) { + compiler.hooks.compilation.tap( + 'extractBackgroundJSContent', + (compilation) => { + compilation.hooks.processAssets.tap( + 'extractBackgroundJSContent', + (assets) => { + for (const key in assets) { + if (/[\\/]background.js$/.test(key)) { + backgroundJSContent = assets[key]!.source() + .toString()! + } + } + }, + ) + }, + ) + }, + } as Rspack.RspackPluginInstance, + { + name: 'beforeEncode-test', + apply(compiler) { + compiler.hooks.compilation.tap( + 'beforeEncode-test', + (compilation) => { + const hooks = LynxTemplatePlugin + .getLynxTemplatePluginHooks( + compilation as unknown as Parameters< + typeof LynxTemplatePlugin.getLynxTemplatePluginHooks + >[0], + ) + hooks.beforeEncode.tap( + 'beforeEncode-test', + (args) => { + entryNamesOfBeforeEncode.push(args.entryNames) + + return args + }, + ) + }, + ) + }, + } as Rspack.RspackPluginInstance, + ], + }, + }, + }, + }) + + await rsbuild.build() + + expect(entryNamesOfBeforeEncode).toMatchInlineSnapshot(` + [ + [ + "main__main-thread", + "main", + ], + [ + "./LazyComponent.js-react__main-thread", + "./LazyComponent.js-react__background", + ], + ] + `) + expect(backgroundJSContent.length).toMatchInlineSnapshot(`572304`) + // /__webpack_require__\.cssHotUpdateList\s*=\s*(\[[\s\S]*?\]);/ + const cssHotUpdateList = /\.cssHotUpdateList\s*=\s*(\[\[[\s\S]*?\]\])/.exec( + backgroundJSContent, + )![1] + expect(cssHotUpdateList).toMatchInlineSnapshot( + `"[["./LazyComponent.js-react__background",".rspeedy/async/./LazyComponent.js-react__background/./LazyComponent.js-react__background.css.hot-update.json"],["main",".rspeedy/main/main.css.hot-update.json"]]"`, + ) + }) }) diff --git a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts index 36a2067f47..5f16bda3ea 100644 --- a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts +++ b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts @@ -671,12 +671,16 @@ class LynxTemplatePluginImpl { await Promise.all( Object.entries(asyncChunkGroups).map( - ([entryName, chunkGroups]): Promise => { - const chunkNames = - // We use the chunk name(provided by `webpackChunkName`) as filename + ([_entryName, chunkGroups]): Promise => { + const entryNames = // We use the chunk name(provided by `webpackChunkName`) as filename chunkGroups - .filter(cg => cg.name !== null && cg.name !== undefined) - .map(cg => hooks.asyncChunkName.call(cg.name!)); + .filter(cg => cg.name !== null && cg.name !== undefined).map(cg => + cg.name! + ); + + const chunkNames = entryNames.map(name => + hooks.asyncChunkName.call(name) + ); const filename = Array.from(new Set(chunkNames)).join('_'); @@ -704,7 +708,7 @@ class LynxTemplatePluginImpl { return this.#encodeByAssetsInformation( compilation, asyncAssetsInfoByGroups, - [entryName], + entryNames, filenameTemplate, path.join(intermediateRoot, 'async', filename), /** isAsync */ true, From 67ab5f00b5b973677fbc458de9a0f97d4887863d Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Wed, 28 Jan 2026 17:14:53 +0800 Subject: [PATCH 4/7] feat: add test case for app-service.js --- .../rspeedy/plugin-react/test/lazy.test.ts | 126 +++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/packages/rspeedy/plugin-react/test/lazy.test.ts b/packages/rspeedy/plugin-react/test/lazy.test.ts index 2800c7e4df..df675aab73 100644 --- a/packages/rspeedy/plugin-react/test/lazy.test.ts +++ b/packages/rspeedy/plugin-react/test/lazy.test.ts @@ -1,6 +1,7 @@ // Copyright 2024 The Lynx Authors. All rights reserved. // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. +import fs from 'node:fs/promises' import path from 'node:path' import type { RsbuildPlugin, Rspack } from '@rsbuild/core' @@ -283,8 +284,6 @@ describe('Lazy', () => { ], ] `) - expect(backgroundJSContent.length).toMatchInlineSnapshot(`572304`) - // /__webpack_require__\.cssHotUpdateList\s*=\s*(\[[\s\S]*?\]);/ const cssHotUpdateList = /\.cssHotUpdateList\s*=\s*(\[\[[\s\S]*?\]\])/.exec( backgroundJSContent, )![1] @@ -292,4 +291,127 @@ describe('Lazy', () => { `"[["./LazyComponent.js-react__background",".rspeedy/async/./LazyComponent.js-react__background/./LazyComponent.js-react__background.css.hot-update.json"],["main",".rspeedy/main/main.css.hot-update.json"]]"`, ) }) + + test('lazy bundle app-service.js should not load hot-update.js', async () => { + vi.stubEnv('NODE_ENV', 'development') + const { pluginReactLynx } = await import('../src/pluginReactLynx.js') + + let appServiceJSContent = '' + let done = false + const waitCompilationDone = () => + new Promise(resolve => { + const interval = setInterval(() => { + if (done) { + clearInterval(interval) + done = false + resolve(null) + } + }, 100) + }) + + const rsbuild = await createRspeedy({ + rspeedyConfig: { + source: { + entry: { + main: new URL( + './fixtures/lazy-bundle/index.tsx', + import.meta.url, + ).pathname, + }, + }, + output: { + distPath: { + root: './dist/lazy-bundle', + }, + }, + plugins: [ + pluginReactLynx(), + { + name: 'test', + pre: ['lynx:react'], + setup(api) { + api.modifyBundlerChain((chain, { CHAIN_ID }) => { + const rule = chain.module + .rules.get('css:react:main-thread') + .uses.get(CHAIN_ID.USE.IGNORE_CSS) + rule.loader( + // add .ts suffix to ignore-css-loader + // this workaround is needed because vitest + // runs on our ts files. + rule.get('loader') as string + '.ts', + ) + }) + }, + } as RsbuildPlugin, + ], + tools: { + rspack: { + plugins: [ + { + name: 'beforeEncode-test', + apply(compiler) { + compiler.hooks.compilation.tap( + 'beforeEncode-test', + (compilation) => { + const hooks = LynxTemplatePlugin + .getLynxTemplatePluginHooks( + compilation as unknown as Parameters< + typeof LynxTemplatePlugin.getLynxTemplatePluginHooks + >[0], + ) + hooks.beforeEmit.tap( + 'beforeEmit-test', + (args) => { + if ( + args.entryNames.some((name) => + name.includes('LazyComponent') + ) + ) { + appServiceJSContent = args.finalEncodeOptions + .manifest['/app-service.js']! + } + return args + }, + ) + }, + ) + compiler.hooks.done.tap('beforeEncode-test', () => { + done = true + }) + }, + } as Rspack.RspackPluginInstance, + ], + }, + }, + }, + }) + + await rsbuild.createDevServer() + await waitCompilationDone() + expect(appServiceJSContent).toMatchInlineSnapshot( + `"(function(){'use strict';function n({tt}){tt.define('/app-service.js',function(e,module,_,i,l,u,a,c,s,f,p,d,h,v,g,y,lynx){module.exports=lynx.requireModule("/static/js/async/./LazyComponent.js-react__background.js",globDynamicComponentEntry?globDynamicComponentEntry:'__Card__');});return tt.require('/app-service.js');}return{init:n}})()"`, + ) + + // Modify the fixtures/lazy-bundle/LazyComponent.tsx file + // to trigger HMR + const tmpContent = await fs.readFile( + new URL('./fixtures/lazy-bundle/LazyComponent.tsx', import.meta.url), + 'utf-8', + ) + await fs.writeFile( + new URL('./fixtures/lazy-bundle/LazyComponent.tsx', import.meta.url), + 'export default function LazyComponent() { return null }', + ) + await waitCompilationDone() + + expect(appServiceJSContent).toMatchInlineSnapshot( + `"(function(){'use strict';function n({tt}){tt.define('/app-service.js',function(e,module,_,i,l,u,a,c,s,f,p,d,h,v,g,y,lynx){module.exports=lynx.requireModule("/static/js/async/./LazyComponent.js-react__background.js",globDynamicComponentEntry?globDynamicComponentEntry:'__Card__');});return tt.require('/app-service.js');}return{init:n}})()"`, + ) + + // Restore the original content + await fs.writeFile( + new URL('./fixtures/lazy-bundle/LazyComponent.tsx', import.meta.url), + tmpContent, + ) + }) }) From 633704e52edb25ea029ad256e19a869261a578ef Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Wed, 28 Jan 2026 23:46:02 +0800 Subject: [PATCH 5/7] Update .changeset/brave-news-sin.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Yiming Li --- .changeset/brave-news-sin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/brave-news-sin.md b/.changeset/brave-news-sin.md index 42f8f71d20..6084e844d9 100644 --- a/.changeset/brave-news-sin.md +++ b/.changeset/brave-news-sin.md @@ -2,4 +2,4 @@ "@lynx-js/template-webpack-plugin": patch --- -Fix error "Failed to load CSS update file" error for lazy bundle +Fix "Failed to load CSS update file" for lazy bundle From bf546f2edfd7f7d2f93df586ed68d727eb0506a0 Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Wed, 28 Jan 2026 23:46:43 +0800 Subject: [PATCH 6/7] Update packages/rspeedy/plugin-react/test/lazy.test.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Yiming Li --- .../rspeedy/plugin-react/test/lazy.test.ts | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/rspeedy/plugin-react/test/lazy.test.ts b/packages/rspeedy/plugin-react/test/lazy.test.ts index df675aab73..4255349874 100644 --- a/packages/rspeedy/plugin-react/test/lazy.test.ts +++ b/packages/rspeedy/plugin-react/test/lazy.test.ts @@ -270,26 +270,31 @@ describe('Lazy', () => { }, }) - await rsbuild.build() + try { + await rsbuild.build() - expect(entryNamesOfBeforeEncode).toMatchInlineSnapshot(` - [ - [ - "main__main-thread", - "main", - ], + expect(entryNamesOfBeforeEncode).toMatchInlineSnapshot(` [ - "./LazyComponent.js-react__main-thread", - "./LazyComponent.js-react__background", - ], - ] - `) - const cssHotUpdateList = /\.cssHotUpdateList\s*=\s*(\[\[[\s\S]*?\]\])/.exec( - backgroundJSContent, - )![1] - expect(cssHotUpdateList).toMatchInlineSnapshot( - `"[["./LazyComponent.js-react__background",".rspeedy/async/./LazyComponent.js-react__background/./LazyComponent.js-react__background.css.hot-update.json"],["main",".rspeedy/main/main.css.hot-update.json"]]"`, - ) + [ + "main__main-thread", + "main", + ], + [ + "./LazyComponent.js-react__main-thread", + "./LazyComponent.js-react__background", + ], + ] + `) + const cssHotUpdateList = + /\.cssHotUpdateList\s*=\s*(\[\[[\s\S]*?\]\])/.exec( + backgroundJSContent, + )![1] + expect(cssHotUpdateList).toMatchInlineSnapshot( + `"[["./LazyComponent.js-react__background",".rspeedy/async/./LazyComponent.js-react__background/./LazyComponent.js-react__background.css.hot-update.json"],["main",".rspeedy/main/main.css.hot-update.json"]]"`, + ) + } finally { + vi.unstubAllEnvs() + } }) test('lazy bundle app-service.js should not load hot-update.js', async () => { From b0dfc8109604d83aac8579c777c220721327d62a Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Wed, 28 Jan 2026 23:47:06 +0800 Subject: [PATCH 7/7] Update packages/rspeedy/plugin-react/test/lazy.test.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Yiming Li --- .../rspeedy/plugin-react/test/lazy.test.ts | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/packages/rspeedy/plugin-react/test/lazy.test.ts b/packages/rspeedy/plugin-react/test/lazy.test.ts index 4255349874..5d56733205 100644 --- a/packages/rspeedy/plugin-react/test/lazy.test.ts +++ b/packages/rspeedy/plugin-react/test/lazy.test.ts @@ -391,32 +391,36 @@ describe('Lazy', () => { }, }) - await rsbuild.createDevServer() - await waitCompilationDone() - expect(appServiceJSContent).toMatchInlineSnapshot( - `"(function(){'use strict';function n({tt}){tt.define('/app-service.js',function(e,module,_,i,l,u,a,c,s,f,p,d,h,v,g,y,lynx){module.exports=lynx.requireModule("/static/js/async/./LazyComponent.js-react__background.js",globDynamicComponentEntry?globDynamicComponentEntry:'__Card__');});return tt.require('/app-service.js');}return{init:n}})()"`, + const lazyComponentUrl = new URL( + './fixtures/lazy-bundle/LazyComponent.tsx', + import.meta.url, ) + let tmpContent: string | undefined - // Modify the fixtures/lazy-bundle/LazyComponent.tsx file - // to trigger HMR - const tmpContent = await fs.readFile( - new URL('./fixtures/lazy-bundle/LazyComponent.tsx', import.meta.url), - 'utf-8', - ) - await fs.writeFile( - new URL('./fixtures/lazy-bundle/LazyComponent.tsx', import.meta.url), - 'export default function LazyComponent() { return null }', - ) - await waitCompilationDone() + try { + await rsbuild.createDevServer() + await waitCompilationDone() + expect(appServiceJSContent).toMatchInlineSnapshot( + `"(function(){'use strict';function n({tt}){tt.define('/app-service.js',function(e,module,_,i,l,u,a,c,s,f,p,d,h,v,g,y,lynx){module.exports=lynx.requireModule("/static/js/async/./LazyComponent.js-react__background.js",globDynamicComponentEntry?globDynamicComponentEntry:'__Card__');});return tt.require('/app-service.js');}return{init:n}})()"`, + ) - expect(appServiceJSContent).toMatchInlineSnapshot( - `"(function(){'use strict';function n({tt}){tt.define('/app-service.js',function(e,module,_,i,l,u,a,c,s,f,p,d,h,v,g,y,lynx){module.exports=lynx.requireModule("/static/js/async/./LazyComponent.js-react__background.js",globDynamicComponentEntry?globDynamicComponentEntry:'__Card__');});return tt.require('/app-service.js');}return{init:n}})()"`, - ) + // Modify the fixtures/lazy-bundle/LazyComponent.tsx file + // to trigger HMR + tmpContent = await fs.readFile(lazyComponentUrl, 'utf-8') + await fs.writeFile( + lazyComponentUrl, + 'export default function LazyComponent() { return null }', + ) + await waitCompilationDone() - // Restore the original content - await fs.writeFile( - new URL('./fixtures/lazy-bundle/LazyComponent.tsx', import.meta.url), - tmpContent, - ) + expect(appServiceJSContent).toMatchInlineSnapshot( + `"(function(){'use strict';function n({tt}){tt.define('/app-service.js',function(e,module,_,i,l,u,a,c,s,f,p,d,h,v,g,y,lynx){module.exports=lynx.requireModule("/static/js/async/./LazyComponent.js-react__background.js",globDynamicComponentEntry?globDynamicComponentEntry:'__Card__');});return tt.require('/app-service.js');}return{init:n}})()"`, + ) + } finally { + if (tmpContent !== undefined) { + await fs.writeFile(lazyComponentUrl, tmpContent) + } + vi.unstubAllEnvs() + } }) })