@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,215 @@
|
|
|
1
|
+
import type { ManifestJsonExports } from '@esmx/core';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { contentHash, generateExports } from './pack';
|
|
4
|
+
|
|
5
|
+
describe('generateExports', () => {
|
|
6
|
+
it('should generate exports with both client and server files', () => {
|
|
7
|
+
const clientExports: ManifestJsonExports = {
|
|
8
|
+
'src/entry.client': {
|
|
9
|
+
file: 'src/entry.client.95f6085b.final.mjs',
|
|
10
|
+
name: 'src/entry.client',
|
|
11
|
+
pkg: true,
|
|
12
|
+
identifier: 'ssr-vue2-remote/src/entry.client'
|
|
13
|
+
},
|
|
14
|
+
'src/components/index': {
|
|
15
|
+
file: 'src/components/index.a73d6772.final.mjs',
|
|
16
|
+
name: 'src/components/index',
|
|
17
|
+
pkg: true,
|
|
18
|
+
identifier: 'ssr-vue2-remote/src/components/index'
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const serverExports: ManifestJsonExports = {
|
|
23
|
+
'src/entry.server': {
|
|
24
|
+
file: 'src/entry.server.b85ed2ff.final.mjs',
|
|
25
|
+
name: 'src/entry.server',
|
|
26
|
+
pkg: true,
|
|
27
|
+
identifier: 'ssr-vue2-remote/src/entry.server'
|
|
28
|
+
},
|
|
29
|
+
'src/components/index': {
|
|
30
|
+
file: 'src/components/index.12b57db5.final.mjs',
|
|
31
|
+
name: 'src/components/index',
|
|
32
|
+
pkg: true,
|
|
33
|
+
identifier: 'ssr-vue2-remote/src/components/index'
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const result = generateExports({
|
|
38
|
+
client: clientExports,
|
|
39
|
+
server: serverExports
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
expect(result).toEqual({
|
|
43
|
+
'./src/entry.client':
|
|
44
|
+
'./client/src/entry.client.95f6085b.final.mjs',
|
|
45
|
+
'./src/entry.server':
|
|
46
|
+
'./server/src/entry.server.b85ed2ff.final.mjs',
|
|
47
|
+
'./src/components/index': {
|
|
48
|
+
default: './server/src/components/index.12b57db5.final.mjs',
|
|
49
|
+
browser: './client/src/components/index.a73d6772.final.mjs'
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should merge with existing exports', () => {
|
|
55
|
+
const clientExports: ManifestJsonExports = {
|
|
56
|
+
index: {
|
|
57
|
+
file: 'index.js',
|
|
58
|
+
name: 'index',
|
|
59
|
+
pkg: true,
|
|
60
|
+
identifier: 'index'
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const serverExports: ManifestJsonExports = {
|
|
65
|
+
index: {
|
|
66
|
+
file: 'index.js',
|
|
67
|
+
name: 'index',
|
|
68
|
+
pkg: true,
|
|
69
|
+
identifier: 'index'
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const existingExports = {
|
|
74
|
+
'./custom': './custom.js'
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const result = generateExports({
|
|
78
|
+
client: clientExports,
|
|
79
|
+
server: serverExports,
|
|
80
|
+
base: existingExports
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
expect(result).toEqual({
|
|
84
|
+
'./custom': './custom.js',
|
|
85
|
+
'.': {
|
|
86
|
+
default: './server/index.js',
|
|
87
|
+
browser: './client/index.js'
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should handle empty exports', () => {
|
|
93
|
+
const clientExports: ManifestJsonExports = {};
|
|
94
|
+
const serverExports: ManifestJsonExports = {};
|
|
95
|
+
|
|
96
|
+
const result = generateExports({
|
|
97
|
+
client: clientExports,
|
|
98
|
+
server: serverExports
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(result).toEqual({});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should handle only client exports', () => {
|
|
105
|
+
const clientExports: ManifestJsonExports = {
|
|
106
|
+
utils: {
|
|
107
|
+
file: 'utils.js',
|
|
108
|
+
name: 'utils',
|
|
109
|
+
pkg: true,
|
|
110
|
+
identifier: 'utils'
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const serverExports: ManifestJsonExports = {};
|
|
115
|
+
|
|
116
|
+
const result = generateExports({
|
|
117
|
+
client: clientExports,
|
|
118
|
+
server: serverExports
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
expect(result).toEqual({
|
|
122
|
+
'./utils': './client/utils.js'
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should handle only server exports', () => {
|
|
127
|
+
const clientExports: ManifestJsonExports = {};
|
|
128
|
+
|
|
129
|
+
const serverExports: ManifestJsonExports = {
|
|
130
|
+
api: {
|
|
131
|
+
file: 'api.js',
|
|
132
|
+
name: 'api',
|
|
133
|
+
pkg: true,
|
|
134
|
+
identifier: 'api'
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const result = generateExports({
|
|
139
|
+
client: clientExports,
|
|
140
|
+
server: serverExports
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
expect(result).toEqual({
|
|
144
|
+
'./api': './server/api.js'
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should handle index export correctly', () => {
|
|
149
|
+
const clientExports: ManifestJsonExports = {
|
|
150
|
+
index: {
|
|
151
|
+
file: 'index.js',
|
|
152
|
+
name: 'index',
|
|
153
|
+
pkg: true,
|
|
154
|
+
identifier: 'index'
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const serverExports: ManifestJsonExports = {
|
|
159
|
+
index: {
|
|
160
|
+
file: 'index.js',
|
|
161
|
+
name: 'index',
|
|
162
|
+
pkg: true,
|
|
163
|
+
identifier: 'index'
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const result = generateExports({
|
|
168
|
+
client: clientExports,
|
|
169
|
+
server: serverExports
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
expect(result).toEqual({
|
|
173
|
+
'.': {
|
|
174
|
+
default: './server/index.js',
|
|
175
|
+
browser: './client/index.js'
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('contentHash', () => {
|
|
182
|
+
it('should generate SHA256 hash for buffer', () => {
|
|
183
|
+
const buffer = Buffer.from('test content');
|
|
184
|
+
const result = contentHash(buffer);
|
|
185
|
+
|
|
186
|
+
expect(result).toMatch(/^sha256-[a-f0-9]{64}$/);
|
|
187
|
+
expect(result).toBe(
|
|
188
|
+
'sha256-6ae8a75555209fd6c44157c0aed8016e763ff435a19cf186f76863140143ff72'
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('should use custom algorithm when provided', () => {
|
|
193
|
+
const buffer = Buffer.from('test content');
|
|
194
|
+
const result = contentHash(buffer, 'md5');
|
|
195
|
+
|
|
196
|
+
expect(result).toMatch(/^md5-[a-f0-9]{32}$/);
|
|
197
|
+
expect(result).toBe('md5-9473fdd0d880a43c21b7778d34872157');
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should handle empty buffer', () => {
|
|
201
|
+
const buffer = Buffer.from('');
|
|
202
|
+
const result = contentHash(buffer);
|
|
203
|
+
|
|
204
|
+
expect(result).toBe(
|
|
205
|
+
'sha256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should handle binary data', () => {
|
|
210
|
+
const buffer = Buffer.from([0x00, 0x01, 0x02, 0x03, 0xff]);
|
|
211
|
+
const result = contentHash(buffer);
|
|
212
|
+
|
|
213
|
+
expect(result).toMatch(/^sha256-[a-f0-9]{64}$/);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import type { Esmx, ManifestJson } from '@esmx/core';
|
|
3
|
+
import Arborist from '@npmcli/arborist';
|
|
4
|
+
import pacote from 'pacote';
|
|
5
|
+
|
|
6
|
+
export async function pack(esmx: Esmx): Promise<boolean> {
|
|
7
|
+
const { packConfig } = esmx;
|
|
8
|
+
|
|
9
|
+
const pkgJson = await packConfig.packageJson(
|
|
10
|
+
esmx,
|
|
11
|
+
await buildPackageJson(esmx)
|
|
12
|
+
);
|
|
13
|
+
esmx.writeSync(
|
|
14
|
+
esmx.resolvePath('dist/package.json'),
|
|
15
|
+
JSON.stringify(pkgJson, null, 4)
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
if (!packConfig.enable) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
await packConfig.onBefore(esmx, pkgJson);
|
|
23
|
+
|
|
24
|
+
const data = await pacote.tarball(esmx.resolvePath('dist'), {
|
|
25
|
+
Arborist
|
|
26
|
+
});
|
|
27
|
+
const hash = contentHash(data);
|
|
28
|
+
packConfig.outputs.forEach((file) => {
|
|
29
|
+
const tgz = esmx.resolvePath('./', file);
|
|
30
|
+
const txt = tgz.replace(/\.tgz$/, '.txt');
|
|
31
|
+
esmx.writeSync(tgz, data);
|
|
32
|
+
esmx.writeSync(txt, hash);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await packConfig.onAfter(esmx, pkgJson, data);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface GenerateExportsOptions {
|
|
40
|
+
client: ManifestJson['exports'];
|
|
41
|
+
server: ManifestJson['exports'];
|
|
42
|
+
base?: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function generateExports(
|
|
46
|
+
options: GenerateExportsOptions
|
|
47
|
+
): Record<string, unknown> {
|
|
48
|
+
const { client, server, base = {} } = options;
|
|
49
|
+
const exports: Record<string, unknown> = { ...base };
|
|
50
|
+
|
|
51
|
+
const set = new Set([...Object.keys(client), ...Object.keys(server)]);
|
|
52
|
+
|
|
53
|
+
set.forEach((name) => {
|
|
54
|
+
const clientExport = client[name];
|
|
55
|
+
const serverExport = server[name];
|
|
56
|
+
const exportName = name === 'index' ? '.' : `./${name}`;
|
|
57
|
+
|
|
58
|
+
if (clientExport && serverExport) {
|
|
59
|
+
exports[exportName] = {
|
|
60
|
+
default: `./server/${serverExport.file}`,
|
|
61
|
+
browser: `./client/${clientExport.file}`
|
|
62
|
+
};
|
|
63
|
+
} else if (clientExport) {
|
|
64
|
+
exports[exportName] = `./client/${clientExport.file}`;
|
|
65
|
+
} else if (serverExport) {
|
|
66
|
+
exports[exportName] = `./server/${serverExport.file}`;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return exports;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function buildPackageJson(esmx: Esmx): Promise<Record<string, any>> {
|
|
74
|
+
const [clientJson, serverJson, curJson] = await Promise.all([
|
|
75
|
+
esmx.readJson<ManifestJson>(
|
|
76
|
+
esmx.resolvePath('dist/client/manifest.json')
|
|
77
|
+
),
|
|
78
|
+
esmx.readJson<ManifestJson>(
|
|
79
|
+
esmx.resolvePath('dist/server/manifest.json')
|
|
80
|
+
),
|
|
81
|
+
esmx.readJson(esmx.resolvePath('package.json'))
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
const exports = generateExports({
|
|
85
|
+
client: clientJson.exports,
|
|
86
|
+
server: serverJson.exports,
|
|
87
|
+
base: curJson?.exports
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const buildJson: Record<string, any> = {
|
|
91
|
+
...curJson,
|
|
92
|
+
exports
|
|
93
|
+
};
|
|
94
|
+
return buildJson;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function contentHash(buffer: Buffer, algorithm = 'sha256') {
|
|
98
|
+
const hash = crypto.createHash(algorithm);
|
|
99
|
+
hash.update(buffer);
|
|
100
|
+
return `${algorithm}-${hash.digest('hex')}`;
|
|
101
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
|
-
import { type
|
|
2
|
+
import { type RspackOptions, rspack } from '@rspack/core';
|
|
3
|
+
|
|
4
|
+
function showError(message: string) {
|
|
5
|
+
console.error(styleText('red', message));
|
|
6
|
+
}
|
|
3
7
|
|
|
4
8
|
export function createRsBuild(options: RspackOptions[]) {
|
|
5
9
|
const multiCompiler = rspack(options);
|
|
@@ -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()) {
|
|
@@ -46,7 +51,7 @@ export function createRsBuild(options: RspackOptions[]) {
|
|
|
46
51
|
}
|
|
47
52
|
});
|
|
48
53
|
|
|
49
|
-
//
|
|
54
|
+
// Listen to process signals to ensure graceful shutdown
|
|
50
55
|
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'] satisfies string[];
|
|
51
56
|
signals.forEach((signal) => {
|
|
52
57
|
process.on(signal, () => {
|
|
@@ -56,7 +61,7 @@ export function createRsBuild(options: RspackOptions[]) {
|
|
|
56
61
|
});
|
|
57
62
|
});
|
|
58
63
|
|
|
59
|
-
//
|
|
64
|
+
// Listen to uncaught exceptions and Promise rejections
|
|
60
65
|
process.on('uncaughtException', handleExit);
|
|
61
66
|
process.on('unhandledRejection', handleExit);
|
|
62
67
|
|
|
@@ -69,37 +74,3 @@ export function createRsBuild(options: RspackOptions[]) {
|
|
|
69
74
|
}
|
|
70
75
|
};
|
|
71
76
|
}
|
|
72
|
-
|
|
73
|
-
export class RsBuild {
|
|
74
|
-
private compiler: Compiler;
|
|
75
|
-
public constructor(options: RspackOptions) {
|
|
76
|
-
this.compiler = rspack(options);
|
|
77
|
-
}
|
|
78
|
-
public async build() {
|
|
79
|
-
return new Promise<boolean>((resolve) => {
|
|
80
|
-
this.compiler.run((err, stats) => {
|
|
81
|
-
if (err) {
|
|
82
|
-
return resolve(false);
|
|
83
|
-
}
|
|
84
|
-
if (stats?.hasErrors()) {
|
|
85
|
-
stats.toJson({ errors: true })?.errors?.forEach((err) => {
|
|
86
|
-
console.error(err);
|
|
87
|
-
});
|
|
88
|
-
return resolve(false);
|
|
89
|
-
}
|
|
90
|
-
this.compiler.close((err) => {
|
|
91
|
-
if (err) {
|
|
92
|
-
console.error(err);
|
|
93
|
-
return resolve(false);
|
|
94
|
-
}
|
|
95
|
-
process.nextTick(() => {
|
|
96
|
-
resolve(true);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
public watch() {
|
|
103
|
-
const watching = this.compiler.watch({}, () => {});
|
|
104
|
-
}
|
|
105
|
-
}
|