Skip to content

Commit

Permalink
feat: add new source.assetsInclude config (#3808)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Oct 24, 2024
1 parent ed69518 commit 14a7c71
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 2 deletions.
79 changes: 79 additions & 0 deletions e2e/cases/assets/addtional-assets/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import path from 'node:path';
import { build } from '@e2e/helper';
import { expect, test } from '@playwright/test';

function isIncludeFile(filenames: string[], includeFilename: string) {
return filenames.some((filename) => filename.includes(includeFilename));
}

test('should allow to configure additional assets and match by RegExp', async () => {
const rsbuild = await build({
cwd: __dirname,
rsbuildConfig: {
source: {
assetsInclude: [/\.json5$/],
},
},
});

const files = await rsbuild.unwrapOutputJSON();
const filenames = Object.keys(files);

const indexJs = await rsbuild.getIndexFile();
expect(indexJs.content).toContain('data:application/json5;base64,');

expect(
isIncludeFile(filenames, 'dist/static/assets/test-temp-large.json5'),
).toBeTruthy();
expect(
isIncludeFile(filenames, 'dist/static/assets/test-temp-small.json5'),
).toBeFalsy();
});

test('should allow to configure additional assets and match by path', async () => {
const rsbuild = await build({
cwd: __dirname,
rsbuildConfig: {
source: {
assetsInclude: path.resolve(__dirname, 'src/assets'),
},
},
});

const files = await rsbuild.unwrapOutputJSON();
const filenames = Object.keys(files);

const indexJs = await rsbuild.getIndexFile();
expect(indexJs.content).toContain('data:application/json5;base64,');

expect(
isIncludeFile(filenames, 'dist/static/assets/test-temp-large.json5'),
).toBeTruthy();
expect(
isIncludeFile(filenames, 'dist/static/assets/test-temp-small.json5'),
).toBeFalsy();
});

test('should allow to disable emit for additional assets', async () => {
const rsbuild = await build({
cwd: __dirname,
rsbuildConfig: {
source: {
assetsInclude: [/\.json5$/],
},
output: {
emitAssets: false,
},
},
});

const files = await rsbuild.unwrapOutputJSON();
const filenames = Object.keys(files);

expect(
isIncludeFile(filenames, 'dist/static/assets/test-temp-large.json5'),
).toBeFalsy();
expect(
isIncludeFile(filenames, 'dist/static/assets/test-temp-small.json5'),
).toBeFalsy();
});
18 changes: 18 additions & 0 deletions e2e/cases/assets/addtional-assets/rsbuild.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { join } from 'node:path';
import { defineConfig } from '@rsbuild/core';
import { outputFileSync } from 'fs-extra';

outputFileSync(
join(__dirname, 'src/assets/test-temp-small.json5'),
JSON.stringify({ a: 1 }),
);
outputFileSync(
join(__dirname, 'src/assets/test-temp-large.json5'),
JSON.stringify({ a: '1'.repeat(10000) }),
);

export default defineConfig({
output: {
filenameHash: false,
},
});
5 changes: 5 additions & 0 deletions e2e/cases/assets/addtional-assets/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import large from './assets/test-temp-large.json5';
import small from './assets/test-temp-small.json5';

console.log(large);
console.log(small);
20 changes: 20 additions & 0 deletions packages/core/src/plugins/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from 'node:path';
import type { GeneratorOptionsByModuleType } from '@rspack/core';
import {
AUDIO_EXTENSIONS,
DEFAULT_DATA_URL_SIZE,
FONT_EXTENSIONS,
IMAGE_EXTENSIONS,
VIDEO_EXTENSIONS,
Expand Down Expand Up @@ -126,6 +127,25 @@ export const pluginAsset = (): RsbuildPlugin => ({
if (!emitAssets) {
chain.module.generator.merge({ 'asset/resource': { emit: false } });
}

// additional assets
const { assetsInclude } = config.source;
if (assetsInclude) {
const { dataUriLimit } = config.output;
const rule = chain.module.rule('additional-assets').test(assetsInclude);
const maxSize =
typeof dataUriLimit === 'number'
? dataUriLimit
: DEFAULT_DATA_URL_SIZE;

chainStaticAssetRule({
emit: emitAssets,
rule,
maxSize,
filename: assetsFilename,
assetType: 'additional',
});
}
});
},
});
5 changes: 5 additions & 0 deletions packages/core/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ export interface SourceConfig {
* and the `alias` option in the bundler.
*/
aliasStrategy?: AliasStrategy;
/**
* Include additional files that should be treated as static assets.
* @default undefined
*/
assetsInclude?: Rspack.RuleSetCondition;
/**
* Specify directories or modules that need additional compilation.
* In order to maintain faster compilation speed, Rsbuild will not compile files under node_modules through
Expand Down
44 changes: 44 additions & 0 deletions website/docs/en/config/source/assets-include.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# source.assetsInclude

- **Type:** [Rspack.RuleSetCondition](https://rspack.dev/config/module#condition)
- **Default:** `undefined`

Include additional files that should be treated as static assets.

By default, Rsbuild treats common image, font, audio, and video files as static assets. Through the `source.assetsInclude` config, you can specify additional file types that should be treated as static assets. These added static assets are processed using the same rules as the built-in supported static assets, see [Static Assets](/guide/basic/static-assets).

The value of `source.assetsInclude` is the same as the `test` option in Rspack loader. It can be a regular expression, string, array, logical condition, etc. For more details, see [Rspack RuleSetCondition](https://rspack.dev/config/module#condition).

## Example

- Treating `.json5` files as static assets:

```ts
export default defineConfig({
source: {
assetsInclude: /\.json5$/,
},
});
```

- Treating multiple file types as static assets:

```ts
export default defineConfig({
source: {
assetsInclude: [/\.json5$/, /\.pdf$/],
},
});
```

- Treating specific files as static assets:

```ts
import path from 'node:path';

export default defineConfig({
source: {
assetsInclude: path.resolve(__dirname, 'src/assets/foo.json5'),
},
});
```
2 changes: 1 addition & 1 deletion website/docs/en/config/source/exclude.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# source.exclude

- **Type:** [RuleSetCondition[]](https://rspack.dev/config/module#condition)
- **Type:** [Rspack.RuleSetCondition](https://rspack.dev/config/module#condition)
- **Default:** `[]`

Specifies JavaScript/TypeScript files that do not need to be compiled. The usage is consistent with [Rule.exclude](https://rspack.dev/config/module#ruleexclude) in Rspack, which supports passing in strings or regular expressions to match the module path.
Expand Down
2 changes: 1 addition & 1 deletion website/docs/en/config/source/include.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# source.include

- **Type:** [RuleSetCondition[]](https://rspack.dev/config/module#condition)
- **Type:** [Rspack.RuleSetCondition](https://rspack.dev/config/module#condition)
- **Default:**

```ts
Expand Down
44 changes: 44 additions & 0 deletions website/docs/zh/config/source/assets-include.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# source.assetsInclude

- **类型:** [Rspack.RuleSetCondition](https://rspack.dev/config/module#condition)
- **默认值:** `undefined`

指定需要被视为静态资源的额外文件类型。

Rsbuild 默认会将常见的图片、字体、音频、视频等文件视为静态资源。通过配置 `source.assetsInclude`,你可以添加更多的文件类型,这些新增的静态资源将按照与内置静态资源相同的规则进行处理,详见 [引用静态资源](/guide/basic/static-assets)

`source.assetsInclude` 的值与 Rspack loader 的 `test` 选项相同,可以是正则表达式、字符串、数组、逻辑条件等,详见 [Rspack RuleSetCondition](https://rspack.dev/config/module#condition)

## 示例

-`.json5` 文件视为静态资源:

```ts
export default defineConfig({
source: {
assetsInclude: /\.json5$/,
},
});
```

- 将多种文件类型视为静态资源:

```ts
export default defineConfig({
source: {
assetsInclude: [/\.json5$/, /\.pdf$/],
},
});
```

- 将指定文件视为静态资源:

```ts
import path from 'node:path';

export default defineConfig({
source: {
assetsInclude: path.resolve(__dirname, 'src/assets/foo.json5'),
},
});
```

0 comments on commit 14a7c71

Please sign in to comment.