Skip to content

Commit c0a15f9

Browse files
committed
docs(JSON): add ouput relationship with bundle mode
1 parent f9a747a commit c0a15f9

File tree

9 files changed

+243
-0
lines changed

9 files changed

+243
-0
lines changed

pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { readFileSync } from 'node:fs';
2+
import { join } from 'node:path';
3+
import { buildAndGetResults, queryContent } from 'test-helper';
4+
import { describe, expect, test } from 'vitest';
5+
6+
describe('JSON', async () => {
7+
const fixturePath = join(__dirname, '.');
8+
const { contents, files } = await buildAndGetResults({ fixturePath });
9+
10+
test('bundle', async () => {
11+
const { content: bundle } = queryContent(contents.esm0!, /index\.js/);
12+
expect(bundle).toMatchInlineSnapshot(`
13+
"var foo_namespaceObject = {
14+
S: "foo"
15+
};
16+
const src = foo_namespaceObject.S + '1';
17+
export { src as default };
18+
"
19+
`);
20+
const bundleResult = await import(files.esm0![0]!);
21+
expect(bundleResult.default).toBe('foo1');
22+
});
23+
24+
test('bundleless default', async () => {
25+
const bundlelessFiles = Object.keys(contents.esm1!);
26+
expect(bundlelessFiles).toMatchInlineSnapshot(`
27+
[
28+
"<ROOT>/tests/integration/json/dist/bundleless-default/foo.js",
29+
"<ROOT>/tests/integration/json/dist/bundleless-default/index.js",
30+
]
31+
`);
32+
const bundlelessResult = await import(
33+
files.esm1!.find((file) => file.endsWith('index.js'))!
34+
);
35+
expect(bundlelessResult.default).toBe('foo1');
36+
});
37+
38+
test('bundleless preserver JSON', async () => {
39+
const { content: bundlelessPreserveJson } = queryContent(
40+
contents.esm2!,
41+
/index\.js/,
42+
);
43+
expect(bundlelessPreserveJson).toMatchInlineSnapshot(`
44+
"import * as __WEBPACK_EXTERNAL_MODULE__foo_json_16d256d4__ from "./foo.json";
45+
const src = __WEBPACK_EXTERNAL_MODULE__foo_json_16d256d4__.value + '1';
46+
export { src as default };
47+
"
48+
`);
49+
50+
expect(
51+
readFileSync(
52+
join(fixturePath, 'dist/bundleless-preserve-json/foo.json'),
53+
'utf-8',
54+
),
55+
).toMatchInlineSnapshot(`
56+
"{
57+
"value": "foo",
58+
"value_unused": "noop"
59+
}
60+
"
61+
`);
62+
});
63+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "json-test",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module",
6+
"dependencies": {
7+
"buffer": "^6.0.3"
8+
},
9+
"devDependencies": {
10+
"@rsbuild/plugin-node-polyfill": "^1.3.0"
11+
}
12+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
lib: [
6+
// bundle default
7+
generateBundleEsmConfig({
8+
output: {
9+
distPath: {
10+
root: './dist/bundle-default',
11+
},
12+
},
13+
}),
14+
// bundleless default
15+
generateBundleEsmConfig({
16+
bundle: false,
17+
source: {
18+
entry: {
19+
index: ['./src/**'],
20+
},
21+
},
22+
output: {
23+
distPath: {
24+
root: './dist/bundleless-default',
25+
},
26+
},
27+
}),
28+
// bundleless preserve JSON
29+
generateBundleEsmConfig({
30+
bundle: false,
31+
source: {
32+
entry: {
33+
index: ['./src/**', '!./src/**/*.json'],
34+
},
35+
},
36+
output: {
37+
copy: [{ from: './**/*.json', context: './src' }],
38+
externals: ({ request }, callback) => {
39+
if (request?.endsWith('.json')) {
40+
callback(undefined, request);
41+
return;
42+
}
43+
44+
return callback();
45+
},
46+
distPath: {
47+
root: './dist/bundleless-preserve-json',
48+
},
49+
},
50+
}),
51+
],
52+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"value": "foo",
3+
"value_unused": "noop"
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { value as foo } from './foo.json';
2+
3+
export default foo + '1';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "@rslib/tsconfig/base",
3+
"compilerOptions": {
4+
"baseUrl": "./"
5+
},
6+
"include": ["./src"]
7+
}

website/docs/en/guide/advanced/json-files.mdx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,49 @@ declare module '*.toml' {
222222
export default content;
223223
}
224224
```
225+
226+
## Bundle Mode and Output
227+
228+
Rslib supports outputting JSON / YAML / TOML files in different forms under different bundle modes.
229+
230+
### bundle
231+
232+
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.
233+
234+
### bundleless
235+
236+
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.
237+
238+
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:
239+
240+
1. Exclude JSON / YAML / TOML files from the [bundleless](/config/rsbuild/source#sourceentry) entry file glob pattern.
241+
2. Reserve request paths for JSON / YAML / TOML files in [output.externals](/config/rsbuild/output#outputexternals).
242+
3. Add [output.copy](/config/rsbuild/output#outputcopy) option to the output configuration, specifying the output path for JSON / YAML / TOML files.
243+
244+
For example, the following configuration will output all JSON files in the `src` directory as-is:
245+
246+
```ts title="rslib.config.ts" {7,11-18}
247+
export default defineConfig({
248+
lib: [
249+
{
250+
bundle: false,
251+
source: {
252+
entry: {
253+
index: ['./src/**', '!./src/**/*.json'],
254+
},
255+
},
256+
output: {
257+
copy: [{ from: './**/*.json', context: './src' }],
258+
externals: ({ request }, callback) => {
259+
if (request?.endsWith('.json')) {
260+
callback(undefined, request);
261+
return;
262+
} else {
263+
return callback();
264+
}
265+
},
266+
},
267+
},
268+
],
269+
});
270+
```

website/docs/zh/guide/advanced/json-files.mdx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,49 @@ declare module '*.toml' {
219219
export default content;
220220
}
221221
```
222+
223+
## 打包模式与输出
224+
225+
Rslib 支持在不同的打包模式下,JSON / YAML / TOML 文件以不同的形式输出。
226+
227+
### bundle
228+
229+
在 bundle 模式下(即 [`bundle: true`](/config/lib/bundle)),JSON 文件会被直接打包到 JavaScript 产物中,且没有被使到的 JSON 文件中的 key 会被 tree-shake 掉,TOML 和 YAML 文件同理。
230+
231+
### bundleless
232+
233+
在 bundleless 模式下(即 [`bundle: false`](/config/lib/bundle)),每个 JSON / YAML / TOML 文件会被转换为对应的 JavaScript 模块输出,JSON 文件会被转换为 `JSON.parse` 的形式并导出,YAML 和 TOML 文件会被转换为 JavaScript 对象并导出。
234+
235+
如果希望 JSON / YAML / TOML 文件按原样输出到产物目录,并且产物 JavaScript 文件中保留对这些文件的引用路径,可以通过以下方式完成:
236+
237+
1. [bundleless](/config/rsbuild/source#sourceentry) 的入口文件 glob 匹配中忽略 JSON / YAML / TOML 文件
238+
2. 在 [output.externals](/config/rsbuild/output#outputexternals) 中保留 JSON / YAML / TOML 文件的请求路径
239+
3. 在产物输出中添加 [output.copy](/config/rsbuild/output#outputcopy) 选项,指定 JSON / YAML / TOML 文件的输出路径
240+
241+
例如下面的配置将会将 `src` 目录下的所有 JSON 文件按原样输出:
242+
243+
```ts title="rslib.config.ts" {7,11-18}
244+
export default defineConfig({
245+
lib: [
246+
{
247+
bundle: false,
248+
source: {
249+
entry: {
250+
index: ['./src/**', '!./src/**/*.json'],
251+
},
252+
},
253+
output: {
254+
copy: [{ from: './**/*.json', context: './src' }],
255+
externals: ({ request }, callback) => {
256+
if (request?.endsWith('.json')) {
257+
callback(undefined, request);
258+
return;
259+
} else {
260+
return callback();
261+
}
262+
},
263+
},
264+
},
265+
],
266+
});
267+
```

0 commit comments

Comments
 (0)