@bleedingdev/modern-js-builder 3.4.0-ultramodern.0 → 3.4.0-ultramodern.10

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.
@@ -45,7 +45,9 @@ var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_na
45
45
  const ASYNC_STORAGE_PATTERN = /universal[/\\]async_storage/;
46
46
  const SERVER_LOADER_ENTRY_PATTERN = /[/\\](?:server-loader-combined|route-server-loaders)\.js$/;
47
47
  const RENDER_RSC_SOURCE_PATTERN = /render[/\\].*[/\\]server[/\\]rsc/;
48
- const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc\.mjs$/;
48
+ const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc(?:Worker)?\.mjs$/;
49
+ const RENDER_RSC_RUNTIME = '@modern-js/render/rsc';
50
+ const RENDER_RSC_WORKER_RUNTIME = '@modern-js/render/rsc-worker';
49
51
  const RSC_COMMON_LAYER = 'rsc-common';
50
52
  const ENTRY_NAME_VAR = '__MODERN_JS_ENTRY_NAME';
51
53
  const createVirtualModule = (content)=>`data:text/javascript,${encodeURIComponent(content)}`;
@@ -54,6 +56,38 @@ const isAsyncStorageExclude = (exclude)=>{
54
56
  if (exclude instanceof RegExp) return exclude.test('universal/async_storage') || exclude.test('universal\\async_storage');
55
57
  return false;
56
58
  };
