From c0a15f919e10d476eca6b4bc4c31ef3a212dedac Mon Sep 17 00:00:00 2001 From: fi3ework Date: Thu, 8 May 2025 13:58:30 +0800 Subject: [PATCH 1/4] docs(JSON): add ouput relationship with bundle mode --- pnpm-lock.yaml | 10 +++ tests/integration/json/index.test.ts | 63 +++++++++++++++++++ tests/integration/json/package.json | 12 ++++ tests/integration/json/rslib.config.ts | 52 +++++++++++++++ tests/integration/json/src/foo.json | 4 ++ tests/integration/json/src/index.ts | 3 + tests/integration/json/tsconfig.json | 7 +++ website/docs/en/guide/advanced/json-files.mdx | 46 ++++++++++++++ website/docs/zh/guide/advanced/json-files.mdx | 46 ++++++++++++++ 9 files changed, 243 insertions(+) create mode 100644 tests/integration/json/index.test.ts create mode 100644 tests/integration/json/package.json create mode 100644 tests/integration/json/rslib.config.ts create mode 100644 tests/integration/json/src/foo.json create mode 100644 tests/integration/json/src/index.ts create mode 100644 tests/integration/json/tsconfig.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index decc5d8b3..c4ab5c2bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -783,6 +783,16 @@ importers: tests/integration/format: {} + tests/integration/json: + dependencies: + buffer: + specifier: ^6.0.3 + version: 6.0.3 + devDependencies: + '@rsbuild/plugin-node-polyfill': + specifier: ^1.3.0 + version: 1.3.0(@rsbuild/core@1.3.15) + tests/integration/minify/config/disabled: {} tests/integration/minify/config/enabled: {} diff --git a/tests/integration/json/index.test.ts b/tests/integration/json/index.test.ts new file mode 100644 index 000000000..f56b6f442 --- /dev/null +++ b/tests/integration/json/index.test.ts @@ -0,0 +1,63 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { buildAndGetResults, queryContent } from 'test-helper'; +import { describe, expect, test } from 'vitest'; + +describe('JSON', async () => { + const fixturePath = join(__dirname, '.'); + const { contents, files } = await buildAndGetResults({ fixturePath }); + + test('bundle', async () => { + const { content: bundle } = queryContent(contents.esm0!, /index\.js/); + expect(bundle).toMatchInlineSnapshot(` + "var foo_namespaceObject = { + S: "foo" + }; + const src = foo_namespaceObject.S + '1'; + export { src as default }; + " + `); + const bundleResult = await import(files.esm0![0]!); + expect(bundleResult.default).toBe('foo1'); + }); + + test('bundleless default', async () => { + const bundlelessFiles = Object.keys(contents.esm1!); + expect(bundlelessFiles).toMatchInlineSnapshot(` + [ + "/tests/integration/json/dist/bundleless-default/foo.js", + "/tests/integration/json/dist/bundleless-default/index.js", + ] + `); + const bundlelessResult = await import( + files.esm1!.find((file) => file.endsWith('index.js'))! + ); + expect(bundlelessResult.default).toBe('foo1'); + }); + + test('bundleless preserver JSON', async () => { + const { content: bundlelessPreserveJson } = queryContent( + contents.esm2!, + /index\.js/, + ); + expect(bundlelessPreserveJson).toMatchInlineSnapshot(` + "import * as __WEBPACK_EXTERNAL_MODULE__foo_json_16d256d4__ from "./foo.json"; + const src = __WEBPACK_EXTERNAL_MODULE__foo_json_16d256d4__.value + '1'; + export { src as default }; + " + `); + + expect( + readFileSync( + join(fixturePath, 'dist/bundleless-preserve-json/foo.json'), + 'utf-8', + ), + ).toMatchInlineSnapshot(` + "{ + "value": "foo", + "value_unused": "noop" + } + " + `); + }); +}); diff --git a/tests/integration/json/package.json b/tests/integration/json/package.json new file mode 100644 index 000000000..24a0ba64c --- /dev/null +++ b/tests/integration/json/package.json @@ -0,0 +1,12 @@ +{ + "name": "json-test", + "version": "1.0.0", + "private": true, + "type": "module", + "dependencies": { + "buffer": "^6.0.3" + }, + "devDependencies": { + "@rsbuild/plugin-node-polyfill": "^1.3.0" + } +} diff --git a/tests/integration/json/rslib.config.ts b/tests/integration/json/rslib.config.ts new file mode 100644 index 000000000..36be66855 --- /dev/null +++ b/tests/integration/json/rslib.config.ts @@ -0,0 +1,52 @@ +import { defineConfig } from '@rslib/core'; +import { generateBundleEsmConfig } from 'test-helper'; + +export default defineConfig({ + lib: [ + // bundle default + generateBundleEsmConfig({ + output: { + distPath: { + root: './dist/bundle-default', + }, + }, + }), + // bundleless default + generateBundleEsmConfig({ + bundle: false, + source: { + entry: { + index: ['./src/**'], + }, + }, + output: { + distPath: { + root: './dist/bundleless-default', + }, + }, + }), + // bundleless preserve JSON + generateBundleEsmConfig({ + bundle: false, + source: { + entry: { + index: ['./src/**', '!./src/**/*.json'], + }, + }, + output: { + copy: [{ from: './**/*.json', context: './src' }], + externals: ({ request }, callback) => { + if (request?.endsWith('.json')) { + callback(undefined, request); + return; + } + + return callback(); + }, + distPath: { + root: './dist/bundleless-preserve-json', + }, + }, + }), + ], +}); diff --git a/tests/integration/json/src/foo.json b/tests/integration/json/src/foo.json new file mode 100644 index 000000000..eeaab156b --- /dev/null +++ b/tests/integration/json/src/foo.json @@ -0,0 +1,4 @@ +{ + "value": "foo", + "value_unused": "noop" +} diff --git a/tests/integration/json/src/index.ts b/tests/integration/json/src/index.ts new file mode 100644 index 000000000..706bb6deb --- /dev/null +++ b/tests/integration/json/src/index.ts @@ -0,0 +1,3 @@ +import { value as foo } from './foo.json'; + +export default foo + '1'; diff --git a/tests/integration/json/tsconfig.json b/tests/integration/json/tsconfig.json new file mode 100644 index 000000000..48845188d --- /dev/null +++ b/tests/integration/json/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@rslib/tsconfig/base", + "compilerOptions": { + "baseUrl": "./" + }, + "include": ["./src"] +} diff --git a/website/docs/en/guide/advanced/json-files.mdx b/website/docs/en/guide/advanced/json-files.mdx index aae3b6dac..8748aa943 100644 --- a/website/docs/en/guide/advanced/json-files.mdx +++ b/website/docs/en/guide/advanced/json-files.mdx @@ -222,3 +222,49 @@ declare module '*.toml' { export default content; } ``` + +## Bundle Mode and Output + +Rslib supports outputting JSON / YAML / TOML files in different forms under different bundle modes. + +### bundle + +In bundle mode ([`bundle: true`](/config/lib/bundle)), JSON files will be directly bundled into JavaScript output, and unused keys in JSON files will be tree-shaken. The same applies to TOML and YAML files. + +### bundleless + +In bundleless mode ([`bundle: false`](/config/lib/bundle)), each JSON / YAML / TOML file will be converted into a corresponding JavaScript output file. JSON files will be converted to `JSON.parse` form and exported, while YAML and TOML files will be converted to JavaScript objects and exported. + +If you want JSON / YAML / TOML files to be output to the distribution directory as-is, and keep the reference paths to these files in the output JavaScript files, you can achieve this through the following steps: + +1. Exclude JSON / YAML / TOML files from the [bundleless](/config/rsbuild/source#sourceentry) entry file glob pattern. +2. Reserve request paths for JSON / YAML / TOML files in [output.externals](/config/rsbuild/output#outputexternals). +3. Add [output.copy](/config/rsbuild/output#outputcopy) option to the output configuration, specifying the output path for JSON / YAML / TOML files. + +For example, the following configuration will output all JSON files in the `src` directory as-is: + +```ts title="rslib.config.ts" {7,11-18} +export default defineConfig({ + lib: [ + { + bundle: false, + source: { + entry: { + index: ['./src/**', '!./src/**/*.json'], + }, + }, + output: { + copy: [{ from: './**/*.json', context: './src' }], + externals: ({ request }, callback) => { + if (request?.endsWith('.json')) { + callback(undefined, request); + return; + } else { + return callback(); + } + }, + }, + }, + ], +}); +``` diff --git a/website/docs/zh/guide/advanced/json-files.mdx b/website/docs/zh/guide/advanced/json-files.mdx index 44a24ca8d..e5161e8fe 100644 --- a/website/docs/zh/guide/advanced/json-files.mdx +++ b/website/docs/zh/guide/advanced/json-files.mdx @@ -219,3 +219,49 @@ declare module '*.toml' { export default content; } ``` + +## 打包模式与输出 + +Rslib 支持在不同的打包模式下,JSON / YAML / TOML 文件以不同的形式输出。 + +### bundle + +在 bundle 模式下(即 [`bundle: true`](/config/lib/bundle)),JSON 文件会被直接打包到 JavaScript 产物中,且没有被使到的 JSON 文件中的 key 会被 tree-shake 掉,TOML 和 YAML 文件同理。 + +### bundleless + +在 bundleless 模式下(即 [`bundle: false`](/config/lib/bundle)),每个 JSON / YAML / TOML 文件会被转换为对应的 JavaScript 模块输出,JSON 文件会被转换为 `JSON.parse` 的形式并导出,YAML 和 TOML 文件会被转换为 JavaScript 对象并导出。 + +如果希望 JSON / YAML / TOML 文件按原样输出到产物目录,并且产物 JavaScript 文件中保留对这些文件的引用路径,可以通过以下方式完成: + +1. [bundleless](/config/rsbuild/source#sourceentry) 的入口文件 glob 匹配中忽略 JSON / YAML / TOML 文件 +2. 在 [output.externals](/config/rsbuild/output#outputexternals) 中保留 JSON / YAML / TOML 文件的请求路径 +3. 在产物输出中添加 [output.copy](/config/rsbuild/output#outputcopy) 选项,指定 JSON / YAML / TOML 文件的输出路径 + +例如下面的配置将会将 `src` 目录下的所有 JSON 文件按原样输出: + +```ts title="rslib.config.ts" {7,11-18} +export default defineConfig({ + lib: [ + { + bundle: false, + source: { + entry: { + index: ['./src/**', '!./src/**/*.json'], + }, + }, + output: { + copy: [{ from: './**/*.json', context: './src' }], + externals: ({ request }, callback) => { + if (request?.endsWith('.json')) { + callback(undefined, request); + return; + } else { + return callback(); + } + }, + }, + }, + ], +}); +``` From cc233ff921b6583e921dae48db430d16d2dd5aa6 Mon Sep 17 00:00:00 2001 From: Wei Date: Thu, 8 May 2025 14:23:09 +0800 Subject: [PATCH 2/4] Update website/docs/zh/guide/advanced/json-files.mdx Co-authored-by: Timeless0911 <50201324+Timeless0911@users.noreply.github.com> --- website/docs/zh/guide/advanced/json-files.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/zh/guide/advanced/json-files.mdx b/website/docs/zh/guide/advanced/json-files.mdx index e5161e8fe..ee8a0dae4 100644 --- a/website/docs/zh/guide/advanced/json-files.mdx +++ b/website/docs/zh/guide/advanced/json-files.mdx @@ -234,7 +234,7 @@ Rslib 支持在不同的打包模式下,JSON / YAML / TOML 文件以不同的 如果希望 JSON / YAML / TOML 文件按原样输出到产物目录,并且产物 JavaScript 文件中保留对这些文件的引用路径,可以通过以下方式完成: -1. [bundleless](/config/rsbuild/source#sourceentry) 的入口文件 glob 匹配中忽略 JSON / YAML / TOML 文件 +1. 在 [source.entry](/config/rsbuild/source#sourceentry) 入口文件的 glob 匹配中忽略 JSON / YAML / TOML 文件 2. 在 [output.externals](/config/rsbuild/output#outputexternals) 中保留 JSON / YAML / TOML 文件的请求路径 3. 在产物输出中添加 [output.copy](/config/rsbuild/output#outputcopy) 选项,指定 JSON / YAML / TOML 文件的输出路径 From 07bdad1aa73da8f21a29f4f2ad30f02da1791bfb Mon Sep 17 00:00:00 2001 From: Wei Date: Thu, 8 May 2025 14:23:18 +0800 Subject: [PATCH 3/4] Update website/docs/zh/guide/advanced/json-files.mdx Co-authored-by: Timeless0911 <50201324+Timeless0911@users.noreply.github.com> --- website/docs/zh/guide/advanced/json-files.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/zh/guide/advanced/json-files.mdx b/website/docs/zh/guide/advanced/json-files.mdx index ee8a0dae4..d1c604a56 100644 --- a/website/docs/zh/guide/advanced/json-files.mdx +++ b/website/docs/zh/guide/advanced/json-files.mdx @@ -226,7 +226,7 @@ Rslib 支持在不同的打包模式下,JSON / YAML / TOML 文件以不同的 ### bundle -在 bundle 模式下(即 [`bundle: true`](/config/lib/bundle)),JSON 文件会被直接打包到 JavaScript 产物中,且没有被使到的 JSON 文件中的 key 会被 tree-shake 掉,TOML 和 YAML 文件同理。 +在 bundle 模式下(即 [`bundle: true`](/config/lib/bundle)),JSON 文件会被直接打包到 JavaScript 产物中,且 JSON 文件中没有被使用到的 key 会被 tree-shake 掉,TOML 和 YAML 文件同理。 ### bundleless From 8ecf87e22ad9e0007ed5b2413c7d4e172a6ccaf1 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Thu, 8 May 2025 14:28:20 +0800 Subject: [PATCH 4/4] up --- pnpm-lock.yaml | 10 +--------- tests/integration/json/index.test.ts | 2 +- tests/integration/json/package.json | 8 +------- tests/integration/json/rslib.config.ts | 9 +-------- website/docs/en/guide/advanced/json-files.mdx | 13 +++---------- website/docs/zh/guide/advanced/json-files.mdx | 11 ++--------- 6 files changed, 9 insertions(+), 44 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c4ab5c2bf..772740169 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -783,15 +783,7 @@ importers: tests/integration/format: {} - tests/integration/json: - dependencies: - buffer: - specifier: ^6.0.3 - version: 6.0.3 - devDependencies: - '@rsbuild/plugin-node-polyfill': - specifier: ^1.3.0 - version: 1.3.0(@rsbuild/core@1.3.15) + tests/integration/json: {} tests/integration/minify/config/disabled: {} diff --git a/tests/integration/json/index.test.ts b/tests/integration/json/index.test.ts index f56b6f442..c8c27df79 100644 --- a/tests/integration/json/index.test.ts +++ b/tests/integration/json/index.test.ts @@ -35,7 +35,7 @@ describe('JSON', async () => { expect(bundlelessResult.default).toBe('foo1'); }); - test('bundleless preserver JSON', async () => { + test('bundleless preserve JSON', async () => { const { content: bundlelessPreserveJson } = queryContent( contents.esm2!, /index\.js/, diff --git a/tests/integration/json/package.json b/tests/integration/json/package.json index 24a0ba64c..0551f1cde 100644 --- a/tests/integration/json/package.json +++ b/tests/integration/json/package.json @@ -2,11 +2,5 @@ "name": "json-test", "version": "1.0.0", "private": true, - "type": "module", - "dependencies": { - "buffer": "^6.0.3" - }, - "devDependencies": { - "@rsbuild/plugin-node-polyfill": "^1.3.0" - } + "type": "module" } diff --git a/tests/integration/json/rslib.config.ts b/tests/integration/json/rslib.config.ts index 36be66855..3684bd4c2 100644 --- a/tests/integration/json/rslib.config.ts +++ b/tests/integration/json/rslib.config.ts @@ -35,14 +35,7 @@ export default defineConfig({ }, output: { copy: [{ from: './**/*.json', context: './src' }], - externals: ({ request }, callback) => { - if (request?.endsWith('.json')) { - callback(undefined, request); - return; - } - - return callback(); - }, + externals: [/.*\.json$/], distPath: { root: './dist/bundleless-preserve-json', }, diff --git a/website/docs/en/guide/advanced/json-files.mdx b/website/docs/en/guide/advanced/json-files.mdx index 8748aa943..d4a3c7618 100644 --- a/website/docs/en/guide/advanced/json-files.mdx +++ b/website/docs/en/guide/advanced/json-files.mdx @@ -223,7 +223,7 @@ declare module '*.toml' { } ``` -## Bundle Mode and Output +## Bundle mode and output Rslib supports outputting JSON / YAML / TOML files in different forms under different bundle modes. @@ -243,7 +243,7 @@ If you want JSON / YAML / TOML files to be output to the distribution directory For example, the following configuration will output all JSON files in the `src` directory as-is: -```ts title="rslib.config.ts" {7,11-18} +```ts title="rslib.config.ts" {7,11-19} export default defineConfig({ lib: [ { @@ -255,14 +255,7 @@ export default defineConfig({ }, output: { copy: [{ from: './**/*.json', context: './src' }], - externals: ({ request }, callback) => { - if (request?.endsWith('.json')) { - callback(undefined, request); - return; - } else { - return callback(); - } - }, + externals: [/.*\.json$/], }, }, ], diff --git a/website/docs/zh/guide/advanced/json-files.mdx b/website/docs/zh/guide/advanced/json-files.mdx index d1c604a56..d73344e21 100644 --- a/website/docs/zh/guide/advanced/json-files.mdx +++ b/website/docs/zh/guide/advanced/json-files.mdx @@ -240,7 +240,7 @@ Rslib 支持在不同的打包模式下,JSON / YAML / TOML 文件以不同的 例如下面的配置将会将 `src` 目录下的所有 JSON 文件按原样输出: -```ts title="rslib.config.ts" {7,11-18} +```ts title="rslib.config.ts" {7,11-19} export default defineConfig({ lib: [ { @@ -252,14 +252,7 @@ export default defineConfig({ }, output: { copy: [{ from: './**/*.json', context: './src' }], - externals: ({ request }, callback) => { - if (request?.endsWith('.json')) { - callback(undefined, request); - return; - } else { - return callback(); - } - }, + externals: [/.*\.json$/], }, }, ],