From 9d9ae45e0f59e22e657d6b20e8f56d9e32e80248 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Fri, 30 May 2025 14:09:54 +0800 Subject: [PATCH 1/3] feat: post assets on demand --- packages/core/src/core/rsbuild.ts | 29 ++++++++++++++++++++++ packages/core/src/pool/index.ts | 41 +++++++++++++++++++++++++------ packages/core/src/types/worker.ts | 1 + 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/packages/core/src/core/rsbuild.ts b/packages/core/src/core/rsbuild.ts index b69620c7f..5f763a4b9 100644 --- a/packages/core/src/core/rsbuild.ts +++ b/packages/core/src/core/rsbuild.ts @@ -108,6 +108,8 @@ export const prepareRsbuild = async ( }, }, output: { + // Pass resources to the worker on demand according to entry + manifest: true, sourceMap: { js: 'source-map', }, @@ -141,6 +143,11 @@ export const prepareRsbuild = async ( ...(config.optimization || {}), moduleIds: 'named', chunkIds: 'named', + splitChunks: { + chunks: 'all', + minSize: 0, + maxInitialRequests: Number.POSITIVE_INFINITY, + }, }; }, }, @@ -213,15 +220,20 @@ export const createRsbuildServer = async ({ const getRsbuildStats = async () => { const stats = await devServer.environments[name]!.getStats(); + const { manifest } = devServer.environments[name]!.context; + const { entrypoints, outputPath, assets, time: buildTime, } = stats.toJson({ + all: false, entrypoints: true, outputPath: true, assets: true, + relatedAssets: true, + cachedAssets: true, // get the compilation time timings: true, }); @@ -237,6 +249,21 @@ export const createRsbuildServer = async ({ }); }; + const getEntryFiles = async () => { + const entryFiles: Record = {}; + + const entries = Object.keys(manifest!.entries!); + + for (const entry of entries) { + const data = manifest!.entries[entry]; + entryFiles[entry] = ( + (data.initial?.js || []).concat(data.async?.js || []) || [] + ).map((file: string) => path.join(outputPath!, file)); + } + return entryFiles; + }; + + const entryFiles = await getEntryFiles(); const entries: EntryInfo[] = []; const setupEntries: EntryInfo[] = []; const sourceEntries = await globTestSourceEntries(); @@ -253,11 +280,13 @@ export const createRsbuildServer = async ({ setupEntries.push({ distPath, testPath: setupFiles[entry], + files: entryFiles[entry], }); } else if (sourceEntries[entry]) { entries.push({ distPath, testPath: sourceEntries[entry], + files: entryFiles[entry], }); } } diff --git a/packages/core/src/pool/index.ts b/packages/core/src/pool/index.ts index 0b55fed81..eb26ee2ce 100644 --- a/packages/core/src/pool/index.ts +++ b/packages/core/src/pool/index.ts @@ -163,11 +163,34 @@ export const createPool = async ({ }, }; + const setupAssets = setupEntries.flatMap((entry) => entry.files); + + const filterAssetsByEntry = (entryInfo: EntryInfo) => { + const neededFiles = entryInfo.files + ? Object.fromEntries( + Object.entries(assetFiles).filter( + ([key]) => + entryInfo.files!.includes(key) || setupAssets.includes(key), + ), + ) + : assetFiles; + + const neededSourceMaps = + Object.keys(entries).length > 1 + ? Object.fromEntries( + Object.entries(sourceMaps).filter(([key]) => neededFiles[key]), + ) + : sourceMaps; + + return { assetFiles: neededFiles, sourceMaps: neededSourceMaps }; + }; return { runTests: async () => { const results = await Promise.all( - entries.map((entryInfo) => - pool.runTest({ + entries.map((entryInfo) => { + const { assetFiles, sourceMaps } = filterAssetsByEntry(entryInfo); + + return pool.runTest({ options: { entryInfo, assetFiles, @@ -181,8 +204,8 @@ export const createPool = async ({ updateSnapshot, }, rpcMethods, - }), - ), + }); + }), ); for (const result of results) { @@ -197,8 +220,10 @@ export const createPool = async ({ }, collectTests: async () => { return Promise.all( - entries.map((entryInfo) => - pool.collectTests({ + entries.map((entryInfo) => { + const { assetFiles, sourceMaps } = filterAssetsByEntry(entryInfo); + + return pool.collectTests({ options: { entryInfo, assetFiles, @@ -212,8 +237,8 @@ export const createPool = async ({ updateSnapshot, }, rpcMethods, - }), - ), + }); + }), ); }, close: () => pool.close(), diff --git a/packages/core/src/types/worker.ts b/packages/core/src/types/worker.ts index fdd79023a..55b72a98f 100644 --- a/packages/core/src/types/worker.ts +++ b/packages/core/src/types/worker.ts @@ -13,6 +13,7 @@ import type { DistPath, TestPath } from './utils'; export type EntryInfo = { distPath: DistPath; testPath: TestPath; + files?: string[]; }; /** Server to Runtime */ From 4c658f6ddd2b852145d2264cd0c2e29166627b72 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 4 Jun 2025 11:35:46 +0800 Subject: [PATCH 2/3] fix: update type --- packages/core/src/core/rsbuild.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core/src/core/rsbuild.ts b/packages/core/src/core/rsbuild.ts index 5f763a4b9..97d15d16b 100644 --- a/packages/core/src/core/rsbuild.ts +++ b/packages/core/src/core/rsbuild.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; import { + type ManifestData, type RsbuildInstance, logger as RsbuildLogger, type RsbuildPlugin, @@ -220,7 +221,8 @@ export const createRsbuildServer = async ({ const getRsbuildStats = async () => { const stats = await devServer.environments[name]!.getStats(); - const { manifest } = devServer.environments[name]!.context; + const manifest = devServer.environments[name]!.context + .manifest as ManifestData; const { entrypoints, @@ -257,7 +259,7 @@ export const createRsbuildServer = async ({ for (const entry of entries) { const data = manifest!.entries[entry]; entryFiles[entry] = ( - (data.initial?.js || []).concat(data.async?.js || []) || [] + (data?.initial?.js || []).concat(data?.async?.js || []) || [] ).map((file: string) => path.join(outputPath!, file)); } return entryFiles; From 8e9cc58622b89e616f820c72351fe1fbca1e7528 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 4 Jun 2025 11:41:11 +0800 Subject: [PATCH 3/3] fix: snapshot --- .../core/__snapshots__/rsbuild.test.ts.snap | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/core/tests/core/__snapshots__/rsbuild.test.ts.snap b/packages/core/tests/core/__snapshots__/rsbuild.test.ts.snap index 868a3c99a..7368acc96 100644 --- a/packages/core/tests/core/__snapshots__/rsbuild.test.ts.snap +++ b/packages/core/tests/core/__snapshots__/rsbuild.test.ts.snap @@ -332,7 +332,11 @@ exports[`prepareRsbuild > should generate rspack config correctly 1`] = ` "emitOnErrors": true, "minimize": false, "moduleIds": "named", - "splitChunks": false, + "splitChunks": { + "chunks": "all", + "maxInitialRequests": Infinity, + "minSize": 0, + }, }, "output": { "assetModuleFilename": "static/assets/[name].[contenthash:8][ext]", @@ -374,6 +378,25 @@ exports[`prepareRsbuild > should generate rspack config correctly 1`] = ` "affectedHooks": "compilation", "name": "DefinePlugin", }, + WebpackManifestPlugin { + "options": { + "assetHookStage": Infinity, + "basePath": "", + "fileName": "manifest.json", + "filter": [Function], + "generate": [Function], + "map": null, + "publicPath": null, + "removeKeyHash": /\\(\\[a-f0-9\\]\\{16,32\\}\\\\\\.\\?\\)/gi, + "seed": undefined, + "serialize": [Function], + "sort": null, + "transformExtensions": /\\^\\(gz\\|map\\)\\$/i, + "useEntryKeys": false, + "useLegacyEmit": false, + "writeToFileEmit": false, + }, + }, IgnoreModuleNotFoundErrorPlugin {}, ], "resolve": {