@bleedingdev/modern-js-builder 3.4.0-ultramodern.1 → 3.4.0-ultramodern.3
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/dist/cjs/plugins/rscConfig.js +37 -1
- package/dist/cjs/plugins/rspack21.js +61 -0
- package/dist/cjs/shared/parseCommonConfig.js +10 -3
- package/dist/cjs/shared/tsgo.js +122 -1
- package/dist/esm/plugins/rscConfig.mjs +37 -1
- package/dist/esm/plugins/rspack21.mjs +23 -0
- package/dist/esm/shared/parseCommonConfig.mjs +10 -3
- package/dist/esm/shared/tsgo.mjs +111 -1
- package/dist/esm-node/plugins/rscConfig.mjs +37 -1
- package/dist/esm-node/plugins/rspack21.mjs +24 -0
- package/dist/esm-node/shared/parseCommonConfig.mjs +10 -3
- package/dist/esm-node/shared/tsgo.mjs +111 -1
- package/dist/types/plugins/rspack21.d.ts +4 -0
- package/dist/types/types.d.ts +20 -0
- package/package.json +6 -6
|
@@ -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
|
|
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
|
}
|
package/dist/cjs/shared/tsgo.js
CHANGED
|
@@ -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
|
|
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
|
}
|
package/dist/esm/shared/tsgo.mjs
CHANGED
|
@@ -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
|
|
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
|
};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "3.4.0-ultramodern.3",
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
62
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.3"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@rslib/core": "0.23.0",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"terser": "^5.48.0",
|
|
70
70
|
"typescript": "^6.0.3",
|
|
71
71
|
"@scripts/rstest-config": "2.66.0",
|
|
72
|
-
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.
|
|
72
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.3"
|
|
73
73
|
},
|
|
74
74
|
"publishConfig": {
|
|
75
75
|
"access": "public",
|