@esmx/rspack 3.0.0-rc.17 → 3.0.0-rc.19
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/LICENSE +1 -1
- package/README.md +42 -21
- package/README.zh-CN.md +50 -0
- package/dist/app.mjs +2 -28
- package/dist/config.mjs +33 -56
- package/dist/html-app.mjs +1 -1
- package/dist/pack.mjs +10 -6
- package/dist/utils/rsbuild.mjs +7 -3
- package/package.json +12 -13
- package/src/app.ts +2 -28
- package/src/config.ts +43 -60
- package/src/html-app.ts +1 -1
- package/src/pack.ts +11 -7
- package/src/utils/rsbuild.ts +8 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,29 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://www.esmnext.com/logo.svg?t=2025" width="120" alt="Esmx Logo" />
|
|
3
|
+
<h1>@esmx/rspack</h1>
|
|
4
|
+
|
|
5
|
+
<div>
|
|
6
|
+
<a href="https://www.npmjs.com/package/@esmx/rspack">
|
|
7
|
+
<img src="https://img.shields.io/npm/v/@esmx/rspack.svg" alt="npm version" />
|
|
8
|
+
</a>
|
|
9
|
+
<a href="https://github.com/esmnext/esmx/actions/workflows/build.yml">
|
|
10
|
+
<img src="https://github.com/esmnext/esmx/actions/workflows/build.yml/badge.svg" alt="Build" />
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://www.esmnext.com/coverage/">
|
|
13
|
+
<img src="https://img.shields.io/badge/coverage-live%20report-brightgreen" alt="Coverage Report" />
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://nodejs.org/">
|
|
16
|
+
<img src="https://img.shields.io/node/v/@esmx/rspack.svg" alt="node version" />
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://bundlephobia.com/package/@esmx/rspack">
|
|
19
|
+
<img src="https://img.shields.io/bundlephobia/minzip/@esmx/rspack" alt="size" />
|
|
20
|
+
</a>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<p>A high-performance Rspack integration for Esmx microfrontend framework, providing module federation and SSR capabilities</p>
|
|
24
|
+
|
|
25
|
+
<p>
|
|
26
|
+
English | <a href="https://github.com/esmnext/esmx/blob/master/packages/rspack/README.zh-CN.md">中文</a>
|
|
27
|
+
</p>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## 🚀 Features
|
|
31
|
+
|
|
32
|
+
- **High-Performance Build** - Ultra-fast building based on Rspack, providing excellent development experience
|
|
33
|
+
- **Application Support** - Complete support for standard applications and HTML applications development and building
|
|
34
|
+
- **Asset Processing** - Smart processing of various assets including JavaScript, CSS, images
|
|
35
|
+
- **SSR Support** - Built-in server-side rendering support for easy isomorphic application building
|
|
36
|
+
- **Developer Experience** - Supports hot reload, intelligent hints, and TypeScript
|
|
37
|
+
|
|
38
|
+
## 📦 Installation
|
|
14
39
|
|
|
15
40
|
```bash
|
|
16
|
-
pnpm add @esmx/rspack -D
|
|
17
|
-
# 或
|
|
18
|
-
yarn add @esmx/rspack -D
|
|
19
|
-
# 或
|
|
20
41
|
npm install @esmx/rspack -D
|
|
21
42
|
```
|
|
22
43
|
|
|
23
|
-
##
|
|
44
|
+
## 📚 Documentation
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
Visit the [official documentation](https://www.esmnext.com/api/app/rspack.html) for detailed usage guides and API reference.
|
|
26
47
|
|
|
27
|
-
##
|
|
48
|
+
## 📄 License
|
|
28
49
|
|
|
29
|
-
MIT
|
|
50
|
+
MIT © [Esmx Team](https://github.com/esmnext/esmx)
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://www.esmnext.com/logo.svg?t=2025" width="120" alt="Esmx Logo" />
|
|
3
|
+
<h1>@esmx/rspack</h1>
|
|
4
|
+
|
|
5
|
+
<div>
|
|
6
|
+
<a href="https://www.npmjs.com/package/@esmx/rspack">
|
|
7
|
+
<img src="https://img.shields.io/npm/v/@esmx/rspack.svg" alt="npm version" />
|
|
8
|
+
</a>
|
|
9
|
+
<a href="https://github.com/esmnext/esmx/actions/workflows/build.yml">
|
|
10
|
+
<img src="https://github.com/esmnext/esmx/actions/workflows/build.yml/badge.svg" alt="Build" />
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://www.esmnext.com/coverage/">
|
|
13
|
+
<img src="https://img.shields.io/badge/coverage-live%20report-brightgreen" alt="Coverage Report" />
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://nodejs.org/">
|
|
16
|
+
<img src="https://img.shields.io/node/v/@esmx/rspack.svg" alt="node version" />
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://bundlephobia.com/package/@esmx/rspack">
|
|
19
|
+
<img src="https://img.shields.io/bundlephobia/minzip/@esmx/rspack" alt="size" />
|
|
20
|
+
</a>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<p>为 Esmx 微前端框架提供的高性能 Rspack 集成,具备模块联邦和 SSR 能力</p>
|
|
24
|
+
|
|
25
|
+
<p>
|
|
26
|
+
<a href="https://github.com/esmnext/esmx/blob/master/packages/rspack/README.md">English</a> | 中文
|
|
27
|
+
</p>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## 🚀 特性
|
|
31
|
+
|
|
32
|
+
- **高性能构建** - 基于 Rspack 的极速构建,为应用提供卓越的开发体验
|
|
33
|
+
- **应用支持** - 完整支持标准应用和 HTML 应用的开发与构建
|
|
34
|
+
- **资源处理** - 智能处理各类资源,支持 JavaScript、CSS、图片等
|
|
35
|
+
- **SSR 支持** - 内置服务端渲染支持,轻松构建同构应用
|
|
36
|
+
- **开发体验** - 支持热更新、智能提示和 TypeScript
|
|
37
|
+
|
|
38
|
+
## 📦 安装
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @esmx/rspack -D
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 📚 文档
|
|
45
|
+
|
|
46
|
+
访问[官方文档](https://www.esmnext.com/api/app/rspack.html)获取详细的使用指南和 API 参考。
|
|
47
|
+
|
|
48
|
+
## 📄 许可证
|
|
49
|
+
|
|
50
|
+
MIT © [Esmx Team](https://github.com/esmnext/esmx)
|
package/dist/app.mjs
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
1
|
import { pathToFileURL } from "node:url";
|
|
3
|
-
import { styleText } from "node:util";
|
|
4
2
|
import {
|
|
5
|
-
PathType,
|
|
6
3
|
RenderContext,
|
|
7
4
|
createApp,
|
|
8
5
|
mergeMiddlewares
|
|
@@ -81,29 +78,6 @@ function rewriteRender(esmx) {
|
|
|
81
78
|
}
|
|
82
79
|
function rewriteBuild(esmx, options = {}) {
|
|
83
80
|
return async () => {
|
|
84
|
-
for (const item of esmx.moduleConfig.exports) {
|
|
85
|
-
if (item.type === PathType.root) {
|
|
86
|
-
const text = fs.readFileSync(
|
|
87
|
-
esmx.resolvePath("./", item.exportPath),
|
|
88
|
-
"utf-8"
|
|
89
|
-
);
|
|
90
|
-
if (/\bexport\s+\*\s+from\b/.test(text)) {
|
|
91
|
-
console.log(
|
|
92
|
-
styleText(
|
|
93
|
-
"red",
|
|
94
|
-
`The export * syntax is used in the file '${item.exportPath}', which will cause the packaging to fail.`
|
|
95
|
-
)
|
|
96
|
-
);
|
|
97
|
-
console.log(
|
|
98
|
-
styleText(
|
|
99
|
-
"red",
|
|
100
|
-
`Please use specific export syntax, such as export { a, b } from './a';`
|
|
101
|
-
)
|
|
102
|
-
);
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
81
|
const ok = await createRsBuild([
|
|
108
82
|
generateBuildConfig(esmx, options, "client"),
|
|
109
83
|
generateBuildConfig(esmx, options, "server"),
|
|
@@ -113,10 +87,10 @@ function rewriteBuild(esmx, options = {}) {
|
|
|
113
87
|
return false;
|
|
114
88
|
}
|
|
115
89
|
esmx.writeSync(
|
|
116
|
-
esmx.resolvePath("dist/index.
|
|
90
|
+
esmx.resolvePath("dist/index.mjs"),
|
|
117
91
|
`
|
|
118
92
|
async function start() {
|
|
119
|
-
const options = await import('./node/src/entry.node.
|
|
93
|
+
const options = await import('./node/src/entry.node.mjs').then(
|
|
120
94
|
(mod) => mod.default
|
|
121
95
|
);
|
|
122
96
|
const { Esmx } = await import('@esmx/core');
|
package/dist/config.mjs
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
} from "@rspack/core";
|
|
5
5
|
import nodeExternals from "webpack-node-externals";
|
|
6
6
|
export function createRspackConfig(esmx, buildTarget, options) {
|
|
7
|
-
const isWebApp = buildTarget === "client" || buildTarget === "server";
|
|
8
7
|
const isHot = buildTarget === "client" && !esmx.isProd;
|
|
9
8
|
return {
|
|
10
9
|
/**
|
|
@@ -12,42 +11,23 @@ export function createRspackConfig(esmx, buildTarget, options) {
|
|
|
12
11
|
*/
|
|
13
12
|
context: esmx.root,
|
|
14
13
|
entry: (() => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
);
|
|
22
|
-
break;
|
|
23
|
-
case "server":
|
|
24
|
-
importPaths.push(esmx.resolvePath("src/entry.server.ts"));
|
|
25
|
-
break;
|
|
26
|
-
case "node":
|
|
27
|
-
importPaths.push(esmx.resolvePath("src/entry.node.ts"));
|
|
28
|
-
break;
|
|
14
|
+
if (buildTarget === "node") {
|
|
15
|
+
return {
|
|
16
|
+
[`./src/entry.${buildTarget}`]: {
|
|
17
|
+
import: esmx.resolvePath("src/entry.node.ts")
|
|
18
|
+
}
|
|
19
|
+
};
|
|
29
20
|
}
|
|
30
|
-
return {
|
|
31
|
-
[`./src/entry.${buildTarget}`]: {
|
|
32
|
-
import: importPaths
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
21
|
})(),
|
|
36
22
|
output: {
|
|
37
23
|
clean: esmx.isProd,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
chunkLoading: esmx.isProd ? "import" : void 0,
|
|
41
|
-
chunkFilename: esmx.isProd ? "chunks/[name].[contenthash:8].final.js" : "chunks/[name].js",
|
|
42
|
-
library: {
|
|
43
|
-
type: esmx.isProd ? "modern-module" : "module"
|
|
44
|
-
},
|
|
45
|
-
filename: buildTarget !== "node" && esmx.isProd ? "[name].[contenthash:8].final.js" : "[name].js",
|
|
24
|
+
chunkFilename: esmx.isProd ? "[name].[contenthash:8].final.mjs" : "[name].mjs",
|
|
25
|
+
filename: buildTarget !== "node" && esmx.isProd ? "[name].[contenthash:8].final.mjs" : "[name].mjs",
|
|
46
26
|
cssFilename: esmx.isProd ? "[name].[contenthash:8].final.css" : "[name].css",
|
|
47
|
-
cssChunkFilename: esmx.isProd ? "
|
|
27
|
+
cssChunkFilename: esmx.isProd ? "[name].[contenthash:8].final.css" : "[name].css",
|
|
48
28
|
publicPath: buildTarget === "client" ? "auto" : `${esmx.basePathPlaceholder}${esmx.basePath}`,
|
|
49
29
|
uniqueName: esmx.varName,
|
|
50
|
-
hotUpdateChunkFilename: "__hot__/[id].[fullhash].hot-update.
|
|
30
|
+
hotUpdateChunkFilename: "__hot__/[id].[fullhash].hot-update.mjs",
|
|
51
31
|
hotUpdateMainFilename: "__hot__/[runtime].[fullhash].hot-update.json",
|
|
52
32
|
path: (() => {
|
|
53
33
|
switch (buildTarget) {
|
|
@@ -58,33 +38,21 @@ export function createRspackConfig(esmx, buildTarget, options) {
|
|
|
58
38
|
case "node":
|
|
59
39
|
return esmx.resolvePath("dist/node");
|
|
60
40
|
}
|
|
61
|
-
})()
|
|
62
|
-
environment: {
|
|
63
|
-
dynamicImport: true,
|
|
64
|
-
dynamicImportInWorker: true,
|
|
65
|
-
module: true,
|
|
66
|
-
nodePrefixForCoreModules: true
|
|
67
|
-
}
|
|
41
|
+
})()
|
|
68
42
|
},
|
|
69
|
-
// 默认插件,不可修改
|
|
70
43
|
plugins: (() => {
|
|
71
44
|
return [
|
|
72
|
-
// 进度条插件
|
|
73
45
|
new rspack.ProgressPlugin({
|
|
74
46
|
prefix: buildTarget
|
|
75
47
|
}),
|
|
76
|
-
|
|
77
|
-
isWebApp ? moduleLinkPlugin(esmx.moduleConfig) : false,
|
|
78
|
-
// 热更新插件
|
|
48
|
+
createModuleLinkPlugin(esmx, buildTarget),
|
|
79
49
|
isHot ? new rspack.HotModuleReplacementPlugin() : false
|
|
80
50
|
];
|
|
81
51
|
})(),
|
|
82
52
|
module: {
|
|
83
53
|
parser: {
|
|
84
54
|
javascript: {
|
|
85
|
-
url: buildTarget === "client" ? true : "relative"
|
|
86
|
-
importMeta: false,
|
|
87
|
-
strictExportPresence: true
|
|
55
|
+
url: buildTarget === "client" ? true : "relative"
|
|
88
56
|
}
|
|
89
57
|
},
|
|
90
58
|
generator: {
|
|
@@ -104,8 +72,6 @@ export function createRspackConfig(esmx, buildTarget, options) {
|
|
|
104
72
|
},
|
|
105
73
|
optimization: {
|
|
106
74
|
minimize: options.minimize ?? esmx.isProd,
|
|
107
|
-
avoidEntryIife: esmx.isProd,
|
|
108
|
-
concatenateModules: esmx.isProd,
|
|
109
75
|
emitOnErrors: true,
|
|
110
76
|
splitChunks: {
|
|
111
77
|
chunks: "async"
|
|
@@ -128,18 +94,29 @@ export function createRspackConfig(esmx, buildTarget, options) {
|
|
|
128
94
|
}
|
|
129
95
|
return [];
|
|
130
96
|
})(),
|
|
131
|
-
experiments: {
|
|
132
|
-
outputModule: true,
|
|
133
|
-
parallelCodeSplitting: true,
|
|
134
|
-
rspackFuture: {
|
|
135
|
-
bundlerInfo: { force: false }
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
97
|
target: buildTarget === "client" ? "web" : "node22.6",
|
|
139
98
|
mode: esmx.isProd ? "production" : "development",
|
|
140
99
|
cache: !esmx.isProd
|
|
141
100
|
};
|
|
142
101
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
102
|
+
function createModuleLinkPlugin(esmx, buildTarget) {
|
|
103
|
+
if (buildTarget === "node") {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const exports = {};
|
|
107
|
+
for (const [name, item] of Object.entries(esmx.moduleConfig.exports)) {
|
|
108
|
+
if (item.inputTarget[buildTarget]) {
|
|
109
|
+
exports[name] = {
|
|
110
|
+
rewrite: item.rewrite,
|
|
111
|
+
file: item.inputTarget[buildTarget]
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return moduleLinkPlugin({
|
|
116
|
+
name: esmx.name,
|
|
117
|
+
ext: "mjs",
|
|
118
|
+
injectChunkName: buildTarget === "server",
|
|
119
|
+
imports: esmx.moduleConfig.imports,
|
|
120
|
+
exports
|
|
121
|
+
});
|
|
145
122
|
}
|
package/dist/html-app.mjs
CHANGED
|
@@ -10,7 +10,7 @@ export async function createRspackHtmlApp(esmx, options) {
|
|
|
10
10
|
options = {
|
|
11
11
|
...options,
|
|
12
12
|
target: {
|
|
13
|
-
web: ["chrome>=
|
|
13
|
+
web: ["chrome>=63", "firefox>=67", "safari>=11.1"],
|
|
14
14
|
node: ["node>=22.6"],
|
|
15
15
|
...options?.target
|
|
16
16
|
},
|
package/dist/pack.mjs
CHANGED
|
@@ -30,8 +30,12 @@ export async function pack(esmx) {
|
|
|
30
30
|
}
|
|
31
31
|
async function buildPackageJson(esmx) {
|
|
32
32
|
const [clientJson, serverJson, curJson] = await Promise.all([
|
|
33
|
-
esmx.readJson(
|
|
34
|
-
|
|
33
|
+
esmx.readJson(
|
|
34
|
+
esmx.resolvePath("dist/client/manifest.json")
|
|
35
|
+
),
|
|
36
|
+
esmx.readJson(
|
|
37
|
+
esmx.resolvePath("dist/server/manifest.json")
|
|
38
|
+
),
|
|
35
39
|
esmx.readJson(esmx.resolvePath("package.json"))
|
|
36
40
|
]);
|
|
37
41
|
const exports = {
|
|
@@ -47,13 +51,13 @@ async function buildPackageJson(esmx) {
|
|
|
47
51
|
const exportName = `./${name}`;
|
|
48
52
|
if (client && server) {
|
|
49
53
|
exports[exportName] = {
|
|
50
|
-
default: `./server/${server}`,
|
|
51
|
-
browser: `./client/${client}`
|
|
54
|
+
default: `./server/${server.file}`,
|
|
55
|
+
browser: `./client/${client.file}`
|
|
52
56
|
};
|
|
53
57
|
} else if (client) {
|
|
54
|
-
exports[exportName] = `./client/${client}`;
|
|
58
|
+
exports[exportName] = `./client/${client.file}`;
|
|
55
59
|
} else if (server) {
|
|
56
|
-
exports[exportName] = `./server/${server}`;
|
|
60
|
+
exports[exportName] = `./server/${server.file}`;
|
|
57
61
|
}
|
|
58
62
|
});
|
|
59
63
|
const buildJson = {
|
package/dist/utils/rsbuild.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { styleText } from "node:util";
|
|
2
2
|
import { rspack } from "@rspack/core";
|
|
3
|
+
function showError(message) {
|
|
4
|
+
console.error(styleText("red", message));
|
|
5
|
+
}
|
|
3
6
|
export function createRsBuild(options) {
|
|
4
7
|
const multiCompiler = rspack(options);
|
|
5
8
|
return {
|
|
@@ -10,17 +13,18 @@ export function createRsBuild(options) {
|
|
|
10
13
|
return new Promise((resolve) => {
|
|
11
14
|
multiCompiler.run((err, stats) => {
|
|
12
15
|
if (err) {
|
|
16
|
+
showError(err.message);
|
|
13
17
|
return resolve(false);
|
|
14
18
|
}
|
|
15
19
|
if (stats?.hasErrors()) {
|
|
16
20
|
stats.toJson({ errors: true })?.errors?.forEach((err2) => {
|
|
17
|
-
|
|
21
|
+
showError(err2.message);
|
|
18
22
|
});
|
|
19
23
|
return resolve(false);
|
|
20
24
|
}
|
|
21
25
|
multiCompiler.close((err2) => {
|
|
22
26
|
if (err2) {
|
|
23
|
-
|
|
27
|
+
showError(err2.message);
|
|
24
28
|
return resolve(false);
|
|
25
29
|
}
|
|
26
30
|
process.nextTick(() => {
|
|
@@ -33,7 +37,7 @@ export function createRsBuild(options) {
|
|
|
33
37
|
watch() {
|
|
34
38
|
const watching = multiCompiler.watch({}, (err, stats) => {
|
|
35
39
|
if (err) {
|
|
36
|
-
console.
|
|
40
|
+
console.log(styleText("red", err.message));
|
|
37
41
|
return;
|
|
38
42
|
}
|
|
39
43
|
if (stats?.hasErrors()) {
|
package/package.json
CHANGED
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@esmx/import": "3.0.0-rc.
|
|
67
|
-
"@esmx/rspack-module-link-plugin": "3.0.0-rc.
|
|
66
|
+
"@esmx/import": "3.0.0-rc.19",
|
|
67
|
+
"@esmx/rspack-module-link-plugin": "3.0.0-rc.19",
|
|
68
68
|
"@npmcli/arborist": "^9.0.1",
|
|
69
|
-
"@rspack/core": "1.
|
|
69
|
+
"@rspack/core": "1.4.0-rc.0",
|
|
70
70
|
"css-loader": "^7.1.2",
|
|
71
71
|
"less-loader": "^12.2.0",
|
|
72
72
|
"node-polyfill-webpack-plugin": "^4.1.0",
|
|
@@ -79,21 +79,20 @@
|
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@biomejs/biome": "1.9.4",
|
|
82
|
-
"@esmx/core": "3.0.0-rc.
|
|
83
|
-
"@esmx/lint": "3.0.0-rc.
|
|
84
|
-
"@
|
|
85
|
-
"@types/node": "22.13.10",
|
|
82
|
+
"@esmx/core": "3.0.0-rc.19",
|
|
83
|
+
"@esmx/lint": "3.0.0-rc.19",
|
|
84
|
+
"@types/node": "22.15.18",
|
|
86
85
|
"@types/npmcli__arborist": "^5.6.11",
|
|
87
86
|
"@types/pacote": "^11.1.8",
|
|
88
87
|
"@types/webpack-hot-middleware": "^2.25.9",
|
|
89
88
|
"@types/webpack-node-externals": "^3.0.4",
|
|
90
|
-
"@vitest/coverage-v8": "3.
|
|
91
|
-
"stylelint": "16.
|
|
89
|
+
"@vitest/coverage-v8": "3.1.3",
|
|
90
|
+
"stylelint": "16.19.1",
|
|
92
91
|
"typescript": "5.8.2",
|
|
93
|
-
"unbuild": "
|
|
94
|
-
"vitest": "3.
|
|
92
|
+
"unbuild": "3.5.0",
|
|
93
|
+
"vitest": "3.1.3"
|
|
95
94
|
},
|
|
96
|
-
"version": "3.0.0-rc.
|
|
95
|
+
"version": "3.0.0-rc.19",
|
|
97
96
|
"type": "module",
|
|
98
97
|
"private": false,
|
|
99
98
|
"exports": {
|
|
@@ -112,5 +111,5 @@
|
|
|
112
111
|
"template",
|
|
113
112
|
"public"
|
|
114
113
|
],
|
|
115
|
-
"gitHead": "
|
|
114
|
+
"gitHead": "83a9cfac4a91b2b54ac576e120bb4541f4cce9d6"
|
|
116
115
|
}
|
package/src/app.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
1
|
import { pathToFileURL } from 'node:url';
|
|
3
|
-
import { styleText } from 'node:util';
|
|
4
2
|
import {
|
|
5
3
|
type App,
|
|
6
4
|
type Esmx,
|
|
7
5
|
type Middleware,
|
|
8
|
-
PathType,
|
|
9
6
|
RenderContext,
|
|
10
7
|
type RenderContextOptions,
|
|
11
8
|
type ServerRenderHandle,
|
|
@@ -270,29 +267,6 @@ function rewriteRender(esmx: Esmx) {
|
|
|
270
267
|
|
|
271
268
|
function rewriteBuild(esmx: Esmx, options: RspackAppOptions = {}) {
|
|
272
269
|
return async (): Promise<boolean> => {
|
|
273
|
-
for (const item of esmx.moduleConfig.exports) {
|
|
274
|
-
if (item.type === PathType.root) {
|
|
275
|
-
const text = fs.readFileSync(
|
|
276
|
-
esmx.resolvePath('./', item.exportPath),
|
|
277
|
-
'utf-8'
|
|
278
|
-
);
|
|
279
|
-
if (/\bexport\s+\*\s+from\b/.test(text)) {
|
|
280
|
-
console.log(
|
|
281
|
-
styleText(
|
|
282
|
-
'red',
|
|
283
|
-
`The export * syntax is used in the file '${item.exportPath}', which will cause the packaging to fail.`
|
|
284
|
-
)
|
|
285
|
-
);
|
|
286
|
-
console.log(
|
|
287
|
-
styleText(
|
|
288
|
-
'red',
|
|
289
|
-
`Please use specific export syntax, such as export { a, b } from './a';`
|
|
290
|
-
)
|
|
291
|
-
);
|
|
292
|
-
return false;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
270
|
const ok = await createRsBuild([
|
|
297
271
|
generateBuildConfig(esmx, options, 'client'),
|
|
298
272
|
generateBuildConfig(esmx, options, 'server'),
|
|
@@ -302,10 +276,10 @@ function rewriteBuild(esmx: Esmx, options: RspackAppOptions = {}) {
|
|
|
302
276
|
return false;
|
|
303
277
|
}
|
|
304
278
|
esmx.writeSync(
|
|
305
|
-
esmx.resolvePath('dist/index.
|
|
279
|
+
esmx.resolvePath('dist/index.mjs'),
|
|
306
280
|
`
|
|
307
281
|
async function start() {
|
|
308
|
-
const options = await import('./node/src/entry.node.
|
|
282
|
+
const options = await import('./node/src/entry.node.mjs').then(
|
|
309
283
|
(mod) => mod.default
|
|
310
284
|
);
|
|
311
285
|
const { Esmx } = await import('@esmx/core');
|
package/src/config.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Esmx } from '@esmx/core';
|
|
|
2
2
|
import { moduleLinkPlugin } from '@esmx/rspack-module-link-plugin';
|
|
3
3
|
import {
|
|
4
4
|
type ExternalItem,
|
|
5
|
+
type Plugin,
|
|
5
6
|
type Plugins,
|
|
6
7
|
type RspackOptions,
|
|
7
8
|
rspack
|
|
@@ -18,7 +19,6 @@ export function createRspackConfig(
|
|
|
18
19
|
buildTarget: BuildTarget,
|
|
19
20
|
options: RspackAppOptions
|
|
20
21
|
): RspackOptions {
|
|
21
|
-
const isWebApp = buildTarget === 'client' || buildTarget === 'server';
|
|
22
22
|
const isHot = buildTarget === 'client' && !esmx.isProd;
|
|
23
23
|
return {
|
|
24
24
|
/**
|
|
@@ -26,55 +26,35 @@ export function createRspackConfig(
|
|
|
26
26
|
*/
|
|
27
27
|
context: esmx.root,
|
|
28
28
|
entry: (() => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`${resolve('webpack-hot-middleware/client')}?path=${esmx.basePath}hot-middleware&timeout=5000&overlay=false`
|
|
36
|
-
);
|
|
37
|
-
break;
|
|
38
|
-
case 'server':
|
|
39
|
-
importPaths.push(esmx.resolvePath('src/entry.server.ts'));
|
|
40
|
-
break;
|
|
41
|
-
case 'node':
|
|
42
|
-
importPaths.push(esmx.resolvePath('src/entry.node.ts'));
|
|
43
|
-
break;
|
|
29
|
+
if (buildTarget === 'node') {
|
|
30
|
+
return {
|
|
31
|
+
[`./src/entry.${buildTarget}`]: {
|
|
32
|
+
import: esmx.resolvePath('src/entry.node.ts')
|
|
33
|
+
}
|
|
34
|
+
};
|
|
44
35
|
}
|
|
45
|
-
return {
|
|
46
|
-
[`./src/entry.${buildTarget}`]: {
|
|
47
|
-
import: importPaths
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
36
|
})(),
|
|
51
37
|
output: {
|
|
52
38
|
clean: esmx.isProd,
|
|
53
|
-
module: true,
|
|
54
|
-
chunkFormat: esmx.isProd ? 'module' : undefined,
|
|
55
|
-
chunkLoading: esmx.isProd ? 'import' : undefined,
|
|
56
39
|
chunkFilename: esmx.isProd
|
|
57
|
-
? '
|
|
58
|
-
: '
|
|
59
|
-
library: {
|
|
60
|
-
type: esmx.isProd ? 'modern-module' : 'module'
|
|
61
|
-
},
|
|
40
|
+
? '[name].[contenthash:8].final.mjs'
|
|
41
|
+
: '[name].mjs',
|
|
62
42
|
filename:
|
|
63
43
|
buildTarget !== 'node' && esmx.isProd
|
|
64
|
-
? '[name].[contenthash:8].final.
|
|
65
|
-
: '[name].
|
|
44
|
+
? '[name].[contenthash:8].final.mjs'
|
|
45
|
+
: '[name].mjs',
|
|
66
46
|
cssFilename: esmx.isProd
|
|
67
47
|
? '[name].[contenthash:8].final.css'
|
|
68
48
|
: '[name].css',
|
|
69
49
|
cssChunkFilename: esmx.isProd
|
|
70
|
-
? '
|
|
71
|
-
: '
|
|
50
|
+
? '[name].[contenthash:8].final.css'
|
|
51
|
+
: '[name].css',
|
|
72
52
|
publicPath:
|
|
73
53
|
buildTarget === 'client'
|
|
74
54
|
? 'auto'
|
|
75
55
|
: `${esmx.basePathPlaceholder}${esmx.basePath}`,
|
|
76
56
|
uniqueName: esmx.varName,
|
|
77
|
-
hotUpdateChunkFilename: '__hot__/[id].[fullhash].hot-update.
|
|
57
|
+
hotUpdateChunkFilename: '__hot__/[id].[fullhash].hot-update.mjs',
|
|
78
58
|
hotUpdateMainFilename:
|
|
79
59
|
'__hot__/[runtime].[fullhash].hot-update.json',
|
|
80
60
|
path: ((): string => {
|
|
@@ -86,33 +66,21 @@ export function createRspackConfig(
|
|
|
86
66
|
case 'node':
|
|
87
67
|
return esmx.resolvePath('dist/node');
|
|
88
68
|
}
|
|
89
|
-
})()
|
|
90
|
-
environment: {
|
|
91
|
-
dynamicImport: true,
|
|
92
|
-
dynamicImportInWorker: true,
|
|
93
|
-
module: true,
|
|
94
|
-
nodePrefixForCoreModules: true
|
|
95
|
-
}
|
|
69
|
+
})()
|
|
96
70
|
},
|
|
97
|
-
// 默认插件,不可修改
|
|
98
71
|
plugins: ((): Plugins => {
|
|
99
72
|
return [
|
|
100
|
-
// 进度条插件
|
|
101
73
|
new rspack.ProgressPlugin({
|
|
102
74
|
prefix: buildTarget
|
|
103
75
|
}),
|
|
104
|
-
|
|
105
|
-
isWebApp ? moduleLinkPlugin(esmx.moduleConfig) : false,
|
|
106
|
-
// 热更新插件
|
|
76
|
+
createModuleLinkPlugin(esmx, buildTarget),
|
|
107
77
|
isHot ? new rspack.HotModuleReplacementPlugin() : false
|
|
108
78
|
];
|
|
109
79
|
})(),
|
|
110
80
|
module: {
|
|
111
81
|
parser: {
|
|
112
82
|
javascript: {
|
|
113
|
-
url: buildTarget === 'client' ? true : 'relative'
|
|
114
|
-
importMeta: false,
|
|
115
|
-
strictExportPresence: true
|
|
83
|
+
url: buildTarget === 'client' ? true : 'relative'
|
|
116
84
|
}
|
|
117
85
|
},
|
|
118
86
|
generator: {
|
|
@@ -132,8 +100,6 @@ export function createRspackConfig(
|
|
|
132
100
|
},
|
|
133
101
|
optimization: {
|
|
134
102
|
minimize: options.minimize ?? esmx.isProd,
|
|
135
|
-
avoidEntryIife: esmx.isProd,
|
|
136
|
-
concatenateModules: esmx.isProd,
|
|
137
103
|
emitOnErrors: true,
|
|
138
104
|
splitChunks: {
|
|
139
105
|
chunks: 'async'
|
|
@@ -156,19 +122,36 @@ export function createRspackConfig(
|
|
|
156
122
|
}
|
|
157
123
|
return [];
|
|
158
124
|
})(),
|
|
159
|
-
experiments: {
|
|
160
|
-
outputModule: true,
|
|
161
|
-
parallelCodeSplitting: true,
|
|
162
|
-
rspackFuture: {
|
|
163
|
-
bundlerInfo: { force: false }
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
125
|
target: buildTarget === 'client' ? 'web' : 'node22.6',
|
|
167
126
|
mode: esmx.isProd ? 'production' : 'development',
|
|
168
127
|
cache: !esmx.isProd
|
|
169
128
|
};
|
|
170
129
|
}
|
|
171
130
|
|
|
172
|
-
function
|
|
173
|
-
|
|
131
|
+
function createModuleLinkPlugin(esmx: Esmx, buildTarget: BuildTarget): Plugin {
|
|
132
|
+
if (buildTarget === 'node') {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const exports: Record<
|
|
136
|
+
string,
|
|
137
|
+
{
|
|
138
|
+
rewrite: boolean;
|
|
139
|
+
file: string;
|
|
140
|
+
}
|
|
141
|
+
> = {};
|
|
142
|
+
for (const [name, item] of Object.entries(esmx.moduleConfig.exports)) {
|
|
143
|
+
if (item.inputTarget[buildTarget]) {
|
|
144
|
+
exports[name] = {
|
|
145
|
+
rewrite: item.rewrite,
|
|
146
|
+
file: item.inputTarget[buildTarget]
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return moduleLinkPlugin({
|
|
151
|
+
name: esmx.name,
|
|
152
|
+
ext: 'mjs',
|
|
153
|
+
injectChunkName: buildTarget === 'server',
|
|
154
|
+
imports: esmx.moduleConfig.imports,
|
|
155
|
+
exports
|
|
156
|
+
});
|
|
174
157
|
}
|
package/src/html-app.ts
CHANGED
|
@@ -326,7 +326,7 @@ export async function createRspackHtmlApp(
|
|
|
326
326
|
options = {
|
|
327
327
|
...options,
|
|
328
328
|
target: {
|
|
329
|
-
web: ['chrome>=
|
|
329
|
+
web: ['chrome>=63', 'firefox>=67', 'safari>=11.1'],
|
|
330
330
|
node: ['node>=22.6'],
|
|
331
331
|
...options?.target
|
|
332
332
|
},
|
package/src/pack.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
-
import type { Esmx } from '@esmx/core';
|
|
2
|
+
import type { Esmx, ManifestJson } from '@esmx/core';
|
|
3
3
|
import Arborist from '@npmcli/arborist';
|
|
4
4
|
import pacote from 'pacote';
|
|
5
5
|
|
|
@@ -38,8 +38,12 @@ export async function pack(esmx: Esmx): Promise<boolean> {
|
|
|
38
38
|
|
|
39
39
|
async function buildPackageJson(esmx: Esmx): Promise<Record<string, any>> {
|
|
40
40
|
const [clientJson, serverJson, curJson] = await Promise.all([
|
|
41
|
-
esmx.readJson(
|
|
42
|
-
|
|
41
|
+
esmx.readJson<ManifestJson>(
|
|
42
|
+
esmx.resolvePath('dist/client/manifest.json')
|
|
43
|
+
),
|
|
44
|
+
esmx.readJson<ManifestJson>(
|
|
45
|
+
esmx.resolvePath('dist/server/manifest.json')
|
|
46
|
+
),
|
|
43
47
|
esmx.readJson(esmx.resolvePath('package.json'))
|
|
44
48
|
]);
|
|
45
49
|
const exports: Record<string, any> = {
|
|
@@ -55,13 +59,13 @@ async function buildPackageJson(esmx: Esmx): Promise<Record<string, any>> {
|
|
|
55
59
|
const exportName = `./${name}`;
|
|
56
60
|
if (client && server) {
|
|
57
61
|
exports[exportName] = {
|
|
58
|
-
default: `./server/${server}`,
|
|
59
|
-
browser: `./client/${client}`
|
|
62
|
+
default: `./server/${server.file}`,
|
|
63
|
+
browser: `./client/${client.file}`
|
|
60
64
|
};
|
|
61
65
|
} else if (client) {
|
|
62
|
-
exports[exportName] = `./client/${client}`;
|
|
66
|
+
exports[exportName] = `./client/${client.file}`;
|
|
63
67
|
} else if (server) {
|
|
64
|
-
exports[exportName] = `./server/${server}`;
|
|
68
|
+
exports[exportName] = `./server/${server.file}`;
|
|
65
69
|
}
|
|
66
70
|
});
|
|
67
71
|
|
package/src/utils/rsbuild.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { type Compiler, type RspackOptions, rspack } from '@rspack/core';
|
|
3
3
|
|
|
4
|
+
function showError(message: string) {
|
|
5
|
+
console.error(styleText('red', message));
|
|
6
|
+
}
|
|
7
|
+
|
|
4
8
|
export function createRsBuild(options: RspackOptions[]) {
|
|
5
9
|
const multiCompiler = rspack(options);
|
|
6
10
|
return {
|
|
@@ -11,19 +15,20 @@ export function createRsBuild(options: RspackOptions[]) {
|
|
|
11
15
|
return new Promise<boolean>((resolve) => {
|
|
12
16
|
multiCompiler.run((err, stats) => {
|
|
13
17
|
if (err) {
|
|
18
|
+
showError(err.message);
|
|
14
19
|
return resolve(false);
|
|
15
20
|
}
|
|
16
21
|
if (stats?.hasErrors()) {
|
|
17
22
|
stats
|
|
18
23
|
.toJson({ errors: true })
|
|
19
24
|
?.errors?.forEach((err) => {
|
|
20
|
-
|
|
25
|
+
showError(err.message);
|
|
21
26
|
});
|
|
22
27
|
return resolve(false);
|
|
23
28
|
}
|
|
24
29
|
multiCompiler.close((err) => {
|
|
25
30
|
if (err) {
|
|
26
|
-
|
|
31
|
+
showError(err.message);
|
|
27
32
|
return resolve(false);
|
|
28
33
|
}
|
|
29
34
|
process.nextTick(() => {
|
|
@@ -36,7 +41,7 @@ export function createRsBuild(options: RspackOptions[]) {
|
|
|
36
41
|
watch() {
|
|
37
42
|
const watching = multiCompiler.watch({}, (err, stats) => {
|
|
38
43
|
if (err) {
|
|
39
|
-
console.
|
|
44
|
+
console.log(styleText('red', err.message));
|
|
40
45
|
return;
|
|
41
46
|
}
|
|
42
47
|
if (stats?.hasErrors()) {
|