59
+ const asRecord = (value)=>{
60
+ if (value && 'object' == typeof value && !Array.isArray(value)) return value;
61
+ };
62
+ const disableReactCompilerInSwcLoaders = (value, seen = new WeakSet())=>{
63
+ if (!value || 'object' != typeof value) return;
64
+ if (seen.has(value)) return;
65
+ seen.add(value);
66
+ if (Array.isArray(value)) {
67
+ for (const item of value)disableReactCompilerInSwcLoaders(item, seen);
68
+ return;
69
+ }
70
+ const record = value;
71
+ if ('builtin:swc-loader' === record.loader) {
72
+ let options = asRecord(record.options);
73
+ if (!options) {
74
+ options = {};
75
+ record.options = options;
76
+ }
77
+ let jsc = asRecord(options.jsc);
78
+ if (!jsc) {
79
+ jsc = {};
80
+ options.jsc = jsc;
81
+ }
82
+ let transform = asRecord(jsc.transform);
83
+ if (!transform) {
84
+ transform = {};
85
+ jsc.transform = transform;
86
+ }
87
+ transform.reactCompiler = false;
88
+ }
89
+ for (const item of Object.values(record))disableReactCompilerInSwcLoaders(item, seen);
90
+ };
57
91
  function pluginRscConfig() {
58
92
  return {
59
93
  name: 'builder:rsc-config',
@@ -69,6 +103,7 @@ function pluginRscConfig() {
69
103
  api.modifyBundlerChain({
70
104
  handler: (chain, { isServer })=>{
71
105
  if (isServer) {
106
+ chain.resolve.alias.set(`${RENDER_RSC_RUNTIME}$`, RENDER_RSC_WORKER_RUNTIME);
72
107
  const routeFilePattern = /[/\\]routes[/\\](?:.*[/\\])?(?:layout|page|\$)\.[tj]sx?$/;
73
108
  const appFilePattern = /[/\\]App\.[tj]sx?$/;
74
109
  const combinedPattern = new RegExp(`(${routeFilePattern.source}|${appFilePattern.source})`);
@@ -107,6 +142,7 @@ function pluginRscConfig() {
107
142
  }
108
143
  if (config.module?.rules) {
109
144
  const rules = config.module.rules;
145
+ disableReactCompilerInSwcLoaders(rules);
110
146
  for (const rule of rules)if (rule.layer === Layers.rsc) {
111
147
  if (rule.exclude) {
112
148
  if (!Array.isArray(rule.exclude)) rule.exclude = [
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ const PERSISTENT_CACHE_MAX_AGE = 604800;
31
+ const PERSISTENT_CACHE_MAX_VERSIONS = 3;
32
+ const pluginRspack21 = ({ sourceImport } = {})=>({
33
+ name: 'modern-js:rspack-2-1-defaults',
34
+ setup (api) {
35
+ api.modifyRspackConfig((config)=>{
36
+ config.module ??= {};
37
+ config.module.parser ??= {};
38
+ config.module.parser.javascript ??= {};
39
+ config.module.parser.javascript.createRequire ??= true;
40
+ if ('object' == typeof config.cache && null !== config.cache && 'persistent' === config.cache.type) {
41
+ config.cache.maxAge ??= PERSISTENT_CACHE_MAX_AGE;
42
+ config.cache.maxVersions ??= PERSISTENT_CACHE_MAX_VERSIONS;
43
+ }
44
+ if (void 0 !== sourceImport) {
45
+ config.experiments ??= {};
46
+ config.experiments.sourceImport = sourceImport;
47
+ }
48
+ return config;
49
+ });
50
+ }
51
+ });
52
+ __webpack_require__.d(__webpack_exports__, {}, {
53
+ pluginRspack21: pluginRspack21
54
+ });
55
+ exports.pluginRspack21 = __webpack_exports__.pluginRspack21;
56
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
57
+ "pluginRspack21"
58
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
59
+ Object.defineProperty(exports, '__esModule', {
60
+ value: true
61
+ });
@@ -41,6 +41,7 @@ const emitRouteFile_js_namespaceObject = require("../plugins/emitRouteFile.js");
41
41
  const environmentDefaults_js_namespaceObject = require("../plugins/environmentDefaults.js");
42
42
  const globalVars_js_namespaceObject = require("../plugins/globalVars.js");
43
43
  const htmlMinify_js_namespaceObject = require("../plugins/htmlMinify.js");
44
+ const rspack21_js_namespaceObject = require("../plugins/rspack21.js");
44
45
  const runtimeChunk_js_namespaceObject = require("../plugins/runtimeChunk.js");
45
46
  const external_devServer_js_namespaceObject = require("./devServer.js");
46
47
  const external_tsgo_js_namespaceObject = require("./tsgo.js");
@@ -59,7 +60,7 @@ function removeUndefinedKey(obj) {
59
60
  }
60
61
  async function parseCommonConfig(builderConfig, options) {
61
62
  const frameworkConfigPath = options?.frameworkConfigPath;
62
- const { plugins: [...plugins] = [], splitChunks, performance: { rsdoctor: rsdoctorConfig, ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
63
+ const { plugins: [...plugins] = [], splitChunks, performance: { rsdoctor: rsdoctorConfig, ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
63
64
  let combinedAlias;
64
65
  if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
65
66
  const rsbuildConfig = {
@@ -135,7 +136,11 @@ async function parseCommonConfig(builderConfig, options) {
135
136
  rsbuildConfig.dev = removeUndefinedKey(rsbuildDev);
136
137
  rsbuildConfig.html = html;
137
138
  rsbuildConfig.output = output;
139
+ const { sourceBuild, sourceImport } = builderConfig.experiments || {};
138
140
  const rsbuildPlugins = [
141
+ (0, rspack21_js_namespaceObject.pluginRspack21)({
142
+ sourceImport
143
+ }),
139
144
  (0, globalVars_js_namespaceObject.pluginGlobalVars)(globalVars),
140
145
  (0, devtools_js_namespaceObject.pluginDevtool)({
141
146
  sourceMap
@@ -169,16 +174,18 @@ async function parseCommonConfig(builderConfig, options) {
169
174
  rsbuildPlugins.push(pluginTypedCSSModules());
170
175
  }
171
176
  rsbuildPlugins.push((0, runtimeChunk_js_namespaceObject.pluginRuntimeChunk)(builderConfig.output?.disableInlineRuntimeChunk));
172
- const { sourceBuild } = builderConfig.experiments || {};
173
177
  if (sourceBuild) {
174
178
  const { pluginSourceBuild } = await import("@rsbuild/plugin-source-build");
175
179
  rsbuildPlugins.push(pluginSourceBuild(true === sourceBuild ? {} : sourceBuild));
176
180
  }
177
- rsbuildPlugins.push((0, plugin_react_namespaceObject.pluginReact)());
181
+ rsbuildPlugins.push((0, plugin_react_namespaceObject.pluginReact)(options?.disableReactCompiler ? {} : {
182
+ reactCompiler: reactCompiler ?? true
183
+ }));
178
184
  if (!disableSvgr) {
179
185
  const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
180
186
  rsbuildPlugins.push(pluginSvgr({
181
187
  mixedImport: true,
188
+ parallel: true,
182
189
  svgrOptions: {
183
190
  exportType: 'component' === svgDefaultExport ? 'default' : 'named'
184
191
  }
@@ -3,6 +3,15 @@ const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
3
3
  return "u" < typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
4
4
  }();
5
5
  var __webpack_require__ = {};
6
+ (()=>{
7
+ __webpack_require__.n = (module)=>{
8
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
9
+ __webpack_require__.d(getter, {
10
+ a: getter
11
+ });
12
+ return getter;
13
+ };
14
+ })();
6
15
  (()=>{
7
16
  __webpack_require__.d = (exports1, getters, values)=>{
8
17
  var define = (defs, kind)=>{
@@ -33,9 +42,16 @@ __webpack_require__.r(__webpack_exports__);
33
42
  __webpack_require__.d(__webpack_exports__, {
34
43
  withTsgoDefaults: ()=>withTsgoDefaults
35
44
  });
45
+ const external_node_crypto_namespaceObject = require("node:crypto");
46
+ const external_node_fs_namespaceObject = require("node:fs");
47
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
36
48
  const external_node_module_namespaceObject = require("node:module");
49
+ const external_node_path_namespaceObject = require("node:path");
50
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
51
+ const utils_namespaceObject = require("@modern-js/utils");
37
52
  const builderRequire = (0, external_node_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
38
53
  const TSGO_PACKAGE = "@typescript/native-preview/package.json";
54
+ const TSGO_CHECKER_DIR = external_node_path_default().join('.modern-js', 'tsgo');
39
55
  const tryResolve = (request, rootPath)=>{
40
56
  try {
41
57
  return builderRequire.resolve(request, {
@@ -47,6 +63,111 @@ const tryResolve = (request, rootPath)=>{
47
63
  return;
48
64
  }
49
65
  };
66
+ const toPosixPath = (input)=>input.replaceAll(external_node_path_default().sep, '/');
67
+ const asTsConfigPath = (request)=>{
68
+ if (external_node_path_default().extname(request)) return [
69
+ request
70
+ ];
71
+ return [
72
+ request,
73
+ `${request}.json`
74
+ ];
75
+ };
76
+ const resolveExtends = (request, configDirectory)=>{
77
+ const configRequire = (0, external_node_module_namespaceObject.createRequire)(external_node_path_default().join(configDirectory, 'tsconfig.json'));
78
+ for (const candidate of asTsConfigPath(request)){
79
+ if (candidate.startsWith('.') || external_node_path_default().isAbsolute(candidate)) {
80
+ const resolved = external_node_path_default().resolve(configDirectory, candidate);
81
+ if (external_node_fs_default().existsSync(resolved)) return resolved;
82
+ continue;
83
+ }
84
+ try {
85
+ return configRequire.resolve(candidate);
86
+ } catch {}
87
+ }
88
+ };
89
+ const readTsConfig = (configFile, visited = new Set())=>{
90
+ if (visited.has(configFile) || !external_node_fs_default().existsSync(configFile)) return {};
91
+ visited.add(configFile);
92
+ const config = utils_namespaceObject.json5.parse(external_node_fs_default().readFileSync(configFile, 'utf8'));
93
+ const configDirectory = external_node_path_default().dirname(configFile);
94
+ const extendsList = Array.isArray(config.extends) ? config.extends : config.extends ? [
95
+ config.extends
96
+ ] : [];
97
+ const baseConfig = extendsList.reduce((merged, request)=>{
98
+ const resolved = resolveExtends(request, configDirectory);
99
+ if (!resolved) return merged;
100
+ const parentConfig = readTsConfig(resolved, visited);
101
+ return {
102
+ ...merged,
103
+ compilerOptions: {
104
+ ...merged.compilerOptions ?? {},
105
+ ...parentConfig.compilerOptions ?? {}
106
+ }
107
+ };
108
+ }, {});
109
+ return {
110
+ ...baseConfig,
111
+ compilerOptions: {
112
+ ...baseConfig.compilerOptions ?? {},
113
+ ...config.compilerOptions ?? {}
114
+ }
115
+ };
116
+ };
117
+ const toRelativeConfigPath = (fromDirectory, target)=>{
118
+ const relative = toPosixPath(external_node_path_default().relative(fromDirectory, target));
119
+ if (relative.startsWith('.')) return relative;
120
+ return `./${relative}`;
121
+ };
122
+ const writeFileIfChanged = (file, content)=>{
123
+ if (external_node_fs_default().existsSync(file) && external_node_fs_default().readFileSync(file, 'utf8') === content) return;
124
+ external_node_fs_default().writeFileSync(file, content);
125
+ };
126
+ const createTsgoCheckerConfig = (configFile)=>{
127
+ const configDirectory = external_node_path_default().dirname(configFile);
128
+ const checkerConfigDirectory = external_node_path_default().join(configDirectory, TSGO_CHECKER_DIR);
129
+ const hash = (0, external_node_crypto_namespaceObject.createHash)('sha1').update(configFile).digest('hex').slice(0, 10);
130
+ const checkerConfigFile = external_node_path_default().join(checkerConfigDirectory, `tsconfig.${hash}.json`);
131
+ const tsConfig = readTsConfig(configFile);
132
+ const compilerOptions = {
133
+ baseUrl: null
134
+ };
135
+ const moduleResolution = String(tsConfig.compilerOptions?.moduleResolution).toLowerCase();
136
+ if ([
137
+ 'node',
138
+ 'node10'
139
+ ].includes(moduleResolution)) compilerOptions.moduleResolution = null;
140
+ const checkerConfig = {
141
+ extends: toRelativeConfigPath(checkerConfigDirectory, configFile),
142
+ compilerOptions
143
+ };
144
+ external_node_fs_default().mkdirSync(checkerConfigDirectory, {
145
+ recursive: true
146
+ });
147
+ writeFileIfChanged(checkerConfigFile, `${JSON.stringify(checkerConfig, null, 2)}\n`);
148
+ return checkerConfigFile;
149
+ };
150
+ const normalizeTsgoConfig = (config, rootPath)=>{
151
+ const { typescript } = config;
152
+ if (typescript?.tsgo === false) return config;
153
+ const compilerOptions = {
154
+ ...typescript?.configOverwrite?.compilerOptions ?? {},
155
+ baseUrl: null
156
+ };
157
+ if ([
158
+ 'node',
159
+ 'node10'
160
+ ].includes(String(compilerOptions.moduleResolution).toLowerCase())) compilerOptions.moduleResolution = null;
161
+ config.typescript = {
162
+ ...typescript,
163
+ configOverwrite: {
164
+ ...typescript?.configOverwrite ?? {},
165
+ compilerOptions
166
+ }
167
+ };
168
+ if (typescript?.configFile) config.typescript.configFile = createTsgoCheckerConfig(external_node_path_default().resolve(rootPath, typescript.configFile));
169
+ return config;
170
+ };
50
171
  const withTsgoDefaults = (userOptions, rootPath)=>{
51
172
  const tsgoPath = tryResolve(TSGO_PACKAGE, rootPath) ?? builderRequire.resolve(TSGO_PACKAGE);
52
173
  const userChain = userOptions ? Array.isArray(userOptions) ? userOptions : [
@@ -63,7 +184,7 @@ const withTsgoDefaults = (userOptions, rootPath)=>{
63
184
  (config)=>{
64
185
  const { typescript } = config;
65
186
  if (typescript?.tsgo === false && typescript.typescriptPath === tsgoPath) typescript.typescriptPath = tryResolve("typescript", rootPath);
66
- return config;
187
+ return normalizeTsgoConfig(config, rootPath);
67
188
  }
68
189
  ];
69
190
  };
@@ -2,7 +2,9 @@ import path from "path";
2
2
  const ASYNC_STORAGE_PATTERN = /universal[/\\]async_storage/;
3
3
  const SERVER_LOADER_ENTRY_PATTERN = /[/\\](?:server-loader-combined|route-server-loaders)\.js$/;
4
4
  const RENDER_RSC_SOURCE_PATTERN = /render[/\\].*[/\\]server[/\\]rsc/;
5
- const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc\.mjs$/;
5
+ const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc(?:Worker)?\.mjs$/;
6
+ const RENDER_RSC_RUNTIME = '@modern-js/render/rsc';
7
+ const RENDER_RSC_WORKER_RUNTIME = '@modern-js/render/rsc-worker';
6
8
  const RSC_COMMON_LAYER = 'rsc-common';
7
9
  const ENTRY_NAME_VAR = '__MODERN_JS_ENTRY_NAME';
8
10
  const createVirtualModule = (content)=>`data:text/javascript,${encodeURIComponent(content)}`;
@@ -11,6 +13,38 @@ const isAsyncStorageExclude = (exclude)=>{
11
13
  if (exclude instanceof RegExp) return exclude.test('universal/async_storage') || exclude.test('universal\\async_storage');
12
14
  return false;
13
15
  };
16
+ const asRecord = (value)=>{
17
+ if (value && 'object' == typeof value && !Array.isArray(value)) return value;
18
+ };
19
+ const disableReactCompilerInSwcLoaders = (value, seen = new WeakSet())=>{
20
+ if (!value || 'object' != typeof value) return;
21
+ if (seen.has(value)) return;
22
+ seen.add(value);
23
+ if (Array.isArray(value)) {
24
+ for (const item of value)disableReactCompilerInSwcLoaders(item, seen);
25
+ return;
26
+ }
27
+ const record = value;
28
+ if ('builtin:swc-loader' === record.loader) {
29
+ let options = asRecord(record.options);
30
+ if (!options) {
31
+ options = {};
32
+ record.options = options;
33
+ }
34
+ let jsc = asRecord(options.jsc);
35
+ if (!jsc) {
36
+ jsc = {};
37
+ options.jsc = jsc;
38
+ }
39
+ let transform = asRecord(jsc.transform);
40
+ if (!transform) {
41
+ transform = {};
42
+ jsc.transform = transform;
43
+ }
44
+ transform.reactCompiler = false;
45
+ }
46
+ for (const item of Object.values(record))disableReactCompilerInSwcLoaders(item, seen);
47
+ };
14
48
  function pluginRscConfig() {
15
49
  return {
16
50
  name: 'builder:rsc-config',
@@ -26,6 +60,7 @@ function pluginRscConfig() {
26
60
  api.modifyBundlerChain({
27
61
  handler: (chain, { isServer })=>{
28
62
  if (isServer) {
63
+ chain.resolve.alias.set(`${RENDER_RSC_RUNTIME}$`, RENDER_RSC_WORKER_RUNTIME);
29
64
  const routeFilePattern = /[/\\]routes[/\\](?:.*[/\\])?(?:layout|page|\$)\.[tj]sx?$/;
30
65
  const appFilePattern = /[/\\]App\.[tj]sx?$/;
31
66
  const combinedPattern = new RegExp(`(${routeFilePattern.source}|${appFilePattern.source})`);
@@ -64,6 +99,7 @@ function pluginRscConfig() {
64
99
  }
65
100
  if (config.module?.rules) {
66
101
  const rules = config.module.rules;
102
+ disableReactCompilerInSwcLoaders(rules);
67
103
  for (const rule of rules)if (rule.layer === Layers.rsc) {
68
104
  if (rule.exclude) {
69
105
  if (!Array.isArray(rule.exclude)) rule.exclude = [
@@ -0,0 +1,23 @@
1
+ const PERSISTENT_CACHE_MAX_AGE = 604800;
2
+ const PERSISTENT_CACHE_MAX_VERSIONS = 3;
3
+ const pluginRspack21 = ({ sourceImport } = {})=>({
4
+ name: 'modern-js:rspack-2-1-defaults',
5
+ setup (api) {
6
+ api.modifyRspackConfig((config)=>{
7
+ config.module ??= {};
8
+ config.module.parser ??= {};
9
+ config.module.parser.javascript ??= {};
10
+ config.module.parser.javascript.createRequire ??= true;
11
+ if ('object' == typeof config.cache && null !== config.cache && 'persistent' === config.cache.type) {
12
+ config.cache.maxAge ??= PERSISTENT_CACHE_MAX_AGE;
13
+ config.cache.maxVersions ??= PERSISTENT_CACHE_MAX_VERSIONS;
14
+ }
15
+ if (void 0 !== sourceImport) {
16
+ config.experiments ??= {};
17
+ config.experiments.sourceImport = sourceImport;
18
+ }
19
+ return config;
20
+ });
21
+ }
22
+ });
23
+ export { pluginRspack21 };
@@ -8,6 +8,7 @@ import { pluginEmitRouteFile } from "../plugins/emitRouteFile.mjs";
8
8
  import { pluginEnvironmentDefaults } from "../plugins/environmentDefaults.mjs";
9
9
  import { pluginGlobalVars } from "../plugins/globalVars.mjs";
10
10
  import { pluginHtmlMinifierTerser } from "../plugins/htmlMinify.mjs";
11
+ import { pluginRspack21 } from "../plugins/rspack21.mjs";
11
12
  import { pluginRuntimeChunk } from "../plugins/runtimeChunk.mjs";
12
13
  import { transformToRsbuildServerOptions } from "./devServer.mjs";
13
14
  import { withTsgoDefaults } from "./tsgo.mjs";
@@ -26,7 +27,7 @@ function removeUndefinedKey(obj) {
26
27
  }
27
28
  async function parseCommonConfig(builderConfig, options) {
28
29
  const frameworkConfigPath = options?.frameworkConfigPath;
29
- const { plugins: [...plugins] = [], splitChunks, performance: { rsdoctor: rsdoctorConfig, ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
30
+ const { plugins: [...plugins] = [], splitChunks, performance: { rsdoctor: rsdoctorConfig, ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
30
31
  let combinedAlias;
31
32
  if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
32
33
  const rsbuildConfig = {
@@ -102,7 +103,11 @@ async function parseCommonConfig(builderConfig, options) {
102
103
  rsbuildConfig.dev = removeUndefinedKey(rsbuildDev);
103
104
  rsbuildConfig.html = html;
104
105
  rsbuildConfig.output = output;
106
+ const { sourceBuild, sourceImport } = builderConfig.experiments || {};
105
107
  const rsbuildPlugins = [
108
+ pluginRspack21({
109
+ sourceImport
110
+ }),
106
111
  pluginGlobalVars(globalVars),
107
112
  pluginDevtool({
108
113
  sourceMap
@@ -136,16 +141,18 @@ async function parseCommonConfig(builderConfig, options) {
136
141
  rsbuildPlugins.push(pluginTypedCSSModules());
137
142
  }
138
143
  rsbuildPlugins.push(pluginRuntimeChunk(builderConfig.output?.disableInlineRuntimeChunk));
139
- const { sourceBuild } = builderConfig.experiments || {};
140
144
  if (sourceBuild) {
141
145
  const { pluginSourceBuild } = await import("@rsbuild/plugin-source-build");
142
146
  rsbuildPlugins.push(pluginSourceBuild(true === sourceBuild ? {} : sourceBuild));
143
147
  }
144
- rsbuildPlugins.push(pluginReact());
148
+ rsbuildPlugins.push(pluginReact(options?.disableReactCompiler ? {} : {
149
+ reactCompiler: reactCompiler ?? true
150
+ }));
145
151
  if (!disableSvgr) {
146
152
  const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
147
153
  rsbuildPlugins.push(pluginSvgr({
148
154
  mixedImport: true,
155
+ parallel: true,
149
156
  svgrOptions: {
150
157
  exportType: 'component' === svgDefaultExport ? 'default' : 'named'
151
158
  }
@@ -1,6 +1,11 @@
1
+ import { createHash } from "node:crypto";
2
+ import node_fs from "node:fs";
1
3
  import { createRequire } from "node:module";
4
+ import node_path from "node:path";
5
+ import { json5 } from "@modern-js/utils";
2
6
  const builderRequire = createRequire(import.meta.url);
3
7
  const TSGO_PACKAGE = "@typescript/native-preview/package.json";
8
+ const TSGO_CHECKER_DIR = node_path.join('.modern-js', 'tsgo');
4
9
  const tryResolve = (request, rootPath)=>{
5
10
  try {
6
11
  return builderRequire.resolve(request, {
@@ -12,6 +17,111 @@ const tryResolve = (request, rootPath)=>{
12
17
  return;
13
18
  }
14
19
  };
20
+ const toPosixPath = (input)=>input.replaceAll(node_path.sep, '/');
21
+ const asTsConfigPath = (request)=>{
22
+ if (node_path.extname(request)) return [
23
+ request
24
+ ];
25
+ return [
26
+ request,
27
+ `${request}.json`
28
+ ];
29
+ };
30
+ const resolveExtends = (request, configDirectory)=>{
31
+ const configRequire = createRequire(node_path.join(configDirectory, 'tsconfig.json'));
32
+ for (const candidate of asTsConfigPath(request)){
33
+ if (candidate.startsWith('.') || node_path.isAbsolute(candidate)) {
34
+ const resolved = node_path.resolve(configDirectory, candidate);
35
+ if (node_fs.existsSync(resolved)) return resolved;
36
+ continue;
37
+ }
38
+ try {
39
+ return configRequire.resolve(candidate);
40
+ } catch {}
41
+ }
42
+ };
43
+ const readTsConfig = (configFile, visited = new Set())=>{
44
+ if (visited.has(configFile) || !node_fs.existsSync(configFile)) return {};
45
+ visited.add(configFile);
46
+ const config = json5.parse(node_fs.readFileSync(configFile, 'utf8'));
47
+ const configDirectory = node_path.dirname(configFile);
48
+ const extendsList = Array.isArray(config.extends) ? config.extends : config.extends ? [
49
+ config.extends
50
+ ] : [];
51
+ const baseConfig = extendsList.reduce((merged, request)=>{
52
+ const resolved = resolveExtends(request, configDirectory);
53
+ if (!resolved) return merged;
54
+ const parentConfig = readTsConfig(resolved, visited);
55
+ return {
56
+ ...merged,
57
+ compilerOptions: {
58
+ ...merged.compilerOptions ?? {},
59
+ ...parentConfig.compilerOptions ?? {}
60
+ }
61
+ };
62
+ }, {});
63
+ return {
64
+ ...baseConfig,
65
+ compilerOptions: {
66
+ ...baseConfig.compilerOptions ?? {},
67
+ ...config.compilerOptions ?? {}
68
+ }
69
+ };
70
+ };
71
+ const toRelativeConfigPath = (fromDirectory, target)=>{
72
+ const relative = toPosixPath(node_path.relative(fromDirectory, target));
73
+ if (relative.startsWith('.')) return relative;
74
+ return `./${relative}`;
75
+ };
76
+ const writeFileIfChanged = (file, content)=>{
77
+ if (node_fs.existsSync(file) && node_fs.readFileSync(file, 'utf8') === content) return;
78
+ node_fs.writeFileSync(file, content);
79
+ };
80
+ const createTsgoCheckerConfig = (configFile)=>{
81
+ const configDirectory = node_path.dirname(configFile);
82
+ const checkerConfigDirectory = node_path.join(configDirectory, TSGO_CHECKER_DIR);
83
+ const hash = createHash('sha1').update(configFile).digest('hex').slice(0, 10);
84
+ const checkerConfigFile = node_path.join(checkerConfigDirectory, `tsconfig.${hash}.json`);
85
+ const tsConfig = readTsConfig(configFile);
86
+ const compilerOptions = {
87
+ baseUrl: null
88
+ };
89
+ const moduleResolution = String(tsConfig.compilerOptions?.moduleResolution).toLowerCase();
90
+ if ([
91
+ 'node',
92
+ 'node10'
93
+ ].includes(moduleResolution)) compilerOptions.moduleResolution = null;
94
+ const checkerConfig = {
95
+ extends: toRelativeConfigPath(checkerConfigDirectory, configFile),
96
+ compilerOptions
97
+ };
98
+ node_fs.mkdirSync(checkerConfigDirectory, {
99
+ recursive: true
100
+ });
101
+ writeFileIfChanged(checkerConfigFile, `${JSON.stringify(checkerConfig, null, 2)}\n`);
102
+ return checkerConfigFile;
103
+ };
104
+ const normalizeTsgoConfig = (config, rootPath)=>{
105
+ const { typescript } = config;
106
+ if (typescript?.tsgo === false) return config;
107
+ const compilerOptions = {
108
+ ...typescript?.configOverwrite?.compilerOptions ?? {},
109
+ baseUrl: null
110
+ };
111
+ if ([
112
+ 'node',
113
+ 'node10'
114
+ ].includes(String(compilerOptions.moduleResolution).toLowerCase())) compilerOptions.moduleResolution = null;
115
+ config.typescript = {
116
+ ...typescript,
117
+ configOverwrite: {
118
+ ...typescript?.configOverwrite ?? {},
119
+ compilerOptions
120
+ }
121
+ };
122
+ if (typescript?.configFile) config.typescript.configFile = createTsgoCheckerConfig(node_path.resolve(rootPath, typescript.configFile));
123
+ return config;
124
+ };
15
125
  const withTsgoDefaults = (userOptions, rootPath)=>{
16
126
  const tsgoPath = tryResolve(TSGO_PACKAGE, rootPath) ?? builderRequire.resolve(TSGO_PACKAGE);
17
127
  const userChain = userOptions ? Array.isArray(userOptions) ? userOptions : [
@@ -28,7 +138,7 @@ const withTsgoDefaults = (userOptions, rootPath)=>{
28
138
  (config)=>{
29
139
  const { typescript } = config;
30
140
  if (typescript?.tsgo === false && typescript.typescriptPath === tsgoPath) typescript.typescriptPath = tryResolve("typescript", rootPath);
31
- return config;
141
+ return normalizeTsgoConfig(config, rootPath);
32
142
  }
33
143
  ];
34
144
  };
@@ -7,7 +7,9 @@ var rscConfig_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url)
7
7
  const ASYNC_STORAGE_PATTERN = /universal[/\\]async_storage/;
8
8
  const SERVER_LOADER_ENTRY_PATTERN = /[/\\](?:server-loader-combined|route-server-loaders)\.js$/;
9
9
  const RENDER_RSC_SOURCE_PATTERN = /render[/\\].*[/\\]server[/\\]rsc/;
10
- const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc\.mjs$/;
10
+ const RENDER_RSC_RSLIB_ENTRY_PATTERN = /render[/\\]dist[/\\]esm[/\\]rsc(?:Worker)?\.mjs$/;
11
+ const RENDER_RSC_RUNTIME = '@modern-js/render/rsc';
12
+ const RENDER_RSC_WORKER_RUNTIME = '@modern-js/render/rsc-worker';
11
13
  const RSC_COMMON_LAYER = 'rsc-common';
12
14
  const ENTRY_NAME_VAR = '__MODERN_JS_ENTRY_NAME';
13
15
  const createVirtualModule = (content)=>`data:text/javascript,${encodeURIComponent(content)}`;
@@ -16,6 +18,38 @@ const isAsyncStorageExclude = (exclude)=>{
16
18
  if (exclude instanceof RegExp) return exclude.test('universal/async_storage') || exclude.test('universal\\async_storage');
17
19
  return false;
18
20
  };
21
+ const asRecord = (value)=>{
22
+ if (value && 'object' == typeof value && !Array.isArray(value)) return value;
23
+ };
24
+ const disableReactCompilerInSwcLoaders = (value, seen = new WeakSet())=>{
25
+ if (!value || 'object' != typeof value) return;
26
+ if (seen.has(value)) return;
27
+ seen.add(value);
28
+ if (Array.isArray(value)) {
29
+ for (const item of value)disableReactCompilerInSwcLoaders(item, seen);
30
+ return;
31
+ }
32
+ const record = value;
33
+ if ('builtin:swc-loader' === record.loader) {
34
+ let options = asRecord(record.options);
35
+ if (!options) {
36
+ options = {};
37
+ record.options = options;
38
+ }
39
+ let jsc = asRecord(options.jsc);
40
+ if (!jsc) {
41
+ jsc = {};
42
+ options.jsc = jsc;
43
+ }
44
+ let transform = asRecord(jsc.transform);
45
+ if (!transform) {
46
+ transform = {};
47
+ jsc.transform = transform;
48
+ }
49
+ transform.reactCompiler = false;
50
+ }
51
+ for (const item of Object.values(record))disableReactCompilerInSwcLoaders(item, seen);
52
+ };
19
53
  function pluginRscConfig() {
20
54
  return {
21
55
  name: 'builder:rsc-config',
@@ -31,6 +65,7 @@ function pluginRscConfig() {
31
65
  api.modifyBundlerChain({
32
66
  handler: (chain, { isServer })=>{
33
67
  if (isServer) {
68
+ chain.resolve.alias.set(`${RENDER_RSC_RUNTIME}$`, RENDER_RSC_WORKER_RUNTIME);
34
69
  const routeFilePattern = /[/\\]routes[/\\](?:.*[/\\])?(?:layout|page|\$)\.[tj]sx?$/;
35
70
  const appFilePattern = /[/\\]App\.[tj]sx?$/;
36
71
  const combinedPattern = new RegExp(`(${routeFilePattern.source}|${appFilePattern.source})`);
@@ -69,6 +104,7 @@ function pluginRscConfig() {
69
104
  }
70
105
  if (config.module?.rules) {
71
106
  const rules = config.module.rules;
107
+ disableReactCompilerInSwcLoaders(rules);
72
108
  for (const rule of rules)if (rule.layer === Layers.rsc) {
73
109
  if (rule.exclude) {
74
110
  if (!Array.isArray(rule.exclude)) rule.exclude = [
@@ -0,0 +1,24 @@
1
+ import "node:module";
2
+ const PERSISTENT_CACHE_MAX_AGE = 604800;
3
+ const PERSISTENT_CACHE_MAX_VERSIONS = 3;
4
+ const pluginRspack21 = ({ sourceImport } = {})=>({
5
+ name: 'modern-js:rspack-2-1-defaults',
6
+ setup (api) {
7
+ api.modifyRspackConfig((config)=>{
8
+ config.module ??= {};
9
+ config.module.parser ??= {};
10
+ config.module.parser.javascript ??= {};
11
+ config.module.parser.javascript.createRequire ??= true;
12
+ if ('object' == typeof config.cache && null !== config.cache && 'persistent' === config.cache.type) {
13
+ config.cache.maxAge ??= PERSISTENT_CACHE_MAX_AGE;
14
+ config.cache.maxVersions ??= PERSISTENT_CACHE_MAX_VERSIONS;
15
+ }
16
+ if (void 0 !== sourceImport) {
17
+ config.experiments ??= {};
18
+ config.experiments.sourceImport = sourceImport;
19
+ }
20
+ return config;
21
+ });
22
+ }
23
+ });
24
+ export { pluginRspack21 };
@@ -9,6 +9,7 @@ import { pluginEmitRouteFile } from "../plugins/emitRouteFile.mjs";
9
9
  import { pluginEnvironmentDefaults } from "../plugins/environmentDefaults.mjs";
10
10
  import { pluginGlobalVars } from "../plugins/globalVars.mjs";
11
11
  import { pluginHtmlMinifierTerser } from "../plugins/htmlMinify.mjs";
12
+ import { pluginRspack21 } from "../plugins/rspack21.mjs";
12
13
  import { pluginRuntimeChunk } from "../plugins/runtimeChunk.mjs";
13
14
  import { transformToRsbuildServerOptions } from "./devServer.mjs";
14
15
  import { withTsgoDefaults } from "./tsgo.mjs";
@@ -27,7 +28,7 @@ function removeUndefinedKey(obj) {
27
28
  }
28
29
  async function parseCommonConfig(builderConfig, options) {
29
30
  const frameworkConfigPath = options?.frameworkConfigPath;
30
- const { plugins: [...plugins] = [], splitChunks, performance: { rsdoctor: rsdoctorConfig, ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
31
+ const { plugins: [...plugins] = [], splitChunks, performance: { rsdoctor: rsdoctorConfig, ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
31
32
  let combinedAlias;
32
33
  if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
33
34
  const rsbuildConfig = {
@@ -103,7 +104,11 @@ async function parseCommonConfig(builderConfig, options) {
103
104
  rsbuildConfig.dev = removeUndefinedKey(rsbuildDev);
104
105
  rsbuildConfig.html = html;
105
106
  rsbuildConfig.output = output;
107
+ const { sourceBuild, sourceImport } = builderConfig.experiments || {};
106
108
  const rsbuildPlugins = [
109
+ pluginRspack21({
110
+ sourceImport
111
+ }),
107
112
  pluginGlobalVars(globalVars),
108
113
  pluginDevtool({
109
114
  sourceMap
@@ -137,16 +142,18 @@ async function parseCommonConfig(builderConfig, options) {
137
142
  rsbuildPlugins.push(pluginTypedCSSModules());
138
143
  }
139
144
  rsbuildPlugins.push(pluginRuntimeChunk(builderConfig.output?.disableInlineRuntimeChunk));
140
- const { sourceBuild } = builderConfig.experiments || {};
141
145
  if (sourceBuild) {
142
146
  const { pluginSourceBuild } = await import("@rsbuild/plugin-source-build");
143
147
  rsbuildPlugins.push(pluginSourceBuild(true === sourceBuild ? {} : sourceBuild));
144
148
  }
145
- rsbuildPlugins.push(pluginReact());
149
+ rsbuildPlugins.push(pluginReact(options?.disableReactCompiler ? {} : {
150
+ reactCompiler: reactCompiler ?? true
151
+ }));
146
152
  if (!disableSvgr) {
147
153
  const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
148
154
  rsbuildPlugins.push(pluginSvgr({
149
155
  mixedImport: true,
156
+ parallel: true,
150
157
  svgrOptions: {
151
158
  exportType: 'component' === svgDefaultExport ? 'default' : 'named'
152
159
  }
@@ -1,7 +1,12 @@
1
1
  import "node:module";
2
+ import { createHash } from "node:crypto";
3
+ import node_fs from "node:fs";
2
4
  import { createRequire } from "node:module";
5
+ import node_path from "node:path";
6
+ import { json5 } from "@modern-js/utils";
3
7
  const builderRequire = createRequire(import.meta.url);
4
8
  const TSGO_PACKAGE = "@typescript/native-preview/package.json";
9
+ const TSGO_CHECKER_DIR = node_path.join('.modern-js', 'tsgo');
5
10
  const tryResolve = (request, rootPath)=>{
6
11
  try {
7
12
  return builderRequire.resolve(request, {
@@ -13,6 +18,111 @@ const tryResolve = (request, rootPath)=>{
13
18
  return;
14
19
  }
15
20
  };
21
+ const toPosixPath = (input)=>input.replaceAll(node_path.sep, '/');
22
+ const asTsConfigPath = (request)=>{
23
+ if (node_path.extname(request)) return [
24
+ request
25
+ ];
26
+ return [
27
+ request,
28
+ `${request}.json`
29
+ ];
30
+ };
31
+ const resolveExtends = (request, configDirectory)=>{
32
+ const configRequire = createRequire(node_path.join(configDirectory, 'tsconfig.json'));
33
+ for (const candidate of asTsConfigPath(request)){
34
+ if (candidate.startsWith('.') || node_path.isAbsolute(candidate)) {
35
+ const resolved = node_path.resolve(configDirectory, candidate);
36
+ if (node_fs.existsSync(resolved)) return resolved;
37
+ continue;
38
+ }
39
+ try {
40
+ return configRequire.resolve(candidate);
41
+ } catch {}
42
+ }
43
+ };
44
+ const readTsConfig = (configFile, visited = new Set())=>{
45
+ if (visited.has(configFile) || !node_fs.existsSync(configFile)) return {};
46
+ visited.add(configFile);
47
+ const config = json5.parse(node_fs.readFileSync(configFile, 'utf8'));
48
+ const configDirectory = node_path.dirname(configFile);
49
+ const extendsList = Array.isArray(config.extends) ? config.extends : config.extends ? [
50
+ config.extends
51
+ ] : [];
52
+ const baseConfig = extendsList.reduce((merged, request)=>{
53
+ const resolved = resolveExtends(request, configDirectory);
54
+ if (!resolved) return merged;
55
+ const parentConfig = readTsConfig(resolved, visited);
56
+ return {
57
+ ...merged,
58
+ compilerOptions: {
59
+ ...merged.compilerOptions ?? {},
60
+ ...parentConfig.compilerOptions ?? {}
61
+ }
62
+ };
63
+ }, {});
64
+ return {
65
+ ...baseConfig,
66
+ compilerOptions: {
67
+ ...baseConfig.compilerOptions ?? {},
68
+ ...config.compilerOptions ?? {}
69
+ }
70
+ };
71
+ };
72
+ const toRelativeConfigPath = (fromDirectory, target)=>{
73
+ const relative = toPosixPath(node_path.relative(fromDirectory, target));
74
+ if (relative.startsWith('.')) return relative;
75
+ return `./${relative}`;
76
+ };
77
+ const writeFileIfChanged = (file, content)=>{
78
+ if (node_fs.existsSync(file) && node_fs.readFileSync(file, 'utf8') === content) return;
79
+ node_fs.writeFileSync(file, content);
80
+ };
81
+ const createTsgoCheckerConfig = (configFile)=>{
82
+ const configDirectory = node_path.dirname(configFile);
83
+ const checkerConfigDirectory = node_path.join(configDirectory, TSGO_CHECKER_DIR);
84
+ const hash = createHash('sha1').update(configFile).digest('hex').slice(0, 10);
85
+ const checkerConfigFile = node_path.join(checkerConfigDirectory, `tsconfig.${hash}.json`);
86
+ const tsConfig = readTsConfig(configFile);
87
+ const compilerOptions = {
88
+ baseUrl: null
89
+ };
90
+ const moduleResolution = String(tsConfig.compilerOptions?.moduleResolution).toLowerCase();
91
+ if ([
92
+ 'node',
93
+ 'node10'
94
+ ].includes(moduleResolution)) compilerOptions.moduleResolution = null;
95
+ const checkerConfig = {
96
+ extends: toRelativeConfigPath(checkerConfigDirectory, configFile),
97
+ compilerOptions
98
+ };
99
+ node_fs.mkdirSync(checkerConfigDirectory, {
100
+ recursive: true
101
+ });
102
+ writeFileIfChanged(checkerConfigFile, `${JSON.stringify(checkerConfig, null, 2)}\n`);
103
+ return checkerConfigFile;
104
+ };
105
+ const normalizeTsgoConfig = (config, rootPath)=>{
106
+ const { typescript } = config;
107
+ if (typescript?.tsgo === false) return config;
108
+ const compilerOptions = {
109
+ ...typescript?.configOverwrite?.compilerOptions ?? {},
110
+ baseUrl: null
111
+ };
112
+ if ([
113
+ 'node',
114
+ 'node10'
115
+ ].includes(String(compilerOptions.moduleResolution).toLowerCase())) compilerOptions.moduleResolution = null;
116
+ config.typescript = {
117
+ ...typescript,
118
+ configOverwrite: {
119
+ ...typescript?.configOverwrite ?? {},
120
+ compilerOptions
121
+ }
122
+ };
123
+ if (typescript?.configFile) config.typescript.configFile = createTsgoCheckerConfig(node_path.resolve(rootPath, typescript.configFile));
124
+ return config;
125
+ };
16
126
  const withTsgoDefaults = (userOptions, rootPath)=>{
17
127
  const tsgoPath = tryResolve(TSGO_PACKAGE, rootPath) ?? builderRequire.resolve(TSGO_PACKAGE);
18
128
  const userChain = userOptions ? Array.isArray(userOptions) ? userOptions : [
@@ -29,7 +139,7 @@ const withTsgoDefaults = (userOptions, rootPath)=>{
29
139
  (config)=>{
30
140
  const { typescript } = config;
31
141
  if (typescript?.tsgo === false && typescript.typescriptPath === tsgoPath) typescript.typescriptPath = tryResolve("typescript", rootPath);
32
- return config;
142
+ return normalizeTsgoConfig(config, rootPath);
33
143
  }
34
144
  ];
35
145
  };
@@ -0,0 +1,4 @@
1
+ import type { RsbuildPlugin } from '@rsbuild/core';
2
+ export declare const pluginRspack21: ({ sourceImport, }?: {
3
+ sourceImport?: boolean;
4
+ }) => RsbuildPlugin;
@@ -4,6 +4,7 @@ import type { PluginAssetsRetryOptions } from '@rsbuild/plugin-assets-retry';
4
4
  import type { PluginCheckSyntaxOptions } from '@rsbuild/plugin-check-syntax';
5
5
  import type { PluginCssMinimizerOptions } from '@rsbuild/plugin-css-minimizer';
6
6
  import type { PluginLessOptions } from '@rsbuild/plugin-less';
7
+ import type { PluginReactOptions } from '@rsbuild/plugin-react';
7
8
  import type { PluginRemOptions } from '@rsbuild/plugin-rem';
8
9
  import type { PluginSassOptions } from '@rsbuild/plugin-sass';
9
10
  import type { PluginSourceBuildOptions } from '@rsbuild/plugin-source-build';
@@ -32,6 +33,11 @@ export type MetaOptions = {
32
33
  };
33
34
  export type CreateBuilderCommonOptions = {
34
35
  frameworkConfigPath?: string;
36
+ /**
37
+ * Disable Modern's default React Compiler SWC option for consumers whose
38
+ * build pipeline does not support Rspack's `jsc.transform.reactCompiler`.
39
+ */
40
+ disableReactCompiler?: boolean;
35
41
  /** The root path of current project. */
36
42
  cwd: string;
37
43
  rscClientRuntimePath?: string;
@@ -146,6 +152,16 @@ export type BuilderExtraConfig = {
146
152
  * Define global variables. It can replace expressions like `process.env.FOO` in your code after compile.
147
153
  */
148
154
  globalVars?: ChainedGlobalVars;
155
+ /**
156
+ * Enable or configure the Rust-backed React Compiler transform.
157
+ *
158
+ * The transform is enabled by default through Rsbuild's SWC integration.
159
+ * Set this to `false` to disable it.
160
+ *
161
+ * For React 17 or 18, install `react-compiler-runtime` and set the
162
+ * matching target version, for example `{ target: '18' }`.
163
+ */
164
+ reactCompiler?: PluginReactOptions['reactCompiler'];
149
165
  };
150
166
  output?: {
151
167
  /**
@@ -207,6 +223,10 @@ export type BuilderExtraConfig = {
207
223
  * Enable the ability for source code building
208
224
  */
209
225
  sourceBuild?: boolean | Pick<PluginSourceBuildOptions, 'sourceField' | 'resolvePriority'>;
226
+ /**
227
+ * Configure Rspack source phase imports for WebAssembly modules.
228
+ */
229
+ sourceImport?: boolean;
210
230
  };
211
231
  };
212
232
  export type SriOptions = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bleedingdev/modern-js-builder",
3
- "version": "3.4.0-ultramodern.0",
3
+ "version": "3.4.0-ultramodern.10",
4
4
  "description": "A builder for Modern.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "dist"
27
27
  ],
28
28
  "dependencies": {
29
- "@rsbuild/core": "2.0.15",
29
+ "@rsbuild/core": "2.1.0",
30
30
  "@rsbuild/plugin-assets-retry": "2.0.1",
31
31
  "@rsbuild/plugin-check-syntax": "2.0.0",
32
32
  "@rsbuild/plugin-css-minimizer": "2.0.1",
@@ -36,13 +36,13 @@
36
36
  "@rsbuild/plugin-sass": "2.0.0",
37
37
  "@rsbuild/plugin-source-build": "1.0.6",
38
38
  "@rsbuild/plugin-svgr": "2.0.4",
39
- "@rsbuild/plugin-type-check": "1.4.0",
39
+ "@rsbuild/plugin-type-check": "1.5.0",
40
40
  "@rsbuild/plugin-typed-css-modules": "1.2.4",
41
41
  "@rsdoctor/rspack-plugin": "^1.5.16",
42
42
  "@swc/core": "1.15.43",
43
43
  "@swc/helpers": "^0.5.23",
44
44
  "@typescript/native-preview": "7.0.0-dev.20260624.1",
45
- "autoprefixer": "10.5.1",
45
+ "autoprefixer": "10.5.2",
46
46
  "browserslist": "4.28.4",
47
47
  "core-js": "^3.49.0",
48
48
  "cssnano": "8.0.2",
@@ -59,7 +59,7 @@
59
59
  "rsbuild-plugin-rsc": "0.1.1",
60
60
  "rspack-manifest-plugin": "5.2.2",
61
61
  "ts-deepmerge": "8.0.0",
62
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.0"
62
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.10"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@rslib/core": "0.23.0",
@@ -68,7 +68,7 @@
68
68
  "react": "^19.2.7",
69
69
  "terser": "^5.48.0",
70
70
  "typescript": "^6.0.3",
71
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.0",
71
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.10",
72
72
  "@scripts/rstest-config": "2.66.0"
73
73
  },
74
74
  "publishConfig": {