Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new source.assetsInclude config #3808

Merged
merged 6 commits into from
Oct 24, 2024
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
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'),
},
});
```
Loading