@rsbuild/plugin-react 1.0.0 → 1.0.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Rsbuild
6
6
 
7
- Unleash the power of Rspack with the out-of-the-box build tool.
7
+ The Rspack-based build tool. It's fast, out-of-the-box and extensible.
8
8
 
9
9
  ## Documentation
10
10
 
package/dist/index.cjs ADDED
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ PLUGIN_REACT_NAME: () => PLUGIN_REACT_NAME,
34
+ pluginReact: () => pluginReact
35
+ });
36
+ module.exports = __toCommonJS(src_exports);
37
+
38
+ // src/react.ts
39
+ var import_node_path = __toESM(require("path"));
40
+ var modifySwcLoaderOptions = ({
41
+ chain,
42
+ CHAIN_ID,
43
+ modifier
44
+ }) => {
45
+ const ruleIds = [CHAIN_ID.RULE.JS, CHAIN_ID.RULE.JS_DATA_URI];
46
+ for (const ruleId of ruleIds) {
47
+ if (chain.module.rules.has(ruleId)) {
48
+ const rule = chain.module.rule(ruleId);
49
+ if (rule.uses.has(CHAIN_ID.USE.SWC)) {
50
+ rule.use(CHAIN_ID.USE.SWC).tap(modifier);
51
+ }
52
+ }
53
+ }
54
+ };
55
+ var applyBasicReactSupport = (api, options) => {
56
+ const REACT_REFRESH_PATH = require.resolve("react-refresh");
57
+ api.modifyBundlerChain(
58
+ async (chain, { CHAIN_ID, environment, isDev, isProd, target }) => {
59
+ const { config } = environment;
60
+ const usingHMR = !isProd && config.dev.hmr && target === "web";
61
+ const reactOptions = {
62
+ development: isDev,
63
+ refresh: usingHMR,
64
+ runtime: "automatic",
65
+ ...options.swcReactOptions
66
+ };
67
+ modifySwcLoaderOptions({
68
+ chain,
69
+ CHAIN_ID,
70
+ modifier: (opts) => {
71
+ opts.jsc ||= {};
72
+ opts.jsc.transform ||= {};
73
+ opts.jsc.transform.react = reactOptions;
74
+ opts.jsc.parser = {
75
+ ...opts.jsc.parser,
76
+ syntax: "typescript",
77
+ // enable supports for React JSX/TSX compilation
78
+ tsx: true
79
+ };
80
+ return opts;
81
+ }
82
+ });
83
+ if (!usingHMR) {
84
+ return;
85
+ }
86
+ chain.resolve.alias.set(
87
+ "react-refresh",
88
+ import_node_path.default.dirname(REACT_REFRESH_PATH)
89
+ );
90
+ const { default: ReactRefreshRspackPlugin } = await import("@rspack/plugin-react-refresh");
91
+ const SCRIPT_REGEX = /\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/;
92
+ chain.plugin(CHAIN_ID.PLUGIN.REACT_FAST_REFRESH).use(ReactRefreshRspackPlugin, [
93
+ {
94
+ include: [SCRIPT_REGEX],
95
+ ...options.reactRefreshOptions
96
+ }
97
+ ]);
98
+ }
99
+ );
100
+ };
101
+ var applyReactProfiler = (api) => {
102
+ api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => {
103
+ const enableProfilerConfig = {
104
+ output: {
105
+ minify: {
106
+ jsOptions: {
107
+ // Need to keep classnames and function names like Components for debugging purposes.
108
+ mangle: {
109
+ keep_classnames: true,
110
+ keep_fnames: true
111
+ }
112
+ }
113
+ }
114
+ }
115
+ };
116
+ return mergeRsbuildConfig(config, enableProfilerConfig);
117
+ });
118
+ api.modifyBundlerChain((chain) => {
119
+ chain.resolve.alias.set("react-dom$", "react-dom/profiling");
120
+ chain.resolve.alias.set("scheduler/tracing", "scheduler/tracing-profiling");
121
+ });
122
+ };
123
+
124
+ // src/splitChunks.ts
125
+ var isPlainObject = (obj) => obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
126
+ var applySplitChunksRule = (api, options = {
127
+ react: true,
128
+ router: true
129
+ }) => {
130
+ api.modifyBundlerChain((chain, { environment, isProd }) => {
131
+ const { config } = environment;
132
+ if (config.performance.chunkSplit.strategy !== "split-by-experience") {
133
+ return;
134
+ }
135
+ const currentConfig = chain.optimization.splitChunks.values();
136
+ if (!isPlainObject(currentConfig)) {
137
+ return;
138
+ }
139
+ const extraGroups = {};
140
+ if (options.react) {
141
+ extraGroups.react = {
142
+ name: "lib-react",
143
+ test: isProd ? /node_modules[\\/](?:react|react-dom|scheduler)[\\/]/ : /node_modules[\\/](?:react|react-dom|scheduler|react-refresh|@rspack[\\/]plugin-react-refresh)[\\/]/,
144
+ priority: 0
145
+ };
146
+ }
147
+ if (options.router) {
148
+ extraGroups.router = {
149
+ name: "lib-router",
150
+ test: /node_modules[\\/](?:react-router|react-router-dom|history|@remix-run[\\/]router)[\\/]/,
151
+ priority: 0
152
+ };
153
+ }
154
+ if (!Object.keys(extraGroups).length) {
155
+ return;
156
+ }
157
+ chain.optimization.splitChunks({
158
+ ...currentConfig,
159
+ cacheGroups: {
160
+ ...currentConfig.cacheGroups,
161
+ ...extraGroups
162
+ }
163
+ });
164
+ });
165
+ };
166
+
167
+ // src/index.ts
168
+ var PLUGIN_REACT_NAME = "rsbuild:react";
169
+ var pluginReact = ({
170
+ enableProfiler = false,
171
+ ...options
172
+ } = {}) => ({
173
+ name: PLUGIN_REACT_NAME,
174
+ setup(api) {
175
+ if (api.context.bundlerType === "rspack") {
176
+ applyBasicReactSupport(api, options);
177
+ const isProdProfile = enableProfiler && process.env.NODE_ENV === "production";
178
+ if (isProdProfile) {
179
+ applyReactProfiler(api);
180
+ }
181
+ }
182
+ applySplitChunksRule(api, options?.splitChunks);
183
+ }
184
+ });
185
+ // Annotate the CommonJS export names for ESM import in node:
186
+ 0 && (module.exports = {
187
+ PLUGIN_REACT_NAME,
188
+ pluginReact
189
+ });
package/dist/index.d.ts CHANGED
@@ -1,7 +1,39 @@
1
- import { RsbuildPlugin } from '@rsbuild/core';
2
-
3
- declare const isBeyondReact17: (cwd: string) => Promise<boolean>;
4
-
5
- declare const pluginReact: () => RsbuildPlugin;
6
-
7
- export { isBeyondReact17, pluginReact };
1
+ import type { RsbuildPlugin, Rspack } from '@rsbuild/core';
2
+ import type { PluginOptions as ReactRefreshOptions } from '@rspack/plugin-react-refresh';
3
+ export type SplitReactChunkOptions = {
4
+ /**
5
+ * Whether to enable split chunking for React-related dependencies (e.g., react, react-dom, scheduler).
6
+ *
7
+ * @default true
8
+ */
9
+ react?: boolean;
10
+ /**
11
+ * Whether to enable split chunking for routing-related dependencies (e.g., react-router, react-router-dom, history).
12
+ *
13
+ * @default true
14
+ */
15
+ router?: boolean;
16
+ };
17
+ export type PluginReactOptions = {
18
+ /**
19
+ * Configure the behavior of SWC to transform React code,
20
+ * the same as SWC's [jsc.transform.react](https://swc.rs/docs/configuration/compilation#jsctransformreact).
21
+ */
22
+ swcReactOptions?: Rspack.SwcLoaderTransformConfig['react'];
23
+ /**
24
+ * Configuration for chunk splitting of React-related dependencies.
25
+ */
26
+ splitChunks?: SplitReactChunkOptions;
27
+ /**
28
+ * When set to `true`, enables the React Profiler for performance analysis in production builds.
29
+ * @default false
30
+ */
31
+ enableProfiler?: boolean;
32
+ /**
33
+ * Options passed to `@rspack/plugin-react-refresh`
34
+ * @see https://rspack.dev/guide/tech/react#rspackplugin-react-refresh
35
+ */
36
+ reactRefreshOptions?: ReactRefreshOptions;
37
+ };
38
+ export declare const PLUGIN_REACT_NAME = "rsbuild:react";
39
+ export declare const pluginReact: ({ enableProfiler, ...options }?: PluginReactOptions) => RsbuildPlugin;
package/dist/index.js CHANGED
@@ -1,135 +1,137 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ import { createRequire } from 'module';
2
+ var require = createRequire(import.meta['url']);
29
3
 
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- isBeyondReact17: () => isBeyondReact17,
34
- pluginReact: () => pluginReact
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined")
8
+ return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
35
10
  });
36
- module.exports = __toCommonJS(src_exports);
37
11
 
38
- // src/antd.ts
39
- var import_shared = require("@rsbuild/shared");
40
- var getAntdMajorVersion = (appDirectory) => {
41
- try {
42
- const pkgJsonPath = require.resolve("antd/package.json", {
43
- paths: [appDirectory]
44
- });
45
- const { version } = require(pkgJsonPath);
46
- return Number(version.split(".")[0]);
47
- } catch (err) {
48
- return null;
12
+ // ../../node_modules/.pnpm/@modern-js+module-tools@2.55.0_eslint@9.6.0_typescript@5.5.2/node_modules/@modern-js/module-tools/shims/esm.js
13
+ import { fileURLToPath } from "url";
14
+ import path from "path";
15
+
16
+ // src/react.ts
17
+ import path2 from "path";
18
+ var modifySwcLoaderOptions = ({
19
+ chain,
20
+ CHAIN_ID,
21
+ modifier
22
+ }) => {
23
+ const ruleIds = [CHAIN_ID.RULE.JS, CHAIN_ID.RULE.JS_DATA_URI];
24
+ for (const ruleId of ruleIds) {
25
+ if (chain.module.rules.has(ruleId)) {
26
+ const rule = chain.module.rule(ruleId);
27
+ if (rule.uses.has(CHAIN_ID.USE.SWC)) {
28
+ rule.use(CHAIN_ID.USE.SWC).tap(modifier);
29
+ }
30
+ }
49
31
  }
50
32
  };
51
- var applyAntdSupport = (api) => {
52
- api.modifyRsbuildConfig((rsbuildConfig) => {
53
- var _a, _b, _c;
54
- (_a = rsbuildConfig.source) != null ? _a : rsbuildConfig.source = {};
55
- if (rsbuildConfig.source.transformImport === false || ((_b = rsbuildConfig.source.transformImport) == null ? void 0 : _b.some(
56
- (item) => item.libraryName === "antd"
57
- ))) {
58
- return;
59
- }
60
- const antdMajorVersion = getAntdMajorVersion(api.context.rootPath);
61
- if (antdMajorVersion && antdMajorVersion < 5) {
62
- (_c = rsbuildConfig.source) != null ? _c : rsbuildConfig.source = {};
63
- rsbuildConfig.source.transformImport = [
64
- ...rsbuildConfig.source.transformImport || [],
33
+ var applyBasicReactSupport = (api, options) => {
34
+ const REACT_REFRESH_PATH = __require.resolve("react-refresh");
35
+ api.modifyBundlerChain(
36
+ async (chain, { CHAIN_ID, environment, isDev, isProd, target }) => {
37
+ const { config } = environment;
38
+ const usingHMR = !isProd && config.dev.hmr && target === "web";
39
+ const reactOptions = {
40
+ development: isDev,
41
+ refresh: usingHMR,
42
+ runtime: "automatic",
43
+ ...options.swcReactOptions
44
+ };
45
+ modifySwcLoaderOptions({
46
+ chain,
47
+ CHAIN_ID,
48
+ modifier: (opts) => {
49
+ opts.jsc ||= {};
50
+ opts.jsc.transform ||= {};
51
+ opts.jsc.transform.react = reactOptions;
52
+ opts.jsc.parser = {
53
+ ...opts.jsc.parser,
54
+ syntax: "typescript",
55
+ // enable supports for React JSX/TSX compilation
56
+ tsx: true
57
+ };
58
+ return opts;
59
+ }
60
+ });
61
+ if (!usingHMR) {
62
+ return;
63
+ }
64
+ chain.resolve.alias.set(
65
+ "react-refresh",
66
+ path2.dirname(REACT_REFRESH_PATH)
67
+ );
68
+ const { default: ReactRefreshRspackPlugin } = await import("@rspack/plugin-react-refresh");
69
+ const SCRIPT_REGEX = /\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/;
70
+ chain.plugin(CHAIN_ID.PLUGIN.REACT_FAST_REFRESH).use(ReactRefreshRspackPlugin, [
65
71
  {
66
- libraryName: "antd",
67
- libraryDirectory: (0, import_shared.isServerTarget)(api.context.target) ? "lib" : "es",
68
- style: true
72
+ include: [SCRIPT_REGEX],
73
+ ...options.reactRefreshOptions
69
74
  }
70
- ];
75
+ ]);
71
76
  }
72
- });
77
+ );
73
78
  };
74
-
75
- // src/arco.ts
76
- var import_shared2 = require("@rsbuild/shared");
77
- var applyArcoSupport = (api) => {
78
- const ARCO_NAME = "@arco-design/web-react";
79
- const ARCO_ICON = `${ARCO_NAME}/icon`;
80
- api.modifyRsbuildConfig((rsbuildConfig) => {
81
- const { transformImport = [] } = rsbuildConfig.source || {};
82
- if (transformImport === false || !(0, import_shared2.isPackageInstalled)(ARCO_NAME, api.context.rootPath)) {
83
- return;
84
- }
85
- const isUseSSR = (0, import_shared2.isServerTarget)(api.context.target);
86
- if (!(transformImport == null ? void 0 : transformImport.some((item) => item.libraryName === ARCO_NAME))) {
87
- transformImport.push({
88
- libraryName: ARCO_NAME,
89
- libraryDirectory: isUseSSR ? "lib" : "es",
90
- camelToDashComponentName: false,
91
- style: true
92
- });
93
- }
94
- if (!(transformImport == null ? void 0 : transformImport.some((item) => item.libraryName === ARCO_ICON))) {
95
- transformImport.push({
96
- libraryName: ARCO_ICON,
97
- libraryDirectory: isUseSSR ? "react-icon-cjs" : "react-icon",
98
- camelToDashComponentName: false
99
- });
100
- }
101
- rsbuildConfig.source || (rsbuildConfig.source = {});
102
- rsbuildConfig.source.transformImport = transformImport;
79
+ var applyReactProfiler = (api) => {
80
+ api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => {
81
+ const enableProfilerConfig = {
82
+ output: {
83
+ minify: {
84
+ jsOptions: {
85
+ // Need to keep classnames and function names like Components for debugging purposes.
86
+ mangle: {
87
+ keep_classnames: true,
88
+ keep_fnames: true
89
+ }
90
+ }
91
+ }
92
+ }
93
+ };
94
+ return mergeRsbuildConfig(config, enableProfilerConfig);
95
+ });
96
+ api.modifyBundlerChain((chain) => {
97
+ chain.resolve.alias.set("react-dom$", "react-dom/profiling");
98
+ chain.resolve.alias.set("scheduler/tracing", "scheduler/tracing-profiling");
103
99
  });
104
100
  };
105
101
 
106
102
  // src/splitChunks.ts
107
- var import_shared3 = require("@rsbuild/shared");
108
- var applySplitChunksRule = (api) => {
109
- api.modifyBundlerChain((chain) => {
110
- const config = api.getNormalizedConfig();
111
- const { chunkSplit } = config.performance || {};
112
- if ((chunkSplit == null ? void 0 : chunkSplit.strategy) !== "split-by-experience") {
103
+ var isPlainObject = (obj) => obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
104
+ var applySplitChunksRule = (api, options = {
105
+ react: true,
106
+ router: true
107
+ }) => {
108
+ api.modifyBundlerChain((chain, { environment, isProd }) => {
109
+ const { config } = environment;
110
+ if (config.performance.chunkSplit.strategy !== "split-by-experience") {
113
111
  return;
114
112
  }
115
113
  const currentConfig = chain.optimization.splitChunks.values();
116
- if (!(0, import_shared3.isPlainObject)(currentConfig)) {
114
+ if (!isPlainObject(currentConfig)) {
115
+ return;
116
+ }
117
+ const extraGroups = {};
118
+ if (options.react) {
119
+ extraGroups.react = {
120
+ name: "lib-react",
121
+ test: isProd ? /node_modules[\\/](?:react|react-dom|scheduler)[\\/]/ : /node_modules[\\/](?:react|react-dom|scheduler|react-refresh|@rspack[\\/]plugin-react-refresh)[\\/]/,
122
+ priority: 0
123
+ };
124
+ }
125
+ if (options.router) {
126
+ extraGroups.router = {
127
+ name: "lib-router",
128
+ test: /node_modules[\\/](?:react-router|react-router-dom|history|@remix-run[\\/]router)[\\/]/,
129
+ priority: 0
130
+ };
131
+ }
132
+ if (!Object.keys(extraGroups).length) {
117
133
  return;
118
134
  }
119
- const extraGroups = (0, import_shared3.createCacheGroups)({
120
- react: [
121
- "react",
122
- "react-dom",
123
- "scheduler",
124
- ...(0, import_shared3.isProd)() ? [] : ["react-refresh", "@pmmmwh/react-refresh-webpack-plugin"]
125
- ],
126
- router: [
127
- "react-router",
128
- "react-router-dom",
129
- "@remix-run/router",
130
- "history"
131
- ]
132
- });
133
135
  chain.optimization.splitChunks({
134
136
  ...currentConfig,
135
137
  cacheGroups: {
@@ -140,110 +142,25 @@ var applySplitChunksRule = (api) => {
140
142
  });
141
143
  };
142
144
 
143
- // src/react.ts
144
- var import_shared4 = require("@rsbuild/shared");
145
- function getReactRefreshEntry(compiler) {
146
- var _a, _b, _c, _d, _e;
147
- const hot = (_b = (_a = compiler.options.devServer) == null ? void 0 : _a.hot) != null ? _b : true;
148
- const refresh = (_e = (_d = (_c = compiler.options.builtins) == null ? void 0 : _c.react) == null ? void 0 : _d.refresh) != null ? _e : true;
149
- if (hot && refresh) {
150
- const reactRefreshEntryPath = require.resolve("@rspack/plugin-react-refresh/react-refresh-entry");
151
- return reactRefreshEntryPath;
152
- }
153
- return null;
154
- }
155
- var setupCompiler = (compiler) => {
156
- if (!(0, import_shared4.isClientCompiler)(compiler)) {
157
- return;
158
- }
159
- const reactRefreshEntry = getReactRefreshEntry(compiler);
160
- if (!reactRefreshEntry) {
161
- return;
162
- }
163
- for (const key in compiler.options.entry) {
164
- compiler.options.entry[key].import = [
165
- reactRefreshEntry,
166
- ...compiler.options.entry[key].import || []
167
- ];
168
- }
169
- };
170
- var applyBasicReactSupport = (api) => {
171
- api.onAfterCreateCompiler(({ compiler: multiCompiler }) => {
172
- if ((0, import_shared4.isProd)()) {
173
- return;
174
- }
175
- if (multiCompiler.compilers) {
176
- multiCompiler.compilers.forEach(setupCompiler);
177
- } else {
178
- setupCompiler(multiCompiler);
179
- }
180
- });
181
- api.modifyBundlerChain(async (chain, { CHAIN_ID, isProd: isProd3, target }) => {
182
- const config = api.getNormalizedConfig();
183
- const usingHMR = (0, import_shared4.isUsingHMR)(config, { isProd: isProd3, target });
184
- const rule = chain.module.rule(CHAIN_ID.RULE.JS);
185
- const reactOptions = {
186
- development: !isProd3,
187
- refresh: usingHMR,
188
- runtime: "automatic"
189
- };
190
- rule.use(CHAIN_ID.USE.SWC).tap((options) => {
191
- options.jsc.transform.react = {
192
- ...reactOptions
193
- };
194
- return options;
195
- });
196
- if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) {
197
- chain.module.rule(CHAIN_ID.RULE.JS_DATA_URI).use(CHAIN_ID.USE.SWC).tap((options) => {
198
- options.jsc.transform.react = {
199
- ...reactOptions
200
- };
201
- return options;
202
- });
203
- }
204
- if (!usingHMR) {
205
- return;
206
- }
207
- const { default: ReactRefreshRspackPlugin } = await import("@rspack/plugin-react-refresh");
208
- chain.plugin(CHAIN_ID.PLUGIN.REACT_FAST_REFRESH).use(ReactRefreshRspackPlugin);
209
- });
210
- };
211
-
212
- // src/utils.ts
213
- var import_fs = __toESM(require("fs"));
214
- var import_semver = __toESM(require("semver"));
215
- var import_shared5 = require("@rsbuild/shared");
216
- var isBeyondReact17 = async (cwd) => {
217
- const pkgPath = await (0, import_shared5.findUp)({ cwd, filename: "package.json" });
218
- if (!pkgPath) {
219
- return false;
220
- }
221
- const pkgInfo = JSON.parse(import_fs.default.readFileSync(pkgPath, "utf8"));
222
- const deps = {
223
- ...pkgInfo.devDependencies,
224
- ...pkgInfo.dependencies
225
- };
226
- if (typeof deps.react !== "string") {
227
- return false;
228
- }
229
- return import_semver.default.satisfies(import_semver.default.minVersion(deps.react), ">=17.0.0");
230
- };
231
-
232
145
  // src/index.ts
233
- var pluginReact = () => ({
234
- name: "rsbuild:react",
235
- pre: ["rsbuild:swc"],
146
+ var PLUGIN_REACT_NAME = "rsbuild:react";
147
+ var pluginReact = ({
148
+ enableProfiler = false,
149
+ ...options
150
+ } = {}) => ({
151
+ name: PLUGIN_REACT_NAME,
236
152
  setup(api) {
237
153
  if (api.context.bundlerType === "rspack") {
238
- applyBasicReactSupport(api);
154
+ applyBasicReactSupport(api, options);
155
+ const isProdProfile = enableProfiler && process.env.NODE_ENV === "production";
156
+ if (isProdProfile) {
157
+ applyReactProfiler(api);
158
+ }
239
159
  }
240
- applyAntdSupport(api);
241
- applyArcoSupport(api);
242
- applySplitChunksRule(api);
160
+ applySplitChunksRule(api, options?.splitChunks);
243
161
  }
244
162
  });
245
- // Annotate the CommonJS export names for ESM import in node:
246
- 0 && (module.exports = {
247
- isBeyondReact17,
163
+ export {
164
+ PLUGIN_REACT_NAME,
248
165
  pluginReact
249
- });
166
+ };
@@ -0,0 +1,4 @@
1
+ import type { RsbuildPluginAPI } from '@rsbuild/core';
2
+ import type { PluginReactOptions } from '.';
3
+ export declare const applyBasicReactSupport: (api: RsbuildPluginAPI, options: PluginReactOptions) => void;
4
+ export declare const applyReactProfiler: (api: RsbuildPluginAPI) => void;
@@ -0,0 +1,3 @@
1
+ import type { RsbuildPluginAPI } from '@rsbuild/core';
2
+ import type { SplitReactChunkOptions } from '.';
3
+ export declare const applySplitChunksRule: (api: RsbuildPluginAPI, options?: SplitReactChunkOptions) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsbuild/plugin-react",
3
- "version": "1.0.0",
3
+ "version": "1.0.1-beta.1",
4
4
  "description": "React plugin for Rsbuild",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,30 +8,31 @@
8
8
  "directory": "packages/plugin-react"
9
9
  },
10
10
  "license": "MIT",
11
+ "type": "module",
11
12
  "exports": {
12
13
  ".": {
13
14
  "types": "./dist/index.d.ts",
14
- "import": "./dist/index.mjs",
15
- "default": "./dist/index.js"
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
16
17
  }
17
18
  },
18
- "main": "./dist/index.js",
19
+ "main": "./dist/index.cjs",
19
20
  "types": "./dist/index.d.ts",
20
21
  "files": [
21
22
  "dist"
22
23
  ],
23
24
  "dependencies": {
24
- "@rspack/plugin-react-refresh": "0.4.0",
25
- "react-refresh": "^0.14.0",
26
- "semver": "^7.5.4",
27
- "@rsbuild/shared": "1.0.0"
25
+ "@rspack/plugin-react-refresh": "1.0.0-alpha.3",
26
+ "react-refresh": "^0.14.2"
28
27
  },
29
28
  "devDependencies": {
30
- "@types/node": "^16",
31
- "@types/semver": "^7.5.4",
32
- "typescript": "^5.3.0",
33
- "@rsbuild/core": "1.0.0",
34
- "@rsbuild/test-helper": "1.0.0"
29
+ "@types/node": "18.x",
30
+ "typescript": "^5.5.2",
31
+ "@rsbuild/core": "1.0.1-beta.1",
32
+ "@scripts/test-helper": "1.0.1-beta.1"
33
+ },
34
+ "peerDependencies": {
35
+ "@rsbuild/core": "^1.0.1-beta.0"
35
36
  },
36
37
  "publishConfig": {
37
38
  "access": "public",
package/dist/index.mjs DELETED
@@ -1,234 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined")
5
- return require.apply(this, arguments);
6
- throw Error('Dynamic require of "' + x + '" is not supported');
7
- });
8
-
9
- // ../../node_modules/.pnpm/@modern-js+module-tools@2.40.0_typescript@5.3.2/node_modules/@modern-js/module-tools/shims/esm.js
10
- import { fileURLToPath } from "url";
11
- import path from "path";
12
-
13
- // ../../scripts/require_shims.js
14
- import { createRequire } from "module";
15
- global.require = createRequire(import.meta.url);
16
-
17
- // src/antd.ts
18
- import { isServerTarget } from "@rsbuild/shared";
19
- var getAntdMajorVersion = (appDirectory) => {
20
- try {
21
- const pkgJsonPath = __require.resolve("antd/package.json", {
22
- paths: [appDirectory]
23
- });
24
- const { version } = __require(pkgJsonPath);
25
- return Number(version.split(".")[0]);
26
- } catch (err) {
27
- return null;
28
- }
29
- };
30
- var applyAntdSupport = (api) => {
31
- api.modifyRsbuildConfig((rsbuildConfig) => {
32
- rsbuildConfig.source ?? (rsbuildConfig.source = {});
33
- if (rsbuildConfig.source.transformImport === false || rsbuildConfig.source.transformImport?.some(
34
- (item) => item.libraryName === "antd"
35
- )) {
36
- return;
37
- }
38
- const antdMajorVersion = getAntdMajorVersion(api.context.rootPath);
39
- if (antdMajorVersion && antdMajorVersion < 5) {
40
- rsbuildConfig.source ?? (rsbuildConfig.source = {});
41
- rsbuildConfig.source.transformImport = [
42
- ...rsbuildConfig.source.transformImport || [],
43
- {
44
- libraryName: "antd",
45
- libraryDirectory: isServerTarget(api.context.target) ? "lib" : "es",
46
- style: true
47
- }
48
- ];
49
- }
50
- });
51
- };
52
-
53
- // src/arco.ts
54
- import {
55
- isServerTarget as isServerTarget2,
56
- isPackageInstalled
57
- } from "@rsbuild/shared";
58
- var applyArcoSupport = (api) => {
59
- const ARCO_NAME = "@arco-design/web-react";
60
- const ARCO_ICON = `${ARCO_NAME}/icon`;
61
- api.modifyRsbuildConfig((rsbuildConfig) => {
62
- const { transformImport = [] } = rsbuildConfig.source || {};
63
- if (transformImport === false || !isPackageInstalled(ARCO_NAME, api.context.rootPath)) {
64
- return;
65
- }
66
- const isUseSSR = isServerTarget2(api.context.target);
67
- if (!transformImport?.some((item) => item.libraryName === ARCO_NAME)) {
68
- transformImport.push({
69
- libraryName: ARCO_NAME,
70
- libraryDirectory: isUseSSR ? "lib" : "es",
71
- camelToDashComponentName: false,
72
- style: true
73
- });
74
- }
75
- if (!transformImport?.some((item) => item.libraryName === ARCO_ICON)) {
76
- transformImport.push({
77
- libraryName: ARCO_ICON,
78
- libraryDirectory: isUseSSR ? "react-icon-cjs" : "react-icon",
79
- camelToDashComponentName: false
80
- });
81
- }
82
- rsbuildConfig.source || (rsbuildConfig.source = {});
83
- rsbuildConfig.source.transformImport = transformImport;
84
- });
85
- };
86
-
87
- // src/splitChunks.ts
88
- import {
89
- isProd,
90
- isPlainObject,
91
- createCacheGroups
92
- } from "@rsbuild/shared";
93
- var applySplitChunksRule = (api) => {
94
- api.modifyBundlerChain((chain) => {
95
- const config = api.getNormalizedConfig();
96
- const { chunkSplit } = config.performance || {};
97
- if (chunkSplit?.strategy !== "split-by-experience") {
98
- return;
99
- }
100
- const currentConfig = chain.optimization.splitChunks.values();
101
- if (!isPlainObject(currentConfig)) {
102
- return;
103
- }
104
- const extraGroups = createCacheGroups({
105
- react: [
106
- "react",
107
- "react-dom",
108
- "scheduler",
109
- ...isProd() ? [] : ["react-refresh", "@pmmmwh/react-refresh-webpack-plugin"]
110
- ],
111
- router: [
112
- "react-router",
113
- "react-router-dom",
114
- "@remix-run/router",
115
- "history"
116
- ]
117
- });
118
- chain.optimization.splitChunks({
119
- ...currentConfig,
120
- cacheGroups: {
121
- ...currentConfig.cacheGroups,
122
- ...extraGroups
123
- }
124
- });
125
- });
126
- };
127
-
128
- // src/react.ts
129
- import { isUsingHMR, isClientCompiler, isProd as isProd2 } from "@rsbuild/shared";
130
- function getReactRefreshEntry(compiler) {
131
- const hot = compiler.options.devServer?.hot ?? true;
132
- const refresh = compiler.options.builtins?.react?.refresh ?? true;
133
- if (hot && refresh) {
134
- const reactRefreshEntryPath = __require.resolve(
135
- "@rspack/plugin-react-refresh/react-refresh-entry"
136
- );
137
- return reactRefreshEntryPath;
138
- }
139
- return null;
140
- }
141
- var setupCompiler = (compiler) => {
142
- if (!isClientCompiler(compiler)) {
143
- return;
144
- }
145
- const reactRefreshEntry = getReactRefreshEntry(compiler);
146
- if (!reactRefreshEntry) {
147
- return;
148
- }
149
- for (const key in compiler.options.entry) {
150
- compiler.options.entry[key].import = [
151
- reactRefreshEntry,
152
- ...compiler.options.entry[key].import || []
153
- ];
154
- }
155
- };
156
- var applyBasicReactSupport = (api) => {
157
- api.onAfterCreateCompiler(({ compiler: multiCompiler }) => {
158
- if (isProd2()) {
159
- return;
160
- }
161
- if (multiCompiler.compilers) {
162
- multiCompiler.compilers.forEach(setupCompiler);
163
- } else {
164
- setupCompiler(multiCompiler);
165
- }
166
- });
167
- api.modifyBundlerChain(async (chain, { CHAIN_ID, isProd: isProd3, target }) => {
168
- const config = api.getNormalizedConfig();
169
- const usingHMR = isUsingHMR(config, { isProd: isProd3, target });
170
- const rule = chain.module.rule(CHAIN_ID.RULE.JS);
171
- const reactOptions = {
172
- development: !isProd3,
173
- refresh: usingHMR,
174
- runtime: "automatic"
175
- };
176
- rule.use(CHAIN_ID.USE.SWC).tap((options) => {
177
- options.jsc.transform.react = {
178
- ...reactOptions
179
- };
180
- return options;
181
- });
182
- if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) {
183
- chain.module.rule(CHAIN_ID.RULE.JS_DATA_URI).use(CHAIN_ID.USE.SWC).tap((options) => {
184
- options.jsc.transform.react = {
185
- ...reactOptions
186
- };
187
- return options;
188
- });
189
- }
190
- if (!usingHMR) {
191
- return;
192
- }
193
- const { default: ReactRefreshRspackPlugin } = await import("@rspack/plugin-react-refresh");
194
- chain.plugin(CHAIN_ID.PLUGIN.REACT_FAST_REFRESH).use(ReactRefreshRspackPlugin);
195
- });
196
- };
197
-
198
- // src/utils.ts
199
- import fs from "fs";
200
- import semver from "semver";
201
- import { findUp } from "@rsbuild/shared";
202
- var isBeyondReact17 = async (cwd) => {
203
- const pkgPath = await findUp({ cwd, filename: "package.json" });
204
- if (!pkgPath) {
205
- return false;
206
- }
207
- const pkgInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
208
- const deps = {
209
- ...pkgInfo.devDependencies,
210
- ...pkgInfo.dependencies
211
- };
212
- if (typeof deps.react !== "string") {
213
- return false;
214
- }
215
- return semver.satisfies(semver.minVersion(deps.react), ">=17.0.0");
216
- };
217
-
218
- // src/index.ts
219
- var pluginReact = () => ({
220
- name: "rsbuild:react",
221
- pre: ["rsbuild:swc"],
222
- setup(api) {
223
- if (api.context.bundlerType === "rspack") {
224
- applyBasicReactSupport(api);
225
- }
226
- applyAntdSupport(api);
227
- applyArcoSupport(api);
228
- applySplitChunksRule(api);
229
- }
230
- });
231
- export {
232
- isBeyondReact17,
233
- pluginReact
234
- };