@meteorjs/rspack 2.0.1 → 2.1.0
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/lib/swc.js +7 -1
- package/lib/testClientNodePolyfills.js +66 -0
- package/package.json +9 -3
- package/plugins/RequireExtenalsPlugin.js +27 -10
- package/rspack.config.js +6 -8
- package/.claude/settings.local.json +0 -10
package/lib/swc.js
CHANGED
|
@@ -14,7 +14,13 @@ function getMeteorAppSwcrc(file = '.swcrc') {
|
|
|
14
14
|
|
|
15
15
|
if (file.endsWith('.ts')) {
|
|
16
16
|
try {
|
|
17
|
-
|
|
17
|
+
let swc;
|
|
18
|
+
try {
|
|
19
|
+
swc = require(require.resolve('@swc/core', { paths: [process.cwd()] }));
|
|
20
|
+
} catch (e) {
|
|
21
|
+
if (e.code !== 'MODULE_NOT_FOUND') throw e;
|
|
22
|
+
swc = require('@swc/core');
|
|
23
|
+
}
|
|
18
24
|
const result = swc.transformSync(content, {
|
|
19
25
|
jsc: {
|
|
20
26
|
parser: {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const { ProvidePlugin } = require("@rspack/core");
|
|
2
|
+
|
|
3
|
+
let meteorNodeStubs;
|
|
4
|
+
try {
|
|
5
|
+
const stubPath = require.resolve("meteor-node-stubs", { paths: [process.cwd()] });
|
|
6
|
+
meteorNodeStubs = require(stubPath);
|
|
7
|
+
} catch (e) {
|
|
8
|
+
if (e.code !== 'MODULE_NOT_FOUND') throw e;
|
|
9
|
+
try {
|
|
10
|
+
meteorNodeStubs = require("meteor-node-stubs");
|
|
11
|
+
} catch (fallbackError) {
|
|
12
|
+
if (fallbackError.code !== 'MODULE_NOT_FOUND') throw fallbackError;
|
|
13
|
+
// It's optional. If not installed, meteorNodeStubs remains undefined.
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const TEST_CLIENT_NODE_POLYFILLS = [
|
|
18
|
+
"assert",
|
|
19
|
+
"buffer",
|
|
20
|
+
"constants",
|
|
21
|
+
"crypto",
|
|
22
|
+
"events",
|
|
23
|
+
"fs",
|
|
24
|
+
"http",
|
|
25
|
+
"https",
|
|
26
|
+
"os",
|
|
27
|
+
"path",
|
|
28
|
+
"querystring",
|
|
29
|
+
"stream",
|
|
30
|
+
"string_decoder",
|
|
31
|
+
"sys",
|
|
32
|
+
"timers",
|
|
33
|
+
"tty",
|
|
34
|
+
"url",
|
|
35
|
+
"util",
|
|
36
|
+
"vm",
|
|
37
|
+
"zlib",
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
function createTestClientNodePolyfillConfig() {
|
|
41
|
+
const fallback = Object.fromEntries(
|
|
42
|
+
TEST_CLIENT_NODE_POLYFILLS.map((name) => [name, meteorNodeStubs?.[name] ?? false]),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const plugins = [];
|
|
46
|
+
|
|
47
|
+
if (meteorNodeStubs?.buffer) {
|
|
48
|
+
plugins.push(
|
|
49
|
+
new ProvidePlugin({
|
|
50
|
+
Buffer: [meteorNodeStubs.buffer, "Buffer"],
|
|
51
|
+
})
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
resolve: {
|
|
57
|
+
alias: {
|
|
58
|
+
"timers/promises$": require.resolve("isomorphic-timers-promises"),
|
|
59
|
+
},
|
|
60
|
+
fallback,
|
|
61
|
+
},
|
|
62
|
+
plugins,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = { createTestClientNodePolyfillConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meteorjs/rspack",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Configuration logic for using Rspack in Meteor projects",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"fast-deep-equal": "^3.1.3",
|
|
15
15
|
"ignore-loader": "^0.1.2",
|
|
16
|
-
"
|
|
16
|
+
"isomorphic-timers-promises": "^1.0.1",
|
|
17
17
|
"webpack-merge": "^6.0.1"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"@rspack/cli": ">=1.3.0",
|
|
24
24
|
"@rspack/core": ">=1.3.0",
|
|
25
|
-
"@swc/core": ">=1.3.0"
|
|
25
|
+
"@swc/core": ">=1.3.0",
|
|
26
|
+
"meteor-node-stubs": ">=1.2.0"
|
|
27
|
+
},
|
|
28
|
+
"peerDependenciesMeta": {
|
|
29
|
+
"meteor-node-stubs": {
|
|
30
|
+
"optional": true
|
|
31
|
+
}
|
|
26
32
|
}
|
|
27
33
|
}
|
|
@@ -13,6 +13,18 @@ const path = require('path');
|
|
|
13
13
|
// Normalize a path to always use forward slashes (POSIX style).
|
|
14
14
|
// Module identifiers in bundled JS must use '/' regardless of OS.
|
|
15
15
|
const toPosix = (p) => p.replace(/\\/g, '/');
|
|
16
|
+
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
17
|
+
const buildStandaloneRequireRegex = (pkg) =>
|
|
18
|
+
new RegExp(`^\\s*require\\('${escapeRegExp(pkg)}'\\);?.*(\\r?\\n)?`, 'gm');
|
|
19
|
+
const buildStandaloneImportRegex = (pkg) =>
|
|
20
|
+
new RegExp(
|
|
21
|
+
`^[\\t ]*import[\\t ]+'${escapeRegExp(pkg)}';?[^\\r\\n]*(?:\\r?\\n|$)`,
|
|
22
|
+
'gm'
|
|
23
|
+
);
|
|
24
|
+
const MANAGED_IMPORT_BLOCK_REGEX =
|
|
25
|
+
/^\/\/\s*\(function\s+(?:eagerExternalImports\d+|lastImports(?:\d+)?)\s*\(\)\s*\{\s*\r?\n[\s\S]*?^\/\/\s*\}\)\s*(?:\r?\n|$)/gm;
|
|
26
|
+
const STANDALONE_REQUIRE_REGEX = /^\s*require\('([^']+)'\)/gm;
|
|
27
|
+
const STANDALONE_IMPORT_REGEX = /^\s*import\s+'([^']+)'/gm;
|
|
16
28
|
|
|
17
29
|
class RequireExternalsPlugin {
|
|
18
30
|
constructor({
|
|
@@ -173,15 +185,22 @@ class RequireExternalsPlugin {
|
|
|
173
185
|
}
|
|
174
186
|
}
|
|
175
187
|
|
|
176
|
-
// 2b) Remove any
|
|
188
|
+
// 2b) Remove any dependencies that are no longer in `current`
|
|
177
189
|
const toRemove = [...existing].filter(p => !current.has(p));
|
|
178
190
|
if (toRemove.length) {
|
|
179
191
|
let content = fs.readFileSync(this.filePath, 'utf-8');
|
|
180
192
|
|
|
181
|
-
// Strip stale
|
|
193
|
+
// Strip stale requires and imports generated by this plugin. Other
|
|
194
|
+
// standalone imports link Meteor entry and Rspack output files and
|
|
195
|
+
// must remain intact.
|
|
182
196
|
for (const pkg of toRemove) {
|
|
183
|
-
const
|
|
184
|
-
|
|
197
|
+
const requireRe = buildStandaloneRequireRegex(pkg);
|
|
198
|
+
const importRe = buildStandaloneImportRegex(pkg);
|
|
199
|
+
content = content.replace(requireRe, '');
|
|
200
|
+
content = content.replace(
|
|
201
|
+
MANAGED_IMPORT_BLOCK_REGEX,
|
|
202
|
+
(block) => block.replace(importRe, '')
|
|
203
|
+
);
|
|
185
204
|
}
|
|
186
205
|
|
|
187
206
|
// Strip out any now-empty helper functions:
|
|
@@ -206,11 +225,11 @@ class RequireExternalsPlugin {
|
|
|
206
225
|
// Re-populate `existing` so the add-diff is accurate
|
|
207
226
|
existing.clear();
|
|
208
227
|
// Check for require statements
|
|
209
|
-
for (const match of content.matchAll(
|
|
228
|
+
for (const match of content.matchAll(STANDALONE_REQUIRE_REGEX)) {
|
|
210
229
|
existing.add(match[1]);
|
|
211
230
|
}
|
|
212
231
|
// Also check for import statements (used in the new format)
|
|
213
|
-
for (const match of content.matchAll(
|
|
232
|
+
for (const match of content.matchAll(STANDALONE_IMPORT_REGEX)) {
|
|
214
233
|
existing.add(match[1]);
|
|
215
234
|
}
|
|
216
235
|
}
|
|
@@ -481,15 +500,13 @@ class RequireExternalsPlugin {
|
|
|
481
500
|
try {
|
|
482
501
|
const content = fs.readFileSync(this.filePath, 'utf-8');
|
|
483
502
|
// Check for require statements
|
|
484
|
-
const requireRegex = /require\('([^']+)'\)/g;
|
|
485
503
|
let match;
|
|
486
|
-
while ((match =
|
|
504
|
+
while ((match = STANDALONE_REQUIRE_REGEX.exec(content)) !== null) {
|
|
487
505
|
existing.add(match[1]);
|
|
488
506
|
}
|
|
489
507
|
|
|
490
508
|
// Also check for import statements (used in the new format)
|
|
491
|
-
|
|
492
|
-
while ((match = importRegex.exec(content)) !== null) {
|
|
509
|
+
while ((match = STANDALONE_IMPORT_REGEX.exec(content)) !== null) {
|
|
493
510
|
existing.add(match[1]);
|
|
494
511
|
}
|
|
495
512
|
} catch {
|
package/rspack.config.js
CHANGED
|
@@ -3,7 +3,6 @@ const fs = require('fs');
|
|
|
3
3
|
const { inspect } = require('node:util');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { merge } = require('webpack-merge');
|
|
6
|
-
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
|
|
7
6
|
|
|
8
7
|
const { cleanOmittedPaths, mergeSplitOverlap } = require("./lib/mergeRulesSplitOverlap.js");
|
|
9
8
|
const { getMeteorAppSwcConfig } = require('./lib/swc.js');
|
|
@@ -30,7 +29,7 @@ const {
|
|
|
30
29
|
const { loadUserAndOverrideConfig } = require('./lib/meteorRspackConfigHelpers.js');
|
|
31
30
|
const { prepareMeteorRspackConfig } = require("./lib/meteorRspackConfigFactory");
|
|
32
31
|
const { extractLocalDependencies } = require('./lib/localDependenciesHelpers.js');
|
|
33
|
-
|
|
32
|
+
const { createTestClientNodePolyfillConfig } = require("./lib/testClientNodePolyfills.js");
|
|
34
33
|
|
|
35
34
|
// Safe require that doesn't throw if the module isn't found
|
|
36
35
|
function safeRequire(moduleName) {
|
|
@@ -127,15 +126,13 @@ function createSwcConfig({
|
|
|
127
126
|
}) {
|
|
128
127
|
const defaultConfig = {
|
|
129
128
|
jsc: {
|
|
130
|
-
baseUrl: process.cwd(),
|
|
131
|
-
paths: { '/*': ['*', '/*'] },
|
|
132
129
|
parser: {
|
|
133
130
|
syntax: isTypescriptEnabled ? 'typescript' : 'ecmascript',
|
|
134
131
|
...(isTsxEnabled && { tsx: true }),
|
|
135
132
|
...(isJsxEnabled && { jsx: true }),
|
|
136
133
|
...(isAngularEnabled && { decorators: true }),
|
|
137
134
|
},
|
|
138
|
-
target: 'es2015',
|
|
135
|
+
target: isClient ? 'es2015' : 'es2022',
|
|
139
136
|
...(isReactEnabled && {
|
|
140
137
|
transform: {
|
|
141
138
|
react: {
|
|
@@ -426,7 +423,7 @@ module.exports = async function (inMeteor = {}, argv = {}) {
|
|
|
426
423
|
// Additional ignore entries
|
|
427
424
|
const additionalEntries = [
|
|
428
425
|
"**/.meteor/local/**",
|
|
429
|
-
"
|
|
426
|
+
path.join(projectDir, "dist", "**").replace(/\\/g, "/"),
|
|
430
427
|
...(isTest && isTestEager
|
|
431
428
|
? [`**/${buildContext}/**`, "**/.meteor/local/**", "node_modules/**"]
|
|
432
429
|
: []),
|
|
@@ -650,7 +647,7 @@ module.exports = async function (inMeteor = {}, argv = {}) {
|
|
|
650
647
|
...extraRules,
|
|
651
648
|
],
|
|
652
649
|
},
|
|
653
|
-
resolve: { extensions, alias, fallback },
|
|
650
|
+
resolve: { extensions, alias, fallback, roots: [path.resolve(projectDir)] },
|
|
654
651
|
externals,
|
|
655
652
|
plugins: [
|
|
656
653
|
...[
|
|
@@ -774,6 +771,7 @@ module.exports = async function (inMeteor = {}, argv = {}) {
|
|
|
774
771
|
alias,
|
|
775
772
|
modules: ["node_modules", path.resolve(projectDir)],
|
|
776
773
|
conditionNames: ["import", "require", "node", "default"],
|
|
774
|
+
roots: [path.resolve(projectDir)],
|
|
777
775
|
},
|
|
778
776
|
externals,
|
|
779
777
|
externalsPresets: { node: true },
|
|
@@ -841,7 +839,7 @@ module.exports = async function (inMeteor = {}, argv = {}) {
|
|
|
841
839
|
optimization: {
|
|
842
840
|
splitChunks: false,
|
|
843
841
|
},
|
|
844
|
-
|
|
842
|
+
...createTestClientNodePolyfillConfig(),
|
|
845
843
|
}
|
|
846
844
|
: {};
|
|
847
845
|
|