@esmx/rspack 3.0.0-rc.11 → 3.0.0-rc.111
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 +48 -20
- package/README.zh-CN.md +57 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.mjs +4 -4
- package/dist/module-link/config.d.ts +5 -0
- package/dist/module-link/config.mjs +100 -0
- package/dist/module-link/config1.d.ts +3 -0
- package/dist/module-link/config1.mjs +16 -0
- package/dist/module-link/config2.d.ts +3 -0
- package/dist/module-link/config2.mjs +17 -0
- package/dist/module-link/index.d.ts +4 -0
- package/dist/module-link/index.mjs +8 -0
- package/dist/module-link/manifest-plugin.d.ts +14 -0
- package/dist/module-link/manifest-plugin.mjs +141 -0
- package/dist/module-link/parse.d.ts +2 -0
- package/dist/module-link/parse.mjs +24 -0
- package/dist/module-link/types.d.ts +25 -0
- package/dist/rspack/app.d.ts +183 -0
- package/dist/{app.mjs → rspack/app.mjs} +18 -46
- package/dist/rspack/build-target.d.ts +7 -0
- package/dist/rspack/build-target.mjs +0 -0
- package/dist/{config.d.ts → rspack/chain-config.d.ts} +3 -4
- package/dist/rspack/chain-config.mjs +113 -0
- package/dist/rspack/index.d.ts +3 -0
- package/dist/rspack/index.mjs +4 -0
- package/dist/rspack/loader.d.ts +9 -0
- package/dist/{loader.mjs → rspack/loader.mjs} +2 -22
- package/dist/rspack/pack.d.ts +9 -0
- package/dist/{pack.mjs → rspack/pack.mjs} +33 -25
- package/dist/rspack/pack.test.d.ts +1 -0
- package/dist/rspack/pack.test.mjs +180 -0
- package/dist/rspack/utils/rsbuild.d.ts +6 -0
- package/dist/{utils → rspack/utils}/rsbuild.mjs +7 -37
- package/dist/rspack-html/index.d.ts +168 -0
- package/dist/rspack-html/index.mjs +160 -0
- package/dist/rspack-html/target-setting.d.ts +17 -0
- package/dist/rspack-html/target-setting.mjs +31 -0
- package/dist/rspack-html/target-setting.test.d.ts +1 -0
- package/dist/rspack-html/target-setting.test.mjs +105 -0
- package/package.json +23 -21
- package/src/index.ts +7 -6
- package/src/module-link/config.ts +157 -0
- package/src/module-link/config1.ts +24 -0
- package/src/module-link/config2.ts +28 -0
- package/src/module-link/index.ts +19 -0
- package/src/module-link/manifest-plugin.ts +179 -0
- package/src/module-link/parse.ts +31 -0
- package/src/module-link/types.ts +31 -0
- package/src/{app.ts → rspack/app.ts} +104 -107
- package/src/rspack/build-target.ts +7 -0
- package/src/rspack/chain-config.ts +165 -0
- package/src/rspack/index.ts +8 -0
- package/src/{loader.ts → rspack/loader.ts} +3 -22
- package/src/rspack/pack.test.ts +215 -0
- package/src/rspack/pack.ts +101 -0
- package/src/{utils → rspack/utils}/rsbuild.ts +11 -40
- package/src/rspack-html/index.ts +495 -0
- package/src/rspack-html/target-setting.test.ts +123 -0
- package/src/rspack-html/target-setting.ts +52 -0
- package/dist/app.d.ts +0 -160
- package/dist/build-target.d.ts +0 -8
- package/dist/config.mjs +0 -142
- package/dist/html-app.d.ts +0 -299
- package/dist/html-app.mjs +0 -214
- package/dist/loader.d.ts +0 -30
- package/dist/pack.d.ts +0 -2
- package/dist/utils/rsbuild.d.ts +0 -12
- package/src/build-target.ts +0 -8
- package/src/config.ts +0 -171
- package/src/html-app.ts +0 -560
- package/src/pack.ts +0 -79
- /package/dist/{build-target.mjs → module-link/types.mjs} +0 -0
- /package/dist/{utils → rspack/utils}/index.d.ts +0 -0
- /package/dist/{utils → rspack/utils}/index.mjs +0 -0
- /package/src/{utils → rspack/utils}/index.ts +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { contentHash, generateExports } from "./pack.mjs";
|
|
3
|
+
describe("generateExports", () => {
|
|
4
|
+
it("should generate exports with both client and server files", () => {
|
|
5
|
+
const clientExports = {
|
|
6
|
+
"src/entry.client": {
|
|
7
|
+
file: "src/entry.client.95f6085b.final.mjs",
|
|
8
|
+
name: "src/entry.client",
|
|
9
|
+
pkg: true,
|
|
10
|
+
identifier: "ssr-vue2-remote/src/entry.client"
|
|
11
|
+
},
|
|
12
|
+
"src/components/index": {
|
|
13
|
+
file: "src/components/index.a73d6772.final.mjs",
|
|
14
|
+
name: "src/components/index",
|
|
15
|
+
pkg: true,
|
|
16
|
+
identifier: "ssr-vue2-remote/src/components/index"
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const serverExports = {
|
|
20
|
+
"src/entry.server": {
|
|
21
|
+
file: "src/entry.server.b85ed2ff.final.mjs",
|
|
22
|
+
name: "src/entry.server",
|
|
23
|
+
pkg: true,
|
|
24
|
+
identifier: "ssr-vue2-remote/src/entry.server"
|
|
25
|
+
},
|
|
26
|
+
"src/components/index": {
|
|
27
|
+
file: "src/components/index.12b57db5.final.mjs",
|
|
28
|
+
name: "src/components/index",
|
|
29
|
+
pkg: true,
|
|
30
|
+
identifier: "ssr-vue2-remote/src/components/index"
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const result = generateExports({
|
|
34
|
+
client: clientExports,
|
|
35
|
+
server: serverExports
|
|
36
|
+
});
|
|
37
|
+
expect(result).toEqual({
|
|
38
|
+
"./src/entry.client": "./client/src/entry.client.95f6085b.final.mjs",
|
|
39
|
+
"./src/entry.server": "./server/src/entry.server.b85ed2ff.final.mjs",
|
|
40
|
+
"./src/components/index": {
|
|
41
|
+
default: "./server/src/components/index.12b57db5.final.mjs",
|
|
42
|
+
browser: "./client/src/components/index.a73d6772.final.mjs"
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it("should merge with existing exports", () => {
|
|
47
|
+
const clientExports = {
|
|
48
|
+
index: {
|
|
49
|
+
file: "index.js",
|
|
50
|
+
name: "index",
|
|
51
|
+
pkg: true,
|
|
52
|
+
identifier: "index"
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const serverExports = {
|
|
56
|
+
index: {
|
|
57
|
+
file: "index.js",
|
|
58
|
+
name: "index",
|
|
59
|
+
pkg: true,
|
|
60
|
+
identifier: "index"
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const existingExports = {
|
|
64
|
+
"./custom": "./custom.js"
|
|
65
|
+
};
|
|
66
|
+
const result = generateExports({
|
|
67
|
+
client: clientExports,
|
|
68
|
+
server: serverExports,
|
|
69
|
+
base: existingExports
|
|
70
|
+
});
|
|
71
|
+
expect(result).toEqual({
|
|
72
|
+
"./custom": "./custom.js",
|
|
73
|
+
".": {
|
|
74
|
+
default: "./server/index.js",
|
|
75
|
+
browser: "./client/index.js"
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it("should handle empty exports", () => {
|
|
80
|
+
const clientExports = {};
|
|
81
|
+
const serverExports = {};
|
|
82
|
+
const result = generateExports({
|
|
83
|
+
client: clientExports,
|
|
84
|
+
server: serverExports
|
|
85
|
+
});
|
|
86
|
+
expect(result).toEqual({});
|
|
87
|
+
});
|
|
88
|
+
it("should handle only client exports", () => {
|
|
89
|
+
const clientExports = {
|
|
90
|
+
utils: {
|
|
91
|
+
file: "utils.js",
|
|
92
|
+
name: "utils",
|
|
93
|
+
pkg: true,
|
|
94
|
+
identifier: "utils"
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const serverExports = {};
|
|
98
|
+
const result = generateExports({
|
|
99
|
+
client: clientExports,
|
|
100
|
+
server: serverExports
|
|
101
|
+
});
|
|
102
|
+
expect(result).toEqual({
|
|
103
|
+
"./utils": "./client/utils.js"
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
it("should handle only server exports", () => {
|
|
107
|
+
const clientExports = {};
|
|
108
|
+
const serverExports = {
|
|
109
|
+
api: {
|
|
110
|
+
file: "api.js",
|
|
111
|
+
name: "api",
|
|
112
|
+
pkg: true,
|
|
113
|
+
identifier: "api"
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const result = generateExports({
|
|
117
|
+
client: clientExports,
|
|
118
|
+
server: serverExports
|
|
119
|
+
});
|
|
120
|
+
expect(result).toEqual({
|
|
121
|
+
"./api": "./server/api.js"
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
it("should handle index export correctly", () => {
|
|
125
|
+
const clientExports = {
|
|
126
|
+
index: {
|
|
127
|
+
file: "index.js",
|
|
128
|
+
name: "index",
|
|
129
|
+
pkg: true,
|
|
130
|
+
identifier: "index"
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const serverExports = {
|
|
134
|
+
index: {
|
|
135
|
+
file: "index.js",
|
|
136
|
+
name: "index",
|
|
137
|
+
pkg: true,
|
|
138
|
+
identifier: "index"
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const result = generateExports({
|
|
142
|
+
client: clientExports,
|
|
143
|
+
server: serverExports
|
|
144
|
+
});
|
|
145
|
+
expect(result).toEqual({
|
|
146
|
+
".": {
|
|
147
|
+
default: "./server/index.js",
|
|
148
|
+
browser: "./client/index.js"
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
describe("contentHash", () => {
|
|
154
|
+
it("should generate SHA256 hash for buffer", () => {
|
|
155
|
+
const buffer = Buffer.from("test content");
|
|
156
|
+
const result = contentHash(buffer);
|
|
157
|
+
expect(result).toMatch(/^sha256-[a-f0-9]{64}$/);
|
|
158
|
+
expect(result).toBe(
|
|
159
|
+
"sha256-6ae8a75555209fd6c44157c0aed8016e763ff435a19cf186f76863140143ff72"
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
it("should use custom algorithm when provided", () => {
|
|
163
|
+
const buffer = Buffer.from("test content");
|
|
164
|
+
const result = contentHash(buffer, "md5");
|
|
165
|
+
expect(result).toMatch(/^md5-[a-f0-9]{32}$/);
|
|
166
|
+
expect(result).toBe("md5-9473fdd0d880a43c21b7778d34872157");
|
|
167
|
+
});
|
|
168
|
+
it("should handle empty buffer", () => {
|
|
169
|
+
const buffer = Buffer.from("");
|
|
170
|
+
const result = contentHash(buffer);
|
|
171
|
+
expect(result).toBe(
|
|
172
|
+
"sha256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
it("should handle binary data", () => {
|
|
176
|
+
const buffer = Buffer.from([0, 1, 2, 3, 255]);
|
|
177
|
+
const result = contentHash(buffer);
|
|
178
|
+
expect(result).toMatch(/^sha256-[a-f0-9]{64}$/);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
@@ -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()) {
|
|
@@ -61,37 +65,3 @@ export function createRsBuild(options) {
|
|
|
61
65
|
}
|
|
62
66
|
};
|
|
63
67
|
}
|
|
64
|
-
export class RsBuild {
|
|
65
|
-
compiler;
|
|
66
|
-
constructor(options) {
|
|
67
|
-
this.compiler = rspack(options);
|
|
68
|
-
}
|
|
69
|
-
async build() {
|
|
70
|
-
return new Promise((resolve) => {
|
|
71
|
-
this.compiler.run((err, stats) => {
|
|
72
|
-
if (err) {
|
|
73
|
-
return resolve(false);
|
|
74
|
-
}
|
|
75
|
-
if (stats?.hasErrors()) {
|
|
76
|
-
stats.toJson({ errors: true })?.errors?.forEach((err2) => {
|
|
77
|
-
console.error(err2);
|
|
78
|
-
});
|
|
79
|
-
return resolve(false);
|
|
80
|
-
}
|
|
81
|
-
this.compiler.close((err2) => {
|
|
82
|
-
if (err2) {
|
|
83
|
-
console.error(err2);
|
|
84
|
-
return resolve(false);
|
|
85
|
-
}
|
|
86
|
-
process.nextTick(() => {
|
|
87
|
-
resolve(true);
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
watch() {
|
|
94
|
-
const watching = this.compiler.watch({}, () => {
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { Esmx } from '@esmx/core';
|
|
2
|
+
import { type SwcLoaderOptions } from '@rspack/core';
|
|
3
|
+
import { type BuildTarget, RSPACK_LOADER, type RspackAppOptions } from '../rspack';
|
|
4
|
+
import type { TargetSetting } from './target-setting';
|
|
5
|
+
export type { TargetSetting };
|
|
6
|
+
export interface RspackHtmlAppOptions extends RspackAppOptions {
|
|
7
|
+
/**
|
|
8
|
+
* CSS output mode configuration
|
|
9
|
+
*
|
|
10
|
+
* @default Automatically selected based on environment:
|
|
11
|
+
* - Production: 'css', outputs CSS to separate files for better caching and parallel loading
|
|
12
|
+
* - Development: 'js', bundles CSS into JS to support hot module replacement (HMR) for instant style updates
|
|
13
|
+
*
|
|
14
|
+
* - 'css': Output CSS to separate CSS files
|
|
15
|
+
* - 'js': Bundle CSS into JS files and dynamically inject styles at runtime
|
|
16
|
+
* - false: Disable default CSS processing configuration, requires manual loader rule configuration
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* // Use environment default configuration
|
|
21
|
+
* css: undefined
|
|
22
|
+
*
|
|
23
|
+
* // Force output to separate CSS files
|
|
24
|
+
* css: 'css'
|
|
25
|
+
*
|
|
26
|
+
* // Force bundle into JS
|
|
27
|
+
* css: 'js'
|
|
28
|
+
*
|
|
29
|
+
* // Custom CSS processing
|
|
30
|
+
* css: false
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
css?: 'css' | 'js' | false;
|
|
34
|
+
/**
|
|
35
|
+
* Custom loader configuration
|
|
36
|
+
*
|
|
37
|
+
* Allows replacing default loader implementations, useful for switching to framework-specific loaders
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* // Use Vue's style-loader
|
|
42
|
+
* loaders: {
|
|
43
|
+
* styleLoader: 'vue-style-loader'
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
loaders?: Partial<Record<keyof typeof RSPACK_LOADER, string>>;
|
|
48
|
+
/**
|
|
49
|
+
* Configure style injection method. For complete options, see:
|
|
50
|
+
* https://github.com/webpack-contrib/style-loader
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* styleLoader: {
|
|
55
|
+
* injectType: 'singletonStyleTag',
|
|
56
|
+
* attributes: { id: 'app-styles' }
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
styleLoader?: Record<string, any>;
|
|
61
|
+
/**
|
|
62
|
+
* Configure CSS modules, URL resolution, etc. For complete options, see:
|
|
63
|
+
* https://github.com/webpack-contrib/css-loader
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* cssLoader: {
|
|
68
|
+
* modules: true,
|
|
69
|
+
* url: false
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
cssLoader?: Record<string, any>;
|
|
74
|
+
/**
|
|
75
|
+
* Configure Less compilation options. For complete options, see:
|
|
76
|
+
* https://github.com/webpack-contrib/less-loader
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* lessLoader: {
|
|
81
|
+
* lessOptions: {
|
|
82
|
+
* javascriptEnabled: true,
|
|
83
|
+
* modifyVars: { '@primary-color': '#1DA57A' }
|
|
84
|
+
* }
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
lessLoader?: Record<string, any>;
|
|
89
|
+
/**
|
|
90
|
+
* Automatically inject global style resources. For complete options, see:
|
|
91
|
+
* https://github.com/yenshih/style-resources-loader
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* styleResourcesLoader: {
|
|
96
|
+
* patterns: [
|
|
97
|
+
* './src/styles/variables.less',
|
|
98
|
+
* './src/styles/mixins.less'
|
|
99
|
+
* ]
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
styleResourcesLoader?: Record<string, any>;
|
|
104
|
+
/**
|
|
105
|
+
* Configure TypeScript/JavaScript compilation options. For complete options, see:
|
|
106
|
+
* https://rspack.dev/guide/features/builtin-swc-loader
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* swcLoader: {
|
|
111
|
+
* jsc: {
|
|
112
|
+
* parser: {
|
|
113
|
+
* syntax: 'typescript',
|
|
114
|
+
* decorators: true
|
|
115
|
+
* },
|
|
116
|
+
* transform: {
|
|
117
|
+
* legacyDecorator: true
|
|
118
|
+
* }
|
|
119
|
+
* }
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
swcLoader?: SwcLoaderOptions;
|
|
124
|
+
/**
|
|
125
|
+
* Define compile-time global constants, supports setting different values for different build targets
|
|
126
|
+
* For complete documentation, see: https://rspack.dev/plugins/webpack/define-plugin
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* // Unified value
|
|
131
|
+
* definePlugin: {
|
|
132
|
+
* 'process.env.APP_ENV': JSON.stringify('production')
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* // Values for different build targets
|
|
136
|
+
* definePlugin: {
|
|
137
|
+
* 'process.env.IS_SERVER': {
|
|
138
|
+
* server: 'true',
|
|
139
|
+
* client: 'false'
|
|
140
|
+
* }
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
definePlugin?: Record<string, string | Partial<Record<BuildTarget, string>>>;
|
|
145
|
+
/**
|
|
146
|
+
* Set the target runtime environment for the code, affecting code compilation downgrading and polyfill injection
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* // Global compatible mode
|
|
151
|
+
* target: 'compatible'
|
|
152
|
+
*
|
|
153
|
+
* // Global modern mode
|
|
154
|
+
* target: 'modern'
|
|
155
|
+
*
|
|
156
|
+
* // Global custom targets
|
|
157
|
+
* target: ['chrome>=89', 'edge>=89', 'firefox>=108', 'safari>=16.4', 'node>=24']
|
|
158
|
+
*
|
|
159
|
+
* // Per-build-target configuration
|
|
160
|
+
* target: {
|
|
161
|
+
* client: 'modern',
|
|
162
|
+
* server: ['node>=24']
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
target?: TargetSetting;
|
|
167
|
+
}
|
|
168
|
+
export declare function createRspackHtmlApp(esmx: Esmx, options?: RspackHtmlAppOptions): Promise<import("@esmx/core").App>;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import {
|
|
2
|
+
rspack
|
|
3
|
+
} from "@rspack/core";
|
|
4
|
+
import NodePolyfillPlugin from "node-polyfill-webpack-plugin";
|
|
5
|
+
import {
|
|
6
|
+
createRspackApp,
|
|
7
|
+
RSPACK_LOADER
|
|
8
|
+
} from "../rspack/index.mjs";
|
|
9
|
+
import { getTargetSetting } from "./target-setting.mjs";
|
|
10
|
+
export async function createRspackHtmlApp(esmx, options) {
|
|
11
|
+
options = {
|
|
12
|
+
...options,
|
|
13
|
+
css: options?.css ? options.css : esmx.isProd ? "css" : "js"
|
|
14
|
+
};
|
|
15
|
+
return createRspackApp(esmx, {
|
|
16
|
+
...options,
|
|
17
|
+
chain(context) {
|
|
18
|
+
const { chain, buildTarget, esmx: esmx2 } = context;
|
|
19
|
+
chain.stats("errors-warnings");
|
|
20
|
+
chain.devtool(false);
|
|
21
|
+
chain.cache(false);
|
|
22
|
+
configureAssetRules(chain, esmx2);
|
|
23
|
+
chain.module.rule("json").test(/\.json$/i).type("json");
|
|
24
|
+
configureWorkerRule(chain, esmx2, options);
|
|
25
|
+
configureTypeScriptRule(chain, buildTarget, options);
|
|
26
|
+
configureOptimization(chain, options);
|
|
27
|
+
chain.plugin("node-polyfill").use(NodePolyfillPlugin);
|
|
28
|
+
configureDefinePlugin(chain, buildTarget, options);
|
|
29
|
+
chain.resolve.extensions.clear().add("...").add(".ts");
|
|
30
|
+
configureCssRules(chain, esmx2, options);
|
|
31
|
+
options?.chain?.(context);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function configureAssetRules(chain, esmx) {
|
|
36
|
+
chain.module.rule("images").test(
|
|
37
|
+
/\.(png|jpg|jpeg|gif|svg|bmp|webp|ico|apng|avif|tif|tiff|jfif|pjpeg|pjp|cur)$/i
|
|
38
|
+
).type("asset/resource").set("generator", {
|
|
39
|
+
filename: filename(esmx, "images")
|
|
40
|
+
});
|
|
41
|
+
chain.module.rule("media").test(/\.(mp4|webm|ogg|mov)$/i).type("asset/resource").set("generator", {
|
|
42
|
+
filename: filename(esmx, "media")
|
|
43
|
+
});
|
|
44
|
+
chain.module.rule("audio").test(/\.(mp3|wav|flac|aac|m4a|opus)$/i).type("asset/resource").set("generator", {
|
|
45
|
+
filename: filename(esmx, "audio")
|
|
46
|
+
});
|
|
47
|
+
chain.module.rule("fonts").test(/\.(woff|woff2|eot|ttf|otf|ttc)(\?.*)?$/i).type("asset/resource").set("generator", {
|
|
48
|
+
filename: filename(esmx, "fonts")
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function configureWorkerRule(chain, esmx, options) {
|
|
52
|
+
chain.module.rule("worker").test(/\.worker\.(c|m)?(t|j)s$/i).use("worker-loader").loader(
|
|
53
|
+
options.loaders?.workerRspackLoader ?? RSPACK_LOADER.workerRspackLoader
|
|
54
|
+
).options({
|
|
55
|
+
esModule: false,
|
|
56
|
+
filename: `${esmx.name}/workers/[name].[contenthash]${esmx.isProd ? ".final" : ""}.js`
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function configureTypeScriptRule(chain, buildTarget, options) {
|
|
60
|
+
const targets = getTargetSetting(options?.target, buildTarget);
|
|
61
|
+
chain.module.rule("typescript").test(/\.(ts|mts)$/i).use("swc-loader").loader(
|
|
62
|
+
options.loaders?.builtinSwcLoader ?? RSPACK_LOADER.builtinSwcLoader
|
|
63
|
+
).options({
|
|
64
|
+
env: {
|
|
65
|
+
targets,
|
|
66
|
+
...options?.swcLoader?.env
|
|
67
|
+
},
|
|
68
|
+
jsc: {
|
|
69
|
+
parser: {
|
|
70
|
+
syntax: "typescript",
|
|
71
|
+
...options?.swcLoader?.jsc?.parser
|
|
72
|
+
},
|
|
73
|
+
...options?.swcLoader?.jsc
|
|
74
|
+
},
|
|
75
|
+
...options?.swcLoader
|
|
76
|
+
}).end().type("javascript/auto");
|
|
77
|
+
}
|
|
78
|
+
function configureOptimization(chain, options) {
|
|
79
|
+
chain.optimization.minimizer("swc-js-minimizer").use(rspack.SwcJsMinimizerRspackPlugin, [
|
|
80
|
+
{
|
|
81
|
+
minimizerOptions: {
|
|
82
|
+
format: {
|
|
83
|
+
comments: false
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
]);
|
|
88
|
+
chain.optimization.minimizer("lightningcss-minimizer").use(rspack.LightningCssMinimizerRspackPlugin, [
|
|
89
|
+
{
|
|
90
|
+
minimizerOptions: {
|
|
91
|
+
targets: getTargetSetting(options?.target, "client"),
|
|
92
|
+
errorRecovery: false
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
]);
|
|
96
|
+
}
|
|
97
|
+
function configureDefinePlugin(chain, buildTarget, options) {
|
|
98
|
+
if (options.definePlugin) {
|
|
99
|
+
const defineOptions = {};
|
|
100
|
+
Object.entries(options.definePlugin).forEach(([name, value]) => {
|
|
101
|
+
const targetValue = typeof value === "string" ? value : value[buildTarget];
|
|
102
|
+
if (typeof targetValue === "string" && name !== targetValue) {
|
|
103
|
+
defineOptions[name] = targetValue;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
if (Object.keys(defineOptions).length) {
|
|
107
|
+
chain.plugin("define").use(rspack.DefinePlugin, [defineOptions]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function configureCssRules(chain, esmx, options) {
|
|
112
|
+
if (options.css === false) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (options.css === "js") {
|
|
116
|
+
configureCssInJS(chain, esmx, options);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
configureCssExtract(chain, options);
|
|
120
|
+
}
|
|
121
|
+
function configureCssInJS(chain, esmx, options) {
|
|
122
|
+
chain.module.rule("css").test(/\.css$/).use("style-loader").loader(options.loaders?.styleLoader ?? RSPACK_LOADER.styleLoader).options(options.styleLoader ?? {}).end().use("css-loader").loader(options.loaders?.cssLoader ?? RSPACK_LOADER.cssLoader).options(options.cssLoader ?? {}).end().use("lightning-css-loader").loader(
|
|
123
|
+
options.loaders?.lightningcssLoader ?? RSPACK_LOADER.lightningcssLoader
|
|
124
|
+
).options({
|
|
125
|
+
targets: getTargetSetting(options?.target, "client"),
|
|
126
|
+
minify: esmx.isProd
|
|
127
|
+
}).end().type("javascript/auto");
|
|
128
|
+
const lessRule = chain.module.rule("less").test(/\.less$/).use("style-loader").loader(options.loaders?.styleLoader ?? RSPACK_LOADER.styleLoader).options(options.styleLoader ?? {}).end().use("css-loader").loader(options.loaders?.cssLoader ?? RSPACK_LOADER.cssLoader).options(options.cssLoader ?? {}).end().use("lightning-css-loader").loader(
|
|
129
|
+
options.loaders?.lightningcssLoader ?? RSPACK_LOADER.lightningcssLoader
|
|
130
|
+
).options({
|
|
131
|
+
targets: getTargetSetting(options?.target, "client"),
|
|
132
|
+
minify: esmx.isProd
|
|
133
|
+
}).end().use("less-loader").loader(options.loaders?.lessLoader ?? RSPACK_LOADER.lessLoader).options(options.lessLoader ?? {}).end();
|
|
134
|
+
if (options.styleResourcesLoader) {
|
|
135
|
+
lessRule.use("style-resources-loader").loader(
|
|
136
|
+
options.loaders?.styleResourcesLoader ?? RSPACK_LOADER.styleResourcesLoader
|
|
137
|
+
).options(options.styleResourcesLoader);
|
|
138
|
+
}
|
|
139
|
+
lessRule.type("javascript/auto");
|
|
140
|
+
}
|
|
141
|
+
function configureCssExtract(chain, options) {
|
|
142
|
+
chain.set("experiments", {
|
|
143
|
+
...chain.get("experiments") ?? {},
|
|
144
|
+
css: true
|
|
145
|
+
});
|
|
146
|
+
const experiments = chain.get("experiments");
|
|
147
|
+
if (!experiments || !experiments.css) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const lessRule = chain.module.rule("less").test(/\.less$/).use("less-loader").loader(options.loaders?.lessLoader ?? RSPACK_LOADER.lessLoader).options(options.lessLoader ?? {}).end();
|
|
151
|
+
if (options.styleResourcesLoader) {
|
|
152
|
+
lessRule.use("style-resources-loader").loader(
|
|
153
|
+
options.loaders?.styleResourcesLoader ?? RSPACK_LOADER.styleResourcesLoader
|
|
154
|
+
).options(options.styleResourcesLoader);
|
|
155
|
+
}
|
|
156
|
+
lessRule.type("css");
|
|
157
|
+
}
|
|
158
|
+
function filename(esmx, name, ext = "[ext]") {
|
|
159
|
+
return esmx.isProd ? `${name}/[name].[contenthash:8].final${ext}` : `${name}/[path][name]${ext}`;
|
|
160
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BuildTarget } from '../rspack/build-target';
|
|
2
|
+
export type TargetPreset = 'compatible' | 'modern';
|
|
3
|
+
export type TargetSpec = TargetPreset | string[];
|
|
4
|
+
export type TargetSetting = TargetSpec | Partial<Record<BuildTarget, TargetSpec>>;
|
|
5
|
+
export declare const PRESET_TARGETS: {
|
|
6
|
+
readonly compatible: {
|
|
7
|
+
readonly client: readonly ["chrome>=64", "edge>=79", "firefox>=67", "safari>=11.1"];
|
|
8
|
+
readonly server: readonly ["node>=24"];
|
|
9
|
+
readonly node: readonly ["node>=24"];
|
|
10
|
+
};
|
|
11
|
+
readonly modern: {
|
|
12
|
+
readonly client: readonly ["chrome>=89", "edge>=89", "firefox>=108", "safari>=16.4"];
|
|
13
|
+
readonly server: readonly ["node>=24"];
|
|
14
|
+
readonly node: readonly ["node>=24"];
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare function getTargetSetting(setting: TargetSetting | undefined, buildTarget: BuildTarget): string[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const PRESET_TARGETS = {
|
|
2
|
+
compatible: {
|
|
3
|
+
client: ["chrome>=64", "edge>=79", "firefox>=67", "safari>=11.1"],
|
|
4
|
+
server: ["node>=24"],
|
|
5
|
+
node: ["node>=24"]
|
|
6
|
+
},
|
|
7
|
+
modern: {
|
|
8
|
+
client: ["chrome>=89", "edge>=89", "firefox>=108", "safari>=16.4"],
|
|
9
|
+
server: ["node>=24"],
|
|
10
|
+
node: ["node>=24"]
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
function resolveTargetSpec(spec, buildTarget) {
|
|
14
|
+
if (typeof spec === "string") {
|
|
15
|
+
return [...PRESET_TARGETS[spec][buildTarget]];
|
|
16
|
+
}
|
|
17
|
+
return spec;
|
|
18
|
+
}
|
|
19
|
+
export function getTargetSetting(setting, buildTarget) {
|
|
20
|
+
if (!setting) {
|
|
21
|
+
return [...PRESET_TARGETS.compatible[buildTarget]];
|
|
22
|
+
}
|
|
23
|
+
if (typeof setting === "string" || Array.isArray(setting)) {
|
|
24
|
+
return resolveTargetSpec(setting, buildTarget);
|
|
25
|
+
}
|
|
26
|
+
const targetSpec = setting[buildTarget];
|
|
27
|
+
if (!targetSpec) {
|
|
28
|
+
return [...PRESET_TARGETS.compatible[buildTarget]];
|
|
29
|
+
}
|
|
30
|
+
return resolveTargetSpec(targetSpec, buildTarget);
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|