From a5c8a504860445ca98e2834870e0e87732b39f15 Mon Sep 17 00:00:00 2001 From: neverland Date: Wed, 17 Jul 2024 16:28:00 +0800 Subject: [PATCH] feat: add environments as a filter of `api.transform` (#2947) --- .../index.test.ts | 23 +++++++++++++++++++ .../myPlugin.ts | 17 ++++++++++++++ .../rsbuild.config.ts | 20 ++++++++++++++++ .../src/index.js | 1 + packages/core/src/initPlugins.ts | 11 ++++++++- packages/core/src/types/plugin.ts | 5 ++++ website/docs/en/plugins/dev/core.mdx | 11 ++++++++- website/docs/zh/plugins/dev/core.mdx | 9 ++++++++ 8 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 e2e/cases/plugin-api/plugin-transform-by-environments/index.test.ts create mode 100644 e2e/cases/plugin-api/plugin-transform-by-environments/myPlugin.ts create mode 100644 e2e/cases/plugin-api/plugin-transform-by-environments/rsbuild.config.ts create mode 100644 e2e/cases/plugin-api/plugin-transform-by-environments/src/index.js diff --git a/e2e/cases/plugin-api/plugin-transform-by-environments/index.test.ts b/e2e/cases/plugin-api/plugin-transform-by-environments/index.test.ts new file mode 100644 index 0000000000..8d080a594c --- /dev/null +++ b/e2e/cases/plugin-api/plugin-transform-by-environments/index.test.ts @@ -0,0 +1,23 @@ +import { build } from '@e2e/helper'; +import { expect, test } from '@playwright/test'; + +test('should allow plugin to transform code by targets', async () => { + const rsbuild = await build({ + cwd: __dirname, + }); + + const files = await rsbuild.unwrapOutputJSON(); + const webJs = Object.keys(files).find( + (file) => + file.includes('index') && + !file.includes('server') && + file.endsWith('.js'), + ); + const nodeJs = Object.keys(files).find( + (file) => + file.includes('index') && file.includes('server') && file.endsWith('.js'), + ); + + expect(files[webJs!].includes('target is web')).toBeTruthy(); + expect(files[nodeJs!].includes('target is node')).toBeTruthy(); +}); diff --git a/e2e/cases/plugin-api/plugin-transform-by-environments/myPlugin.ts b/e2e/cases/plugin-api/plugin-transform-by-environments/myPlugin.ts new file mode 100644 index 0000000000..7071ae8685 --- /dev/null +++ b/e2e/cases/plugin-api/plugin-transform-by-environments/myPlugin.ts @@ -0,0 +1,17 @@ +import type { RsbuildPlugin } from '@rsbuild/core'; + +export const myPlugin: RsbuildPlugin = { + name: 'my-plugin', + setup(api) { + api.transform({ test: /\.js$/, environments: ['web'] }, ({ code }) => { + return { + code: code.replace('hello', 'target is web'), + }; + }); + api.transform({ test: /\.js$/, environments: ['node'] }, ({ code }) => { + return { + code: code.replace('hello', 'target is node'), + }; + }); + }, +}; diff --git a/e2e/cases/plugin-api/plugin-transform-by-environments/rsbuild.config.ts b/e2e/cases/plugin-api/plugin-transform-by-environments/rsbuild.config.ts new file mode 100644 index 0000000000..421641c807 --- /dev/null +++ b/e2e/cases/plugin-api/plugin-transform-by-environments/rsbuild.config.ts @@ -0,0 +1,20 @@ +import { myPlugin } from './myPlugin'; + +export default { + plugins: [myPlugin], + environments: { + web: { + output: { + target: 'web', + }, + }, + node: { + output: { + target: 'node', + distPath: { + root: 'dist/server', + }, + }, + }, + }, +}; diff --git a/e2e/cases/plugin-api/plugin-transform-by-environments/src/index.js b/e2e/cases/plugin-api/plugin-transform-by-environments/src/index.js new file mode 100644 index 0000000000..e921523b1b --- /dev/null +++ b/e2e/cases/plugin-api/plugin-transform-by-environments/src/index.js @@ -0,0 +1 @@ +console.log('hello'); diff --git a/packages/core/src/initPlugins.ts b/packages/core/src/initPlugins.ts index 442fbbd7ac..72dfc2b33d 100644 --- a/packages/core/src/initPlugins.ts +++ b/packages/core/src/initPlugins.ts @@ -118,11 +118,20 @@ export function getPluginAPI({ transformer[id] = handler; - hooks.modifyBundlerChain.tap((chain, { target }) => { + hooks.modifyBundlerChain.tap((chain, { target, environment }) => { + // filter by targets if (descriptor.targets && !descriptor.targets.includes(target)) { return; } + // filter by environments + if ( + descriptor.environments && + !descriptor.environments.includes(environment.name) + ) { + return; + } + const rule = chain.module.rule(id); if (descriptor.test) { diff --git a/packages/core/src/types/plugin.ts b/packages/core/src/types/plugin.ts index 27146a3923..1c2d3247ec 100644 --- a/packages/core/src/types/plugin.ts +++ b/packages/core/src/types/plugin.ts @@ -221,6 +221,11 @@ export type TransformDescriptor = { * @see https://rsbuild.dev/config/output/targets */ targets?: RsbuildTarget[]; + /** + * Match based on the Rsbuild environment names and only apply the transform to certain environments. + * @see https://rsbuild.dev/config/environments + */ + environments?: string[]; /** * If raw is `true`, the transform handler will receive the Buffer type code instead of the string type. * @see https://rspack.dev/api/loader-api#raw-loader diff --git a/website/docs/en/plugins/dev/core.mdx b/website/docs/en/plugins/dev/core.mdx index 2466c69dcd..0a07857b17 100644 --- a/website/docs/en/plugins/dev/core.mdx +++ b/website/docs/en/plugins/dev/core.mdx @@ -170,7 +170,7 @@ Used to transform the code of modules. ```ts function Transform( - descriptor: { test?: RuleSetCondition | undefined }, + descriptor: TransformDescriptor, handler: TransformHandler, ): void; ``` @@ -208,6 +208,7 @@ The descriptor param is an object describing the module's matching conditions. type TransformDescriptor = { test?: RuleSetCondition; targets?: RsbuildTarget[]; + environments?: string[]; resourceQuery?: RuleSetCondition; raw?: boolean; }; @@ -231,6 +232,14 @@ api.transform({ test: /\.pug$/, targets: ['web'] }, ({ code }) => { }); ``` +- `environments`: matches the Rsbuild [environment](/guide/advanced/environments) name, and applies the current transform function only to the matched environments. + +```js +api.transform({ test: /\.pug$/, environments: ['web'] }, ({ code }) => { + // ... +}); +``` + - `resourceQuery`: matches module's query, the same as Rspack's [Rule.resourceQuery](https://rspack.dev/config/module#ruleresourcequery). ```js diff --git a/website/docs/zh/plugins/dev/core.mdx b/website/docs/zh/plugins/dev/core.mdx index 86810d77cb..a0d3269a6c 100644 --- a/website/docs/zh/plugins/dev/core.mdx +++ b/website/docs/zh/plugins/dev/core.mdx @@ -206,6 +206,7 @@ descriptor 参数是一个对象,用于描述模块的匹配条件。 type TransformDescriptor = { test?: RuleSetCondition; targets?: RsbuildTarget[]; + environments?: string[]; resourceQuery?: RuleSetCondition; raw?: boolean; }; @@ -229,6 +230,14 @@ api.transform({ test: /\.pug$/, targets: ['web'] }, ({ code }) => { }); ``` +- `environments`:匹配 Rsbuild [environment](/guide/advanced/environments) name,仅对匹配的 environments 应用当前 transform 函数。 + +```js +api.transform({ test: /\.pug$/, environments: ['web'] }, ({ code }) => { + // ... +}); +``` + - `resourceQuery`:匹配模块的 query,等价于 Rspack 的 [Rule.resourceQuery](https://rspack.dev/config/module#ruleresourcequery)。 ```js