Skip to content

Commit

Permalink
feat: allow to access environment context in transform API (#2968)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Jul 20, 2024
1 parent 2d5cff5 commit 7746922
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { build } from '@e2e/helper';
import { expect, test } from '@playwright/test';

test('should allow plugin to transform code by targets', async () => {
test('should allow plugin to transform code by environments', async () => {
const rsbuild = await build({
cwd: __dirname,
});
Expand All @@ -18,6 +18,6 @@ test('should allow plugin to transform code by targets', async () => {
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();
expect(files[webJs!].includes('environments is web')).toBeTruthy();
expect(files[nodeJs!].includes('environments is node')).toBeTruthy();
});
26 changes: 16 additions & 10 deletions e2e/cases/plugin-api/plugin-transform-by-environments/myPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@ 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'),
};
});
api.transform(
{ test: /\.js$/, environments: ['web'] },
({ code, environment }) => {
return {
code: code.replace('hello', `environments is ${environment.name}`),
};
},
);
api.transform(
{ test: /\.js$/, environments: ['node'] },
({ code, environment }) => {
return {
code: code.replace('hello', `environments is ${environment.name}`),
};
},
);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe
{
"loader": "<ROOT>/packages/core/dist/transformRawLoader.cjs",
"options": {
"getEnvironment": [Function],
"id": "rsbuild-transform-0",
},
},
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/initPlugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Compiler } from '@rspack/core';
import { LOADER_PATH } from './constants';
import { createPublicContext } from './createContext';
import { removeLeadingSlash } from './helpers';
import type { TransformLoaderOptions } from './loader/transformLoader';
import type {
GetRsbuildConfig,
InternalContext,
Expand Down Expand Up @@ -191,7 +192,13 @@ export function getPluginAPI({
: 'transformLoader.cjs';
const loaderPath = join(LOADER_PATH, loaderName);

rule.use(id).loader(loaderPath).options({ id });
rule
.use(id)
.loader(loaderPath)
.options({
id,
getEnvironment: () => environment,
} satisfies TransformLoaderOptions);

applyTransformPlugin(chain, transformer);
});
Expand Down
16 changes: 13 additions & 3 deletions packages/core/src/loader/transformLoader.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import type { LoaderContext } from '@rspack/core';
import type { RspackSourceMap, TransformContext } from '../types';
import type {
EnvironmentContext,
RspackSourceMap,
TransformContext,
} from '../types';

export type TransformLoaderOptions = {
id: string;
getEnvironment: () => EnvironmentContext;
};

export default async function transform(
this: LoaderContext<{ id: string }>,
this: LoaderContext<TransformLoaderOptions>,
source: string,
map?: string | RspackSourceMap,
): Promise<void> {
const callback = this.async();
const bypass = () => callback(null, source, map);

const transformId = this.getOptions().id;
const { id: transformId, getEnvironment } = this.getOptions();
if (!transformId) {
return bypass();
}
Expand All @@ -24,6 +33,7 @@ export default async function transform(
resource: this.resource,
resourcePath: this.resourcePath,
resourceQuery: this.resourceQuery,
environment: getEnvironment(),
addDependency: this.addDependency,
emitFile: this.emitFile as TransformContext['emitFile'],
});
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
} from './config';
import type { RsbuildContext } from './context';
import type {
EnvironmentContext,
ModifyBundlerChainFn,
ModifyChainUtils,
ModifyEnvironmentConfigFn,
Expand Down Expand Up @@ -180,6 +181,10 @@ export type TransformContext = {
* @example '?foo=123'
*/
resourceQuery: string;
/**
* The environment context for current build.
*/
environment: EnvironmentContext;
/**
* Add an additional file as the dependency.
* The file will be watched and changes to the file will trigger rebuild.
Expand Down
1 change: 1 addition & 0 deletions packages/core/tests/__snapshots__/default.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe
{
"loader": "<ROOT>/packages/core/dist/transformRawLoader.cjs",
"options": {
"getEnvironment": [Function],
"id": "rsbuild-transform-0",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1955,6 +1955,7 @@ exports[`environment config > tools.rspack / bundlerChain can be used in environ
{
"loader": "<ROOT>/packages/core/src/transformRawLoader.cjs",
"options": {
"getEnvironment": [Function],
"id": "rsbuild-transform-0",
},
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/tests/__snapshots__/nodeAddons.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exports[`plugin-node-addons > should add node addons rule properly 1`] = `
{
"loader": "<ROOT>/packages/core/dist/transformRawLoader.cjs",
"options": {
"getEnvironment": [Function],
"id": "rsbuild-transform-0",
},
},
Expand Down
2 changes: 2 additions & 0 deletions website/docs/en/plugins/dev/core.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ type TransformContext = {
resource: string;
resourcePath: string;
resourceQuery: string;
environment: EnvironmentContext;
addDependency: (file: string) => void;
emitFile: (
name: string,
Expand Down Expand Up @@ -295,6 +296,7 @@ The `handler` function provides the following params:
- `resource`: The absolute path of the module, including the query.
- `resourcePath`: The absolute path of the module, without the query.
- `resourceQuery`: The query of the module.
- `environment`: The [environment context](/api/javascript-api/types#environmentcontext) for current build.
- `addDependency`: Add an additional file as the dependency. The file will be watched and changes to the file will trigger rebuild.
- `emitFile`: Emits a file to the build output.

Expand Down
4 changes: 3 additions & 1 deletion website/docs/en/plugins/dev/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,9 @@ type Context = {
* @example 'index.html'
*/
filename: string;
/** The environment context for current build. */
/**
* The environment context for current build.
*/
environment: EnvironmentContext;
};

Expand Down
2 changes: 2 additions & 0 deletions website/docs/zh/plugins/dev/core.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ type TransformContext = {
resource: string;
resourcePath: string;
resourceQuery: string;
environment: EnvironmentContext;
addDependency: (file: string) => void;
emitFile: (
name: string,
Expand Down Expand Up @@ -293,6 +294,7 @@ handler 函数提供以下参数:
- `resource`:模块的绝对路径,包含 query。
- `resourcePath`:模块的绝对路径,不包含 query。
- `resourceQuery`:模块路径上的 query。
- `environment`: 当前构建的 [environment 上下文](/api/javascript-api/types#environmentcontext).
- `addDependency`:添加一个额外的文件作为依赖。该文件将被监听,并在发生变更时触发重新构建。
- `emitFile`:将一个文件输出到构建结果中。

Expand Down
2 changes: 1 addition & 1 deletion website/docs/zh/plugins/dev/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ type Context = {
*/
filename: string;
/**
* 本次构建的 environment 上下文
* 当前构建的 environment 上下文
*/
environment: EnvironmentContext;
};
Expand Down

0 comments on commit 7746922

Please sign in to comment.