From b7d41abb855c5748e9941cac7eab4217765619ff Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 23 Nov 2024 08:50:11 +0800 Subject: [PATCH] feat: add `printFileSize.include` option (#4044) --- e2e/cases/print-file-size/basic/index.test.ts | 36 ++++++- packages/core/src/plugins/fileSize.ts | 17 ++- packages/core/src/types/config.ts | 19 ++++ .../en/config/performance/print-file-size.mdx | 101 +++++++++++++++--- .../zh/config/performance/print-file-size.mdx | 101 +++++++++++++++--- 5 files changed, 237 insertions(+), 37 deletions(-) diff --git a/e2e/cases/print-file-size/basic/index.test.ts b/e2e/cases/print-file-size/basic/index.test.ts index 864250ddfe..bc80bc6390 100644 --- a/e2e/cases/print-file-size/basic/index.test.ts +++ b/e2e/cases/print-file-size/basic/index.test.ts @@ -103,7 +103,7 @@ test.describe('should print file size correctly', async () => { ).toBeTruthy(); }); - test('printFileSize: false should work', async () => { + test('printFileSize: false should not print logs', async () => { await build({ cwd, rsbuildConfig: { @@ -190,4 +190,38 @@ test.describe('should print file size correctly', async () => { expect(logs.some((log) => log.includes('Total:'))).toBeTruthy(); expect(logs.some((log) => log.includes('gzip:'))).toBeFalsy(); }); + + test('should allow to filter assets by name', async () => { + await build({ + cwd, + rsbuildConfig: { + performance: { + printFileSize: { + include: (asset) => asset.name.endsWith('.js'), + }, + }, + }, + }); + + expect(logs.some((log) => log.includes('index.html'))).toBeFalsy(); + expect(logs.some((log) => log.includes('.css'))).toBeFalsy(); + expect(logs.some((log) => log.includes('.js'))).toBeTruthy(); + }); + + test('should allow to filter assets by size', async () => { + await build({ + cwd, + rsbuildConfig: { + performance: { + printFileSize: { + include: (asset) => asset.size > 10 * 1000, + }, + }, + }, + }); + + expect(logs.some((log) => log.includes('index.html'))).toBeFalsy(); + expect(logs.some((log) => log.includes('.js'))).toBeTruthy(); + expect(logs.some((log) => log.includes('.css'))).toBeFalsy(); + }); }); diff --git a/packages/core/src/plugins/fileSize.ts b/packages/core/src/plugins/fileSize.ts index 547defdf05..c371786b9b 100644 --- a/packages/core/src/plugins/fileSize.ts +++ b/packages/core/src/plugins/fileSize.ts @@ -128,9 +128,18 @@ async function printFileSizes( groupAssetsByEmitStatus: false, }); - const filteredAssets = origin.assets!.filter((asset) => - filterAsset(asset.name), - ); + const filteredAssets = origin.assets!.filter((asset) => { + if (!filterAsset(asset.name)) { + return false; + } + if (options.include) { + return options.include({ + name: asset.name, + size: asset.size, + }); + } + return true; + }); const distFolder = path.relative(rootPath, distPath); @@ -244,7 +253,7 @@ export const pluginFileSize = (): RsbuildPlugin => ({ const multiStats = 'stats' in stats ? stats.stats : [stats]; - const defaultConfig = { + const defaultConfig: PrintFileSizeOptions = { total: true, detail: true, compressed: true, diff --git a/packages/core/src/types/config.ts b/packages/core/src/types/config.ts index 26fa54d157..8e59b05905 100644 --- a/packages/core/src/types/config.ts +++ b/packages/core/src/types/config.ts @@ -442,6 +442,18 @@ export type BuildCacheOptions = { cacheDigest?: Array; }; +export type PrintFileSizeAsset = { + /** + * The name of the asset. + * @example 'index.html', 'static/js/index.[hash].js' + */ + name: string; + /** + * The size of the asset in bytes. + */ + size: number; +}; + export type PrintFileSizeOptions = { /** * Whether to print the total size of all static assets. @@ -459,6 +471,13 @@ export type PrintFileSizeOptions = { * @default true */ compressed?: boolean; + /** + * A filter function to determine which static assets to print. + * If returned `false`, the static asset will be excluded and not included in the + * total size or detailed size. + * @default undefined + */ + include?: (asset: PrintFileSizeAsset) => boolean; }; export interface PreconnectOption { diff --git a/website/docs/en/config/performance/print-file-size.mdx b/website/docs/en/config/performance/print-file-size.mdx index 97aa9ada01..ec69e776e3 100644 --- a/website/docs/en/config/performance/print-file-size.mdx +++ b/website/docs/en/config/performance/print-file-size.mdx @@ -6,21 +6,10 @@ type PrintFileSizeOptions = | boolean | { - /** - * Whether to print the total size of all static assets. - * @default true - */ total?: boolean; - /** - * Whether to print the size of each static asset. - * @default true - */ detail?: boolean; - /** - * Whether to print the gzip-compressed size of each static asset. - * @default true - */ compressed?: boolean; + include?: (asset: PrintFileSizeAsset) => boolean; }; ``` @@ -32,7 +21,7 @@ Whether to print the file sizes after production build. The default output log is as follows: -```bash +``` File (web) Size Gzip dist/static/js/lib-react.b0714b60.js 140.4 kB 45.0 kB dist/static/js/index.f3fde9c7.js 1.9 kB 0.97 kB @@ -54,11 +43,35 @@ export default { }; ``` -## Custom Outputs +## Options You can customize the output format through the options. -- If you don't need to output the size of each static asset, you can set `detail` to false. In this case, only the total size will be output: +### total + +- **Type:** `boolean` +- **Default:** `true` + +Whether to output the total size of all static assets. + +```ts +export default { + performance: { + printFileSize: { + total: false, + }, + }, +}; +``` + +### detail + +- **Type:** `boolean` +- **Default:** `true` + +Whether to output the size of each static asset. + +If you don't need to view the size of each static asset, you can set `detail` to false. In this case, only the total size will be output: ```ts export default { @@ -70,7 +83,14 @@ export default { }; ``` -- If you don't need to output the gzipped size, you can set `compressed` to false. This can save some gzip computation time for large projects: +### compressed + +- **Type:** `boolean` +- **Default:** `true` + +Whether to output the gzip-compressed size of each static asset. + +If you don't need to view the gzipped size, you can set `compressed` to false. This can save some gzip computation time for large projects: ```ts export default { @@ -81,3 +101,52 @@ export default { }, }; ``` + +### include + +- **Type:** + +```ts +type PrintFileSizeAsset = { + /** + * The name of the static asset. + * @example 'index.html', 'static/js/index.[hash].js' + */ + name: string; + /** + * The size of the static asset in bytes. + */ + size: number; +}; +type Include = (asset: PrintFileSizeAsset) => boolean; +``` + +- **Default:** `undefined` + +A filter function to determine which static assets to print. + +If returned `false`, the static asset will be excluded and not included in the total size or detailed size. + +For example, only output static assets larger than 10kB: + +```ts +export default { + performance: { + printFileSize: { + include: (asset) => asset.size > 10 * 1000, + }, + }, +}; +``` + +Or only output `.js` files: + +```ts +export default { + performance: { + printFileSize: { + include: (asset) => /\.js$/.test(asset.name), + }, + }, +}; +``` diff --git a/website/docs/zh/config/performance/print-file-size.mdx b/website/docs/zh/config/performance/print-file-size.mdx index ff8c6ede77..1e87652ab5 100644 --- a/website/docs/zh/config/performance/print-file-size.mdx +++ b/website/docs/zh/config/performance/print-file-size.mdx @@ -6,21 +6,10 @@ type PrintFileSizeOptions = | boolean | { - /** - * 是否输出所有静态资源的总体积 - * @default true - */ total?: boolean; - /** - * 是否输出每个静态资源的体积 - * @default true - */ detail?: boolean; - /** - * 是否输出 gzip 压缩后的体积 - * @default true - */ compressed?: boolean; + include?: (asset: PrintFileSizeAsset) => boolean; }; ``` @@ -32,7 +21,7 @@ type PrintFileSizeOptions = 默认输出的日志如下: -```bash +``` File (web) Size Gzip dist/static/js/lib-react.b0714b60.js 140.4 kB 45.0 kB dist/static/js/index.f3fde9c7.js 1.9 kB 0.97 kB @@ -54,11 +43,35 @@ export default { }; ``` -## 自定义输出 +## 选项 你可以通过选项来自定义输出的格式。 -- 如果不需要输出每个静态资源文件的体积,可以把 `detail` 设置为 false,此时仅输出总体积: +### total + +- **类型:** `boolean` +- **默认值:** `true` + +是否输出所有静态资源的总体积。 + +```ts +export default { + performance: { + printFileSize: { + total: false, + }, + }, +}; +``` + +### detail + +- **类型:** `boolean` +- **默认值:** `true` + +是否输出每个静态资源的体积。 + +如果你不需要查看每个静态资源文件的体积,可以把 `detail` 设置为 false,此时仅输出总体积: ```ts export default { @@ -70,7 +83,14 @@ export default { }; ``` -- 如果不需要输出 gzip 压缩后的体积,可以把 `compressed` 设置为 false,这在大型项目中可以节省一些 gzip 计算的耗时: +### compressed + +- **类型:** `boolean` +- **默认值:** `true` + +是否输出 gzip 压缩后的体积。 + +如果你不需要查看 gzip 压缩后的体积,可以把 `compressed` 设置为 false,这在大型项目中可以节省一些 gzip 计算的耗时: ```ts export default { @@ -81,3 +101,52 @@ export default { }, }; ``` + +### include + +- **类型:** + +```ts +type PrintFileSizeAsset = { + /** + * 静态资源名称 + * @example 'index.html', 'static/js/index.[hash].js' + */ + name: string; + /** + * 静态资源体积,单位为 bytes + */ + size: number; +}; +type Include = (asset: PrintFileSizeAsset) => boolean; +``` + +- **默认值:** `undefined` + +一个过滤函数,用于确定哪些静态资源需要输出。 + +如果返回 `false`,则该静态资源将被排除,不会被包含在总体积或详细体积中。 + +例如,只输出体积大于 10kB 的静态资源: + +```ts +export default { + performance: { + printFileSize: { + include: (asset) => asset.size > 10 * 1000, + }, + }, +}; +``` + +或者只输出 `.js` 文件: + +```ts +export default { + performance: { + printFileSize: { + include: (asset) => /\.js$/.test(asset.name), + }, + }, +}; +```