Skip to content

Commit a28e69d

Browse files
authored
feat: support rsbuild modify config hook (#6840)
1 parent 3903cf9 commit a28e69d

File tree

12 files changed

+246
-0
lines changed

12 files changed

+246
-0
lines changed

.changeset/strange-rings-thank.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@modern-js/app-tools': minor
3+
---
4+
5+
feat: support rsbuild modify config hook
6+
7+
feat: 支持 rsbuild 修改配置的 Hook 函数

packages/solutions/app-tools/src/builder/generator/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,14 @@ async function applyBuilderPlugins<B extends Bundler>(
5959
builderPluginAdapterBasic,
6060
builderPluginAdapterHtml,
6161
builderPluginAdapterSSR,
62+
builderPluginAdapterHooks,
6263
} = await import('../shared/builderPlugins/index.js');
6364

6465
builder.addPlugins([
6566
builderPluginAdapterBasic(),
6667
builderPluginAdapterSSR(options),
6768
builderPluginAdapterHtml(options),
69+
builderPluginAdapterHooks(options),
6870
]);
6971

7072
builder.addPlugins([builderPluginAdapterCopy(options)], {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { RsbuildPlugin } from '@rsbuild/core';
2+
import type { Bundler } from '../../../types';
3+
import type { BuilderOptions } from '../types';
4+
5+
export const builderPluginAdapterHooks = <B extends Bundler>(
6+
options: BuilderOptions<B>,
7+
): RsbuildPlugin => ({
8+
name: 'builder-plugin-support-modern-hooks',
9+
setup(api) {
10+
const _internalContext = options.appContext._internalContext;
11+
const hooks = _internalContext.pluginAPI?.getHooks();
12+
api.modifyBundlerChain(async (chain, utils) => {
13+
await hooks?.modifyBundlerChain.call(chain, utils);
14+
});
15+
api.modifyRsbuildConfig(async (config, utils) => {
16+
await hooks?.modifyRsbuildConfig.call(config, utils);
17+
});
18+
api.modifyRspackConfig(async (config, utils) => {
19+
await hooks?.modifyRspackConfig.call(config, utils);
20+
});
21+
api.modifyWebpackChain(async (chain, utils) => {
22+
await hooks?.modifyWebpackChain.call(chain, utils);
23+
});
24+
api.modifyWebpackConfig(async (config, utils) => {
25+
await hooks?.modifyWebpackConfig.call(config, utils);
26+
});
27+
},
28+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './adapterBasic';
22
export * from './adapterHtml';
33
export * from './adapterSSR';
4+
export * from './builderHooks';

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {
2+
type AppTools,
3+
type CliPluginFuture,
4+
appTools,
5+
defineConfig,
6+
} from '@modern-js/app-tools';
7+
8+
const MyPlugin = (): CliPluginFuture<AppTools> => ({
9+
name: 'test',
10+
setup(api) {
11+
api.config(() => {
12+
return {
13+
tools: {
14+
webpack: () => {
15+
console.log('tools.webpack');
16+
},
17+
rspack: () => {
18+
console.log('tools.rspack');
19+
},
20+
bundlerChain: () => {
21+
console.log('tools.bundlerChain');
22+
},
23+
webpackChain: () => {
24+
console.log('tools.webpackChain');
25+
},
26+
},
27+
};
28+
});
29+
api.modifyBundlerChain(async (chain, utils) => {
30+
console.log('modifyBundlerChain');
31+
});
32+
api.modifyRsbuildConfig(async (config, utils) => {
33+
console.log('modifyRsbuildConfig');
34+
});
35+
api.modifyRspackConfig(async (config, utils) => {
36+
console.log('modifyRspackConfig');
37+
});
38+
api.modifyWebpackChain(async (chain, utils) => {
39+
console.log('modifyWebpackChain');
40+
});
41+
api.modifyWebpackConfig(async (config, utils) => {
42+
console.log('modifyWebpackConfig');
43+
});
44+
},
45+
});
46+
export default defineConfig({
47+
runtime: {
48+
router: true,
49+
},
50+
plugins: [
51+
appTools({
52+
bundler: process.env.BUNDLER === 'webpack' ? 'webpack' : 'rspack',
53+
}),
54+
MyPlugin(),
55+
],
56+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"private": true,
3+
"name": "app-rsbuild-hooks",
4+
"version": "2.64.3",
5+
"scripts": {
6+
"dev": "modern dev"
7+
},
8+
"dependencies": {
9+
"@modern-js/app-tools": "workspace:*",
10+
"@modern-js/runtime": "workspace:*",
11+
"react": "^18.3.1",
12+
"react-dom": "^18.3.1"
13+
}
14+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { RuntimeReactContext } from '@modern-js/runtime';
2+
import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';
3+
import { useContext } from 'react';
4+
5+
const App = () => {
6+
const context = useContext(RuntimeReactContext);
7+
const { initialData } = context;
8+
return (
9+
<BrowserRouter>
10+
<Routes>
11+
<Route index element={<div>index</div>} />
12+
<Route
13+
path="about"
14+
element={<div>about {initialData?.data as string}</div>}
15+
/>
16+
</Routes>
17+
</BrowserRouter>
18+
);
19+
};
20+
21+
App.init = () => {
22+
console.log('init');
23+
return {
24+
data: 'init data',
25+
};
26+
};
27+
28+
export default App;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// <reference types='@modern-js/app-tools/types' />
2+
/// <reference types='@modern-js/runtime/types' />
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { defineRuntimeConfig } from '@modern-js/runtime';
2+
3+
export default defineRuntimeConfig({
4+
plugins: [],
5+
});
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import path from 'path';
2+
import { modernBuild } from '../../../utils/modernTestUtils';
3+
4+
const appDir = path.resolve(__dirname, '../');
5+
6+
function processStdout(stdout: string) {
7+
const cleaned = stdout.replace(
8+
// biome-ignore lint/suspicious/noControlCharactersInRegex: <explanation>
9+
/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g,
10+
'',
11+
);
12+
return cleaned.replace(/\r\n/g, '\n').trim();
13+
}
14+
15+
function verifyOrder(output: string, expectedOrder: string[]): boolean {
16+
let currentIndex = 0;
17+
const lines = output.split('\n');
18+
19+
for (const line of lines) {
20+
if (line.includes(expectedOrder[currentIndex])) {
21+
currentIndex++;
22+
}
23+
if (currentIndex === expectedOrder.length) {
24+
return true;
25+
}
26+
}
27+
28+
return false;
29+
}
30+
describe('build with rspack', () => {
31+
test('rspack hooks', async () => {
32+
const buildResult = await modernBuild(appDir, [], {
33+
env: {
34+
BUNDLER: 'rspack',
35+
},
36+
});
37+
38+
expect(buildResult.code).toEqual(0);
39+
40+
const cleanOutput = processStdout(buildResult.stdout);
41+
const expectedOrder = [
42+
'modifyBundlerChain',
43+
'tools.bundlerChain',
44+
'modifyRspackConfig',
45+
'tools.rspack',
46+
];
47+
48+
expect(verifyOrder(cleanOutput, expectedOrder)).toBeTruthy();
49+
});
50+
});
51+
52+
describe('build with webpack', () => {
53+
test('webpack hooks', async () => {
54+
const buildResult = await modernBuild(appDir, [], {
55+
env: {
56+
BUNDLER: 'webpack',
57+
},
58+
});
59+
60+
expect(buildResult.code).toEqual(0);
61+
62+
const cleanOutput = processStdout(buildResult.stdout);
63+
const expectedOrder = [
64+
'modifyBundlerChain',
65+
'tools.bundlerChain',
66+
'modifyWebpackChain',
67+
'tools.webpackChain',
68+
'modifyWebpackConfig',
69+
'tools.webpack',
70+
];
71+
72+
expect(verifyOrder(cleanOutput, expectedOrder)).toBeTruthy();
73+
});
74+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "@modern-js/tsconfig/base",
3+
"compilerOptions": {
4+
"declaration": false,
5+
"jsx": "preserve",
6+
"baseUrl": "./",
7+
"outDir": "dist",
8+
"paths": {
9+
"@/*": ["./src/*"],
10+
"@shared/*": ["./shared/*"]
11+
}
12+
},
13+
"include": ["src", "tests", "modern.config.ts"]
14+
}

0 commit comments

Comments
 (0)