diff --git a/packages/core/src/plugins/EntryChunkPlugin.ts b/packages/core/src/plugins/EntryChunkPlugin.ts index 727fb3f13..5e89f0209 100644 --- a/packages/core/src/plugins/EntryChunkPlugin.ts +++ b/packages/core/src/plugins/EntryChunkPlugin.ts @@ -46,7 +46,6 @@ class EntryChunkPlugin { private enabledImportMetaUrlShim: boolean; private contextToWatch: string | null = null; - private contextWatched = false; constructor({ enabledImportMetaUrlShim = true, @@ -60,12 +59,21 @@ class EntryChunkPlugin { } apply(compiler: Rspack.Compiler) { - compiler.hooks.afterCompile.tap(PLUGIN_NAME, (compilation) => { - if (this.contextWatched || this.contextToWatch === null) return; + // TODO: contextDependencies now can only be added in `tapPromise` hook. + // Change to `.tap` when it's supported. + compiler.hooks.afterCompile.tapPromise(PLUGIN_NAME, (compilation) => { + return new Promise((resolve) => { + if (this.contextToWatch === null) { + resolve(); + return; + } - const contextDep = compilation.contextDependencies; - contextDep.add(this.contextToWatch); - this.contextWatched = true; + const contextDep = compilation.contextDependencies; + if (!contextDep.has(this.contextToWatch)) { + contextDep.add(this.contextToWatch); + } + resolve(); + }); }); compiler.hooks.make.tap(PLUGIN_NAME, (compilation) => { diff --git a/packages/core/tests/__snapshots__/config.test.ts.snap b/packages/core/tests/__snapshots__/config.test.ts.snap index 223695372..7331adaf6 100644 --- a/packages/core/tests/__snapshots__/config.test.ts.snap +++ b/packages/core/tests/__snapshots__/config.test.ts.snap @@ -225,7 +225,6 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "plugins": [ EntryChunkPlugin { "contextToWatch": null, - "contextWatched": false, "enabledImportMetaUrlShim": false, "reactDirectives": {}, "shebangChmod": 493, @@ -469,7 +468,6 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "plugins": [ EntryChunkPlugin { "contextToWatch": null, - "contextWatched": false, "enabledImportMetaUrlShim": true, "reactDirectives": {}, "shebangChmod": 493, @@ -691,7 +689,6 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "plugins": [ EntryChunkPlugin { "contextToWatch": null, - "contextWatched": false, "enabledImportMetaUrlShim": false, "reactDirectives": {}, "shebangChmod": 493, @@ -848,7 +845,6 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i "plugins": [ EntryChunkPlugin { "contextToWatch": null, - "contextWatched": false, "enabledImportMetaUrlShim": false, "reactDirectives": {}, "shebangChmod": 493, diff --git a/tests/integration/cli/build-watch/build.test.ts b/tests/integration/cli/build-watch/build.test.ts index a5628e665..dd9d6d189 100644 --- a/tests/integration/cli/build-watch/build.test.ts +++ b/tests/integration/cli/build-watch/build.test.ts @@ -1,5 +1,6 @@ -import { exec } from 'node:child_process'; +import { exec, spawn } from 'node:child_process'; import path from 'node:path'; +import { after } from 'node:test'; import fse from 'fs-extra'; import { awaitFileChanges, awaitFileExists } from 'test-helper'; import { describe, expect, test } from 'vitest'; @@ -59,46 +60,66 @@ describe('build --watch should handle add / change / unlink', async () => { const tempSrcPath = path.join(__dirname, 'test-temp-src'); await fse.remove(tempSrcPath); await fse.remove(path.join(__dirname, 'dist')); - await fse.copy(path.join(__dirname, 'src'), tempSrcPath); + await fse.copy(path.join(__dirname, 'src'), path.resolve(tempSrcPath)); const tempConfigFile = path.join(__dirname, 'test-temp-rslib.config.mjs'); await fse.remove(tempConfigFile); fse.outputFileSync( tempConfigFile, `import { defineConfig } from '@rslib/core'; - import { generateBundleEsmConfig } from 'test-helper'; - - export default defineConfig({ - lib: [ - generateBundleEsmConfig({ - source: { - entry: { - index: 'test-temp-src', - }, - }, - bundle: false, - }), - ], - }); - `, +import { generateBundleEsmConfig, generateBundleCjsConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig({ + bundle: false, + }), + generateBundleCjsConfig({ + bundle: false, + }), + ], + source: { + entry: { + index: ['./test-temp-src/**'], + }, + }, +}); +`, ); const srcIndexFile = path.join(tempSrcPath, 'index.ts'); - const srcFooFile = path.join(tempSrcPath, 'foo.js'); + const srcFooFile = path.join(tempSrcPath, 'foo.ts'); + const srcFoo2File = path.join(tempSrcPath, 'foo2.ts'); + const distIndexFile = path.join(__dirname, 'dist/esm/index.js'); const distFooFile = path.join(__dirname, 'dist/esm/foo.js'); + const distFoo2File = path.join(__dirname, 'dist/esm/foo2.js'); + + const child = spawn( + 'npx', + ['rslib', 'build', '--watch', '-c', tempConfigFile], + { + cwd: __dirname, + stdio: 'inherit', + shell: true, + }, + ); - const process = exec(`npx rslib build --watch -c ${tempConfigFile}`, { - cwd: __dirname, - }); + await awaitFileExists(distIndexFile); - // add fse.outputFileSync(srcFooFile, `export const foo = 'foo';`); - await awaitFileExists(distFooFile); + fse.outputFileSync(srcFoo2File, `export const foo2 = 'foo2';`); + await awaitFileExists(distFoo2File); const content1 = await fse.readFile(distFooFile, 'utf-8'); expect(content1!).toMatchInlineSnapshot(` "const foo = 'foo'; export { foo }; " `); + const content2 = await fse.readFile(distFoo2File, 'utf-8'); + expect(content2!).toMatchInlineSnapshot(` + "const foo2 = 'foo2'; + export { foo2 }; + " + `); // unlink // Following "change" cases won't succeed if error is thrown in this step. @@ -108,13 +129,15 @@ describe('build --watch should handle add / change / unlink', async () => { const wait = await awaitFileChanges(distFooFile); fse.outputFileSync(srcFooFile, `export const foo = 'foo1';`); await wait(); - const content2 = await fse.readFile(distFooFile, 'utf-8'); - expect(content2!).toMatchInlineSnapshot(` + const content3 = await fse.readFile(distFooFile, 'utf-8'); + expect(content3!).toMatchInlineSnapshot(` "const foo = 'foo1'; export { foo }; " `); - process.kill(); + after(() => { + child.kill(); + }); }); }); diff --git a/tests/integration/cli/build-watch/rslib.config.ts b/tests/integration/cli/build-watch/rslib.config.ts index 642e4bd91..dc17b031e 100644 --- a/tests/integration/cli/build-watch/rslib.config.ts +++ b/tests/integration/cli/build-watch/rslib.config.ts @@ -1,15 +1,18 @@ import { defineConfig } from '@rslib/core'; -import { generateBundleEsmConfig } from 'test-helper'; +import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper'; export default defineConfig({ lib: [ + generateBundleCjsConfig({ + bundle: false, + }), generateBundleEsmConfig({ - source: { - entry: { - index: 'src', - }, - }, bundle: false, }), ], + source: { + entry: { + index: ['./src/**'], + }, + }, });