@esmx/rspack 3.0.0-rc.51 → 3.0.0-rc.53
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/rspack/pack.d.ts +8 -1
- package/dist/rspack/pack.mjs +27 -23
- package/dist/rspack/pack.test.d.ts +1 -0
- package/dist/rspack/pack.test.mjs +180 -0
- package/package.json +6 -8
- package/src/rspack/pack.test.ts +217 -0
- package/src/rspack/pack.ts +41 -23
package/dist/rspack/pack.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
import type { Esmx } from '@esmx/core';
|
|
1
|
+
import type { Esmx, ManifestJson } from '@esmx/core';
|
|
2
2
|
export declare function pack(esmx: Esmx): Promise<boolean>;
|
|
3
|
+
export interface GenerateExportsOptions {
|
|
4
|
+
client: ManifestJson['exports'];
|
|
5
|
+
server: ManifestJson['exports'];
|
|
6
|
+
base?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export declare function generateExports(options: GenerateExportsOptions): Record<string, unknown>;
|
|
9
|
+
export declare function contentHash(buffer: Buffer, algorithm?: string): string;
|
package/dist/rspack/pack.mjs
CHANGED
|
@@ -28,6 +28,27 @@ export async function pack(esmx) {
|
|
|
28
28
|
await packConfig.onAfter(esmx, pkgJson, data);
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
31
|
+
export function generateExports(options) {
|
|
32
|
+
const { client, server, base = {} } = options;
|
|
33
|
+
const exports = { ...base };
|
|
34
|
+
const set = /* @__PURE__ */ new Set([...Object.keys(client), ...Object.keys(server)]);
|
|
35
|
+
set.forEach((name) => {
|
|
36
|
+
const clientExport = client[name];
|
|
37
|
+
const serverExport = server[name];
|
|
38
|
+
const exportName = name === "index" ? "." : `./${name}`;
|
|
39
|
+
if (clientExport && serverExport) {
|
|
40
|
+
exports[exportName] = {
|
|
41
|
+
default: `./server/${serverExport.file}`,
|
|
42
|
+
browser: `./client/${clientExport.file}`
|
|
43
|
+
};
|
|
44
|
+
} else if (clientExport) {
|
|
45
|
+
exports[exportName] = `./client/${clientExport.file}`;
|
|
46
|
+
} else if (serverExport) {
|
|
47
|
+
exports[exportName] = `./server/${serverExport.file}`;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return exports;
|
|
51
|
+
}
|
|
31
52
|
async function buildPackageJson(esmx) {
|
|
32
53
|
const [clientJson, serverJson, curJson] = await Promise.all([
|
|
33
54
|
esmx.readJson(
|
|
@@ -38,27 +59,10 @@ async function buildPackageJson(esmx) {
|
|
|
38
59
|
),
|
|
39
60
|
esmx.readJson(esmx.resolvePath("package.json"))
|
|
40
61
|
]);
|
|
41
|
-
const exports = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
...Object.keys(clientJson.exports),
|
|
46
|
-
...Object.keys(serverJson.exports)
|
|
47
|
-
]);
|
|
48
|
-
set.forEach((name) => {
|
|
49
|
-
const client = clientJson.exports[name];
|
|
50
|
-
const server = serverJson.exports[name];
|
|
51
|
-
const exportName = `./${name}`;
|
|
52
|
-
if (client && server) {
|
|
53
|
-
exports[exportName] = {
|
|
54
|
-
default: `./server/${server.file}`,
|
|
55
|
-
browser: `./client/${client.file}`
|
|
56
|
-
};
|
|
57
|
-
} else if (client) {
|
|
58
|
-
exports[exportName] = `./client/${client.file}`;
|
|
59
|
-
} else if (server) {
|
|
60
|
-
exports[exportName] = `./server/${server.file}`;
|
|
61
|
-
}
|
|
62
|
+
const exports = generateExports({
|
|
63
|
+
client: clientJson.exports,
|
|
64
|
+
server: serverJson.exports,
|
|
65
|
+
base: curJson?.exports
|
|
62
66
|
});
|
|
63
67
|
const buildJson = {
|
|
64
68
|
...curJson,
|
|
@@ -66,8 +70,8 @@ async function buildPackageJson(esmx) {
|
|
|
66
70
|
};
|
|
67
71
|
return buildJson;
|
|
68
72
|
}
|
|
69
|
-
function contentHash(buffer, algorithm = "sha256") {
|
|
70
|
-
const hash = crypto.createHash(
|
|
73
|
+
export function contentHash(buffer, algorithm = "sha256") {
|
|
74
|
+
const hash = crypto.createHash(algorithm);
|
|
71
75
|
hash.update(buffer);
|
|
72
76
|
return `${algorithm}-${hash.digest("hex")}`;
|
|
73
77
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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: "exports/src/entry.client.95f6085b.final.mjs",
|
|
8
|
+
name: "src/entry.client",
|
|
9
|
+
rewrite: true,
|
|
10
|
+
identifier: "ssr-vue2-remote/src/entry.client"
|
|
11
|
+
},
|
|
12
|
+
"src/components/index": {
|
|
13
|
+
file: "exports/src/components/index.a73d6772.final.mjs",
|
|
14
|
+
name: "src/components/index",
|
|
15
|
+
rewrite: true,
|
|
16
|
+
identifier: "ssr-vue2-remote/src/components/index"
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const serverExports = {
|
|
20
|
+
"src/entry.server": {
|
|
21
|
+
file: "exports/src/entry.server.b85ed2ff.final.mjs",
|
|
22
|
+
name: "src/entry.server",
|
|
23
|
+
rewrite: true,
|
|
24
|
+
identifier: "ssr-vue2-remote/src/entry.server"
|
|
25
|
+
},
|
|
26
|
+
"src/components/index": {
|
|
27
|
+
file: "exports/src/components/index.12b57db5.final.mjs",
|
|
28
|
+
name: "src/components/index",
|
|
29
|
+
rewrite: 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/exports/src/entry.client.95f6085b.final.mjs",
|
|
39
|
+
"./src/entry.server": "./server/exports/src/entry.server.b85ed2ff.final.mjs",
|
|
40
|
+
"./src/components/index": {
|
|
41
|
+
default: "./server/exports/src/components/index.12b57db5.final.mjs",
|
|
42
|
+
browser: "./client/exports/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
|
+
rewrite: true,
|
|
52
|
+
identifier: "index"
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const serverExports = {
|
|
56
|
+
index: {
|
|
57
|
+
file: "index.js",
|
|
58
|
+
name: "index",
|
|
59
|
+
rewrite: 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
|
+
rewrite: 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
|
+
rewrite: 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
|
+
rewrite: true,
|
|
130
|
+
identifier: "index"
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const serverExports = {
|
|
134
|
+
index: {
|
|
135
|
+
file: "index.js",
|
|
136
|
+
name: "index",
|
|
137
|
+
rewrite: 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
|
+
});
|
package/package.json
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
],
|
|
45
45
|
"scripts": {
|
|
46
46
|
"lint:js": "biome check --write --no-errors-on-unmatched",
|
|
47
|
-
"lint:css": "
|
|
47
|
+
"lint:css": "npm run lint:js",
|
|
48
48
|
"lint:type": "tsc --noEmit",
|
|
49
49
|
"test": "vitest run --pass-with-no-tests",
|
|
50
50
|
"coverage": "vitest run --coverage --pass-with-no-tests",
|
|
@@ -63,8 +63,8 @@
|
|
|
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.53",
|
|
67
|
+
"@esmx/rspack-module-link-plugin": "3.0.0-rc.53",
|
|
68
68
|
"@npmcli/arborist": "^9.0.1",
|
|
69
69
|
"@rspack/core": "1.4.8",
|
|
70
70
|
"css-loader": "^7.1.2",
|
|
@@ -80,20 +80,18 @@
|
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@biomejs/biome": "1.9.4",
|
|
83
|
-
"@esmx/core": "3.0.0-rc.
|
|
84
|
-
"@esmx/lint": "3.0.0-rc.51",
|
|
83
|
+
"@esmx/core": "3.0.0-rc.53",
|
|
85
84
|
"@types/node": "^24.0.0",
|
|
86
85
|
"@types/npmcli__arborist": "^6.3.1",
|
|
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
89
|
"@vitest/coverage-v8": "3.2.4",
|
|
91
|
-
"stylelint": "16.21.0",
|
|
92
90
|
"typescript": "5.8.3",
|
|
93
91
|
"unbuild": "3.5.0",
|
|
94
92
|
"vitest": "3.2.4"
|
|
95
93
|
},
|
|
96
|
-
"version": "3.0.0-rc.
|
|
94
|
+
"version": "3.0.0-rc.53",
|
|
97
95
|
"type": "module",
|
|
98
96
|
"private": false,
|
|
99
97
|
"exports": {
|
|
@@ -112,5 +110,5 @@
|
|
|
112
110
|
"template",
|
|
113
111
|
"public"
|
|
114
112
|
],
|
|
115
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "e76fe45c0af262d52944c038f04e62b3b0fca3f7"
|
|
116
114
|
}
|
|
@@ -0,0 +1,217 @@
|
|
|
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: 'exports/src/entry.client.95f6085b.final.mjs',
|
|
10
|
+
name: 'src/entry.client',
|
|
11
|
+
rewrite: true,
|
|
12
|
+
identifier: 'ssr-vue2-remote/src/entry.client'
|
|
13
|
+
},
|
|
14
|
+
'src/components/index': {
|
|
15
|
+
file: 'exports/src/components/index.a73d6772.final.mjs',
|
|
16
|
+
name: 'src/components/index',
|
|
17
|
+
rewrite: true,
|
|
18
|
+
identifier: 'ssr-vue2-remote/src/components/index'
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const serverExports: ManifestJsonExports = {
|
|
23
|
+
'src/entry.server': {
|
|
24
|
+
file: 'exports/src/entry.server.b85ed2ff.final.mjs',
|
|
25
|
+
name: 'src/entry.server',
|
|
26
|
+
rewrite: true,
|
|
27
|
+
identifier: 'ssr-vue2-remote/src/entry.server'
|
|
28
|
+
},
|
|
29
|
+
'src/components/index': {
|
|
30
|
+
file: 'exports/src/components/index.12b57db5.final.mjs',
|
|
31
|
+
name: 'src/components/index',
|
|
32
|
+
rewrite: 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/exports/src/entry.client.95f6085b.final.mjs',
|
|
45
|
+
'./src/entry.server':
|
|
46
|
+
'./server/exports/src/entry.server.b85ed2ff.final.mjs',
|
|
47
|
+
'./src/components/index': {
|
|
48
|
+
default:
|
|
49
|
+
'./server/exports/src/components/index.12b57db5.final.mjs',
|
|
50
|
+
browser:
|
|
51
|
+
'./client/exports/src/components/index.a73d6772.final.mjs'
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should merge with existing exports', () => {
|
|
57
|
+
const clientExports: ManifestJsonExports = {
|
|
58
|
+
index: {
|
|
59
|
+
file: 'index.js',
|
|
60
|
+
name: 'index',
|
|
61
|
+
rewrite: true,
|
|
62
|
+
identifier: 'index'
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const serverExports: ManifestJsonExports = {
|
|
67
|
+
index: {
|
|
68
|
+
file: 'index.js',
|
|
69
|
+
name: 'index',
|
|
70
|
+
rewrite: true,
|
|
71
|
+
identifier: 'index'
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const existingExports = {
|
|
76
|
+
'./custom': './custom.js'
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const result = generateExports({
|
|
80
|
+
client: clientExports,
|
|
81
|
+
server: serverExports,
|
|
82
|
+
base: existingExports
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(result).toEqual({
|
|
86
|
+
'./custom': './custom.js',
|
|
87
|
+
'.': {
|
|
88
|
+
default: './server/index.js',
|
|
89
|
+
browser: './client/index.js'
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should handle empty exports', () => {
|
|
95
|
+
const clientExports: ManifestJsonExports = {};
|
|
96
|
+
const serverExports: ManifestJsonExports = {};
|
|
97
|
+
|
|
98
|
+
const result = generateExports({
|
|
99
|
+
client: clientExports,
|
|
100
|
+
server: serverExports
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
expect(result).toEqual({});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should handle only client exports', () => {
|
|
107
|
+
const clientExports: ManifestJsonExports = {
|
|
108
|
+
utils: {
|
|
109
|
+
file: 'utils.js',
|
|
110
|
+
name: 'utils',
|
|
111
|
+
rewrite: true,
|
|
112
|
+
identifier: 'utils'
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const serverExports: ManifestJsonExports = {};
|
|
117
|
+
|
|
118
|
+
const result = generateExports({
|
|
119
|
+
client: clientExports,
|
|
120
|
+
server: serverExports
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
expect(result).toEqual({
|
|
124
|
+
'./utils': './client/utils.js'
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should handle only server exports', () => {
|
|
129
|
+
const clientExports: ManifestJsonExports = {};
|
|
130
|
+
|
|
131
|
+
const serverExports: ManifestJsonExports = {
|
|
132
|
+
api: {
|
|
133
|
+
file: 'api.js',
|
|
134
|
+
name: 'api',
|
|
135
|
+
rewrite: true,
|
|
136
|
+
identifier: 'api'
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const result = generateExports({
|
|
141
|
+
client: clientExports,
|
|
142
|
+
server: serverExports
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(result).toEqual({
|
|
146
|
+
'./api': './server/api.js'
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should handle index export correctly', () => {
|
|
151
|
+
const clientExports: ManifestJsonExports = {
|
|
152
|
+
index: {
|
|
153
|
+
file: 'index.js',
|
|
154
|
+
name: 'index',
|
|
155
|
+
rewrite: true,
|
|
156
|
+
identifier: 'index'
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const serverExports: ManifestJsonExports = {
|
|
161
|
+
index: {
|
|
162
|
+
file: 'index.js',
|
|
163
|
+
name: 'index',
|
|
164
|
+
rewrite: true,
|
|
165
|
+
identifier: 'index'
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const result = generateExports({
|
|
170
|
+
client: clientExports,
|
|
171
|
+
server: serverExports
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(result).toEqual({
|
|
175
|
+
'.': {
|
|
176
|
+
default: './server/index.js',
|
|
177
|
+
browser: './client/index.js'
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('contentHash', () => {
|
|
184
|
+
it('should generate SHA256 hash for buffer', () => {
|
|
185
|
+
const buffer = Buffer.from('test content');
|
|
186
|
+
const result = contentHash(buffer);
|
|
187
|
+
|
|
188
|
+
expect(result).toMatch(/^sha256-[a-f0-9]{64}$/);
|
|
189
|
+
expect(result).toBe(
|
|
190
|
+
'sha256-6ae8a75555209fd6c44157c0aed8016e763ff435a19cf186f76863140143ff72'
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('should use custom algorithm when provided', () => {
|
|
195
|
+
const buffer = Buffer.from('test content');
|
|
196
|
+
const result = contentHash(buffer, 'md5');
|
|
197
|
+
|
|
198
|
+
expect(result).toMatch(/^md5-[a-f0-9]{32}$/);
|
|
199
|
+
expect(result).toBe('md5-9473fdd0d880a43c21b7778d34872157');
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should handle empty buffer', () => {
|
|
203
|
+
const buffer = Buffer.from('');
|
|
204
|
+
const result = contentHash(buffer);
|
|
205
|
+
|
|
206
|
+
expect(result).toBe(
|
|
207
|
+
'sha256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should handle binary data', () => {
|
|
212
|
+
const buffer = Buffer.from([0x00, 0x01, 0x02, 0x03, 0xff]);
|
|
213
|
+
const result = contentHash(buffer);
|
|
214
|
+
|
|
215
|
+
expect(result).toMatch(/^sha256-[a-f0-9]{64}$/);
|
|
216
|
+
});
|
|
217
|
+
});
|
package/src/rspack/pack.ts
CHANGED
|
@@ -36,6 +36,40 @@ export async function pack(esmx: Esmx): Promise<boolean> {
|
|
|
36
36
|
return true;
|
|
37
37
|
}
|
|
38
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
|
+
|
|
39
73
|
async function buildPackageJson(esmx: Esmx): Promise<Record<string, any>> {
|
|
40
74
|
const [clientJson, serverJson, curJson] = await Promise.all([
|
|
41
75
|
esmx.readJson<ManifestJson>(
|
|
@@ -46,27 +80,11 @@ async function buildPackageJson(esmx: Esmx): Promise<Record<string, any>> {
|
|
|
46
80
|
),
|
|
47
81
|
esmx.readJson(esmx.resolvePath('package.json'))
|
|
48
82
|
]);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
...Object.keys(serverJson.exports)
|
|
55
|
-
]);
|
|
56
|
-
set.forEach((name) => {
|
|
57
|
-
const client = clientJson.exports[name];
|
|
58
|
-
const server = serverJson.exports[name];
|
|
59
|
-
const exportName = `./${name}`;
|
|
60
|
-
if (client && server) {
|
|
61
|
-
exports[exportName] = {
|
|
62
|
-
default: `./server/${server.file}`,
|
|
63
|
-
browser: `./client/${client.file}`
|
|
64
|
-
};
|
|
65
|
-
} else if (client) {
|
|
66
|
-
exports[exportName] = `./client/${client.file}`;
|
|
67
|
-
} else if (server) {
|
|
68
|
-
exports[exportName] = `./server/${server.file}`;
|
|
69
|
-
}
|
|
83
|
+
|
|
84
|
+
const exports = generateExports({
|
|
85
|
+
client: clientJson.exports,
|
|
86
|
+
server: serverJson.exports,
|
|
87
|
+
base: curJson?.exports
|
|
70
88
|
});
|
|
71
89
|
|
|
72
90
|
const buildJson: Record<string, any> = {
|
|
@@ -76,8 +94,8 @@ async function buildPackageJson(esmx: Esmx): Promise<Record<string, any>> {
|
|
|
76
94
|
return buildJson;
|
|
77
95
|
}
|
|
78
96
|
|
|
79
|
-
function contentHash(buffer: Buffer, algorithm = 'sha256') {
|
|
80
|
-
const hash = crypto.createHash(
|
|
97
|
+
export function contentHash(buffer: Buffer, algorithm = 'sha256') {
|
|
98
|
+
const hash = crypto.createHash(algorithm);
|
|
81
99
|
hash.update(buffer);
|
|
82
100
|
return `${algorithm}-${hash.digest('hex')}`;
|
|
83
101
|
}
|