Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions tests/integration/json/index.test.ts
Original file line number Diff line number Diff line change
@@ -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(`
[
"<ROOT>/tests/integration/json/dist/bundleless-default/foo.js",
"<ROOT>/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 preserve 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"
}
"
`);
});
});
6 changes: 6 additions & 0 deletions tests/integration/json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "json-test",
"version": "1.0.0",
"private": true,
"type": "module"
}
45 changes: 45 additions & 0 deletions tests/integration/json/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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: [/.*\.json$/],
distPath: {
root: './dist/bundleless-preserve-json',
},
},
}),
],
});
4 changes: 4 additions & 0 deletions tests/integration/json/src/foo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"value": "foo",
"value_unused": "noop"
}
3 changes: 3 additions & 0 deletions tests/integration/json/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { value as foo } from './foo.json';

export default foo + '1';
7 changes: 7 additions & 0 deletions tests/integration/json/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@rslib/tsconfig/base",
"compilerOptions": {
"baseUrl": "./"
},
"include": ["./src"]
}
39 changes: 39 additions & 0 deletions website/docs/en/guide/advanced/json-files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,42 @@ 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-19}
export default defineConfig({
lib: [
{
bundle: false,
source: {
entry: {
index: ['./src/**', '!./src/**/*.json'],
},
},
output: {
copy: [{ from: './**/*.json', context: './src' }],
externals: [/.*\.json$/],
},
},
],
});
```
39 changes: 39 additions & 0 deletions website/docs/zh/guide/advanced/json-files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,42 @@ 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. 在 [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 文件的输出路径

例如下面的配置将会将 `src` 目录下的所有 JSON 文件按原样输出:

```ts title="rslib.config.ts" {7,11-19}
export default defineConfig({
lib: [
{
bundle: false,
source: {
entry: {
index: ['./src/**', '!./src/**/*.json'],
},
},
output: {
copy: [{ from: './**/*.json', context: './src' }],
externals: [/.*\.json$/],
},
},
],
});
```
Loading