every-plugin 3.0.0-rc.6 → 3.0.0-rc.7
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/build/rspack/chunk-completeness-plugin.cjs +19 -7
- package/dist/build/rspack/chunk-completeness-plugin.cjs.map +1 -1
- package/dist/build/rspack/chunk-completeness-plugin.mjs +19 -7
- package/dist/build/rspack/chunk-completeness-plugin.mjs.map +1 -1
- package/dist/runtime/mf-config.cjs +1 -1
- package/dist/runtime/mf-config.mjs +1 -1
- package/package.json +1 -1
- package/skills/plugin-client/SKILL.md +10 -4
- package/skills/plugin-testing/SKILL.md +1 -0
- package/src/build/rspack/chunk-completeness-plugin.ts +15 -6
|
@@ -28,14 +28,26 @@ var ChunkCompletenessPlugin = class {
|
|
|
28
28
|
const entry = require_build_artifact_names.findHashedEntry(names, this.entryBase) ?? names.find((n) => n === `${this.entryBase}.js`);
|
|
29
29
|
if (!entry) return;
|
|
30
30
|
const jsFiles = new Set(names.filter((n) => n.endsWith(".js")));
|
|
31
|
-
const
|
|
31
|
+
const entryAsset = assets[entry];
|
|
32
|
+
if (!entryAsset) return;
|
|
33
|
+
const source = entryAsset.source().toString();
|
|
32
34
|
const special = /* @__PURE__ */ new Map();
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const uExpression = source.match(/\.u\s*=\s*(\w+)=>([^,;]+)/)?.[2];
|
|
36
|
+
if (uExpression) for (const m of uExpression.matchAll(/(\d+)\s*===\s*\w+\s*\?\s*"([^"]+)"/g)) {
|
|
37
|
+
const chunkId = m[1];
|
|
38
|
+
const chunkName = m[2];
|
|
39
|
+
if (chunkId && chunkName) special.set(chunkId, chunkName);
|
|
40
|
+
}
|
|
41
|
+
for (const pa of source.matchAll(/Promise\.all\(\[([^\]]*)\]\)/g)) {
|
|
42
|
+
const eagerList = pa[1];
|
|
43
|
+
if (!eagerList) continue;
|
|
44
|
+
for (const m of eagerList.matchAll(/(?:__webpack_require__|\w+)\.e\((\d+)\)/g)) {
|
|
45
|
+
const id = m[1];
|
|
46
|
+
if (!id) continue;
|
|
47
|
+
const chunkName = special.get(id);
|
|
48
|
+
const file = chunkName ? `${chunkName}.js` : `${id}.js`;
|
|
49
|
+
if (!jsFiles.has(file)) compilation.errors.push(/* @__PURE__ */ new Error(`[${this.name}] entry ${entry} eagerly loads chunk ${id} (${file}) but the compilation never emitted it — the built remote would fail at load time with "__webpack_modules__[r] is not a function".`));
|
|
50
|
+
}
|
|
39
51
|
}
|
|
40
52
|
});
|
|
41
53
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-completeness-plugin.cjs","names":["findHashedEntry"],"sources":["../../../src/build/rspack/chunk-completeness-plugin.ts"],"sourcesContent":["import type { Compiler, RspackPluginInstance } from \"@rspack/core\";\nimport { findHashedEntry } from \"../artifact-names\";\n\n/**\n * Fails the build when a container entry's eager chunk references\n * (`Promise.all([__webpack_require__.e(N), …])` in get factories) point at\n * chunk files the compilation never emits. Rspack 2.x splitChunks re-ids the\n * final chunk graph while the federation get-factory codegen can keep\n * pre-split ids — the emitted entry then 404s its own chunks at load time and\n * the failure surfaces downstream as `__webpack_modules__[r] is not a\n * function`. SplitChunks is disabled in the composition for exactly this\n * reason; this gate catches any regression loudly at build time instead.\n */\nexport class ChunkCompletenessPlugin implements RspackPluginInstance {\n name = \"ChunkCompletenessPlugin\";\n\n constructor(private entryBase = \"remoteEntry\") {}\n\n apply(compiler: Compiler) {\n compiler.hooks.thisCompilation.tap(this.name, (compilation) => {\n const webpack = (compiler as Compiler & { webpack?: any }).webpack;\n const stage = webpack?.Compilation?.PROCESS_ASSETS_STAGE_ADDITIONS ?? 1000;\n\n compilation.hooks.processAssets.tap({ name: this.name, stage }, (assets) => {\n const names = Object.keys(assets);\n const entry =\n findHashedEntry(names, this.entryBase) ?? names.find((n) => n === `${this.entryBase}.js`);\n if (!entry) return;\n\n const jsFiles = new Set(names.filter((n) => n.endsWith(\".js\")));\n const
|
|
1
|
+
{"version":3,"file":"chunk-completeness-plugin.cjs","names":["findHashedEntry"],"sources":["../../../src/build/rspack/chunk-completeness-plugin.ts"],"sourcesContent":["import type { Compiler, RspackPluginInstance } from \"@rspack/core\";\nimport { findHashedEntry } from \"../artifact-names\";\n\n/**\n * Fails the build when a container entry's eager chunk references\n * (`Promise.all([__webpack_require__.e(N), …])` in get factories) point at\n * chunk files the compilation never emits. Rspack 2.x splitChunks re-ids the\n * final chunk graph while the federation get-factory codegen can keep\n * pre-split ids — the emitted entry then 404s its own chunks at load time and\n * the failure surfaces downstream as `__webpack_modules__[r] is not a\n * function`. SplitChunks is disabled in the composition for exactly this\n * reason; this gate catches any regression loudly at build time instead.\n */\nexport class ChunkCompletenessPlugin implements RspackPluginInstance {\n name = \"ChunkCompletenessPlugin\";\n\n constructor(private entryBase = \"remoteEntry\") {}\n\n apply(compiler: Compiler) {\n compiler.hooks.thisCompilation.tap(this.name, (compilation) => {\n const webpack = (compiler as Compiler & { webpack?: any }).webpack;\n const stage = webpack?.Compilation?.PROCESS_ASSETS_STAGE_ADDITIONS ?? 1000;\n\n compilation.hooks.processAssets.tap({ name: this.name, stage }, (assets) => {\n const names = Object.keys(assets);\n const entry =\n findHashedEntry(names, this.entryBase) ?? names.find((n) => n === `${this.entryBase}.js`);\n if (!entry) return;\n\n const jsFiles = new Set(names.filter((n) => n.endsWith(\".js\")));\n const entryAsset = assets[entry];\n if (!entryAsset) return;\n const source = entryAsset.source().toString();\n\n const special = new Map<string, string>();\n const u = source.match(/\\.u\\s*=\\s*(\\w+)=>([^,;]+)/);\n const uExpression = u?.[2];\n if (uExpression) {\n for (const m of uExpression.matchAll(/(\\d+)\\s*===\\s*\\w+\\s*\\?\\s*\"([^\"]+)\"/g)) {\n const chunkId = m[1];\n const chunkName = m[2];\n if (chunkId && chunkName) special.set(chunkId, chunkName);\n }\n }\n\n for (const pa of source.matchAll(/Promise\\.all\\(\\[([^\\]]*)\\]\\)/g)) {\n const eagerList = pa[1];\n if (!eagerList) continue;\n for (const m of eagerList.matchAll(/(?:__webpack_require__|\\w+)\\.e\\((\\d+)\\)/g)) {\n const id = m[1];\n if (!id) continue;\n const chunkName = special.get(id);\n const file = chunkName ? `${chunkName}.js` : `${id}.js`;\n if (!jsFiles.has(file)) {\n compilation.errors.push(\n new Error(\n `[${this.name}] entry ${entry} eagerly loads chunk ${id} (${file}) but the compilation never emitted it — the built remote would fail at load time with \"__webpack_modules__[r] is not a function\".`,\n ),\n );\n }\n }\n }\n });\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,0BAAb,MAAqE;CAG/C;CAFpB,OAAO;CAEP,YAAY,AAAQ,YAAY,eAAe;EAA3B;CAA4B;CAEhD,MAAM,UAAoB;EACxB,SAAS,MAAM,gBAAgB,IAAI,KAAK,OAAO,gBAAgB;GAE7D,MAAM,QADW,SAA0C,SACpC,aAAa,kCAAkC;GAEtE,YAAY,MAAM,cAAc,IAAI;IAAE,MAAM,KAAK;IAAM;GAAM,IAAI,WAAW;IAC1E,MAAM,QAAQ,OAAO,KAAK,MAAM;IAChC,MAAM,QACJA,6CAAgB,OAAO,KAAK,SAAS,KAAK,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,UAAU,IAAI;IAC1F,IAAI,CAAC,OAAO;IAEZ,MAAM,UAAU,IAAI,IAAI,MAAM,QAAQ,MAAM,EAAE,SAAS,KAAK,CAAC,CAAC;IAC9D,MAAM,aAAa,OAAO;IAC1B,IAAI,CAAC,YAAY;IACjB,MAAM,SAAS,WAAW,OAAO,CAAC,CAAC,SAAS;IAE5C,MAAM,0BAAU,IAAI,IAAoB;IAExC,MAAM,cADI,OAAO,MAAM,2BACH,CAAC,GAAG;IACxB,IAAI,aACF,KAAK,MAAM,KAAK,YAAY,SAAS,qCAAqC,GAAG;KAC3E,MAAM,UAAU,EAAE;KAClB,MAAM,YAAY,EAAE;KACpB,IAAI,WAAW,WAAW,QAAQ,IAAI,SAAS,SAAS;IAC1D;IAGF,KAAK,MAAM,MAAM,OAAO,SAAS,+BAA+B,GAAG;KACjE,MAAM,YAAY,GAAG;KACrB,IAAI,CAAC,WAAW;KAChB,KAAK,MAAM,KAAK,UAAU,SAAS,0CAA0C,GAAG;MAC9E,MAAM,KAAK,EAAE;MACb,IAAI,CAAC,IAAI;MACT,MAAM,YAAY,QAAQ,IAAI,EAAE;MAChC,MAAM,OAAO,YAAY,GAAG,UAAU,OAAO,GAAG,GAAG;MACnD,IAAI,CAAC,QAAQ,IAAI,IAAI,GACnB,YAAY,OAAO,qBACjB,IAAI,MACF,IAAI,KAAK,KAAK,UAAU,MAAM,uBAAuB,GAAG,IAAI,KAAK,mIACnE,CACF;KAEJ;IACF;GACF,CAAC;EACH,CAAC;CACH;AACF"}
|
|
@@ -28,14 +28,26 @@ var ChunkCompletenessPlugin = class {
|
|
|
28
28
|
const entry = findHashedEntry(names, this.entryBase) ?? names.find((n) => n === `${this.entryBase}.js`);
|
|
29
29
|
if (!entry) return;
|
|
30
30
|
const jsFiles = new Set(names.filter((n) => n.endsWith(".js")));
|
|
31
|
-
const
|
|
31
|
+
const entryAsset = assets[entry];
|
|
32
|
+
if (!entryAsset) return;
|
|
33
|
+
const source = entryAsset.source().toString();
|
|
32
34
|
const special = /* @__PURE__ */ new Map();
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const uExpression = source.match(/\.u\s*=\s*(\w+)=>([^,;]+)/)?.[2];
|
|
36
|
+
if (uExpression) for (const m of uExpression.matchAll(/(\d+)\s*===\s*\w+\s*\?\s*"([^"]+)"/g)) {
|
|
37
|
+
const chunkId = m[1];
|
|
38
|
+
const chunkName = m[2];
|
|
39
|
+
if (chunkId && chunkName) special.set(chunkId, chunkName);
|
|
40
|
+
}
|
|
41
|
+
for (const pa of source.matchAll(/Promise\.all\(\[([^\]]*)\]\)/g)) {
|
|
42
|
+
const eagerList = pa[1];
|
|
43
|
+
if (!eagerList) continue;
|
|
44
|
+
for (const m of eagerList.matchAll(/(?:__webpack_require__|\w+)\.e\((\d+)\)/g)) {
|
|
45
|
+
const id = m[1];
|
|
46
|
+
if (!id) continue;
|
|
47
|
+
const chunkName = special.get(id);
|
|
48
|
+
const file = chunkName ? `${chunkName}.js` : `${id}.js`;
|
|
49
|
+
if (!jsFiles.has(file)) compilation.errors.push(/* @__PURE__ */ new Error(`[${this.name}] entry ${entry} eagerly loads chunk ${id} (${file}) but the compilation never emitted it — the built remote would fail at load time with "__webpack_modules__[r] is not a function".`));
|
|
50
|
+
}
|
|
39
51
|
}
|
|
40
52
|
});
|
|
41
53
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-completeness-plugin.mjs","names":[],"sources":["../../../src/build/rspack/chunk-completeness-plugin.ts"],"sourcesContent":["import type { Compiler, RspackPluginInstance } from \"@rspack/core\";\nimport { findHashedEntry } from \"../artifact-names\";\n\n/**\n * Fails the build when a container entry's eager chunk references\n * (`Promise.all([__webpack_require__.e(N), …])` in get factories) point at\n * chunk files the compilation never emits. Rspack 2.x splitChunks re-ids the\n * final chunk graph while the federation get-factory codegen can keep\n * pre-split ids — the emitted entry then 404s its own chunks at load time and\n * the failure surfaces downstream as `__webpack_modules__[r] is not a\n * function`. SplitChunks is disabled in the composition for exactly this\n * reason; this gate catches any regression loudly at build time instead.\n */\nexport class ChunkCompletenessPlugin implements RspackPluginInstance {\n name = \"ChunkCompletenessPlugin\";\n\n constructor(private entryBase = \"remoteEntry\") {}\n\n apply(compiler: Compiler) {\n compiler.hooks.thisCompilation.tap(this.name, (compilation) => {\n const webpack = (compiler as Compiler & { webpack?: any }).webpack;\n const stage = webpack?.Compilation?.PROCESS_ASSETS_STAGE_ADDITIONS ?? 1000;\n\n compilation.hooks.processAssets.tap({ name: this.name, stage }, (assets) => {\n const names = Object.keys(assets);\n const entry =\n findHashedEntry(names, this.entryBase) ?? names.find((n) => n === `${this.entryBase}.js`);\n if (!entry) return;\n\n const jsFiles = new Set(names.filter((n) => n.endsWith(\".js\")));\n const
|
|
1
|
+
{"version":3,"file":"chunk-completeness-plugin.mjs","names":[],"sources":["../../../src/build/rspack/chunk-completeness-plugin.ts"],"sourcesContent":["import type { Compiler, RspackPluginInstance } from \"@rspack/core\";\nimport { findHashedEntry } from \"../artifact-names\";\n\n/**\n * Fails the build when a container entry's eager chunk references\n * (`Promise.all([__webpack_require__.e(N), …])` in get factories) point at\n * chunk files the compilation never emits. Rspack 2.x splitChunks re-ids the\n * final chunk graph while the federation get-factory codegen can keep\n * pre-split ids — the emitted entry then 404s its own chunks at load time and\n * the failure surfaces downstream as `__webpack_modules__[r] is not a\n * function`. SplitChunks is disabled in the composition for exactly this\n * reason; this gate catches any regression loudly at build time instead.\n */\nexport class ChunkCompletenessPlugin implements RspackPluginInstance {\n name = \"ChunkCompletenessPlugin\";\n\n constructor(private entryBase = \"remoteEntry\") {}\n\n apply(compiler: Compiler) {\n compiler.hooks.thisCompilation.tap(this.name, (compilation) => {\n const webpack = (compiler as Compiler & { webpack?: any }).webpack;\n const stage = webpack?.Compilation?.PROCESS_ASSETS_STAGE_ADDITIONS ?? 1000;\n\n compilation.hooks.processAssets.tap({ name: this.name, stage }, (assets) => {\n const names = Object.keys(assets);\n const entry =\n findHashedEntry(names, this.entryBase) ?? names.find((n) => n === `${this.entryBase}.js`);\n if (!entry) return;\n\n const jsFiles = new Set(names.filter((n) => n.endsWith(\".js\")));\n const entryAsset = assets[entry];\n if (!entryAsset) return;\n const source = entryAsset.source().toString();\n\n const special = new Map<string, string>();\n const u = source.match(/\\.u\\s*=\\s*(\\w+)=>([^,;]+)/);\n const uExpression = u?.[2];\n if (uExpression) {\n for (const m of uExpression.matchAll(/(\\d+)\\s*===\\s*\\w+\\s*\\?\\s*\"([^\"]+)\"/g)) {\n const chunkId = m[1];\n const chunkName = m[2];\n if (chunkId && chunkName) special.set(chunkId, chunkName);\n }\n }\n\n for (const pa of source.matchAll(/Promise\\.all\\(\\[([^\\]]*)\\]\\)/g)) {\n const eagerList = pa[1];\n if (!eagerList) continue;\n for (const m of eagerList.matchAll(/(?:__webpack_require__|\\w+)\\.e\\((\\d+)\\)/g)) {\n const id = m[1];\n if (!id) continue;\n const chunkName = special.get(id);\n const file = chunkName ? `${chunkName}.js` : `${id}.js`;\n if (!jsFiles.has(file)) {\n compilation.errors.push(\n new Error(\n `[${this.name}] entry ${entry} eagerly loads chunk ${id} (${file}) but the compilation never emitted it — the built remote would fail at load time with \"__webpack_modules__[r] is not a function\".`,\n ),\n );\n }\n }\n }\n });\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,0BAAb,MAAqE;CAG/C;CAFpB,OAAO;CAEP,YAAY,AAAQ,YAAY,eAAe;EAA3B;CAA4B;CAEhD,MAAM,UAAoB;EACxB,SAAS,MAAM,gBAAgB,IAAI,KAAK,OAAO,gBAAgB;GAE7D,MAAM,QADW,SAA0C,SACpC,aAAa,kCAAkC;GAEtE,YAAY,MAAM,cAAc,IAAI;IAAE,MAAM,KAAK;IAAM;GAAM,IAAI,WAAW;IAC1E,MAAM,QAAQ,OAAO,KAAK,MAAM;IAChC,MAAM,QACJ,gBAAgB,OAAO,KAAK,SAAS,KAAK,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,UAAU,IAAI;IAC1F,IAAI,CAAC,OAAO;IAEZ,MAAM,UAAU,IAAI,IAAI,MAAM,QAAQ,MAAM,EAAE,SAAS,KAAK,CAAC,CAAC;IAC9D,MAAM,aAAa,OAAO;IAC1B,IAAI,CAAC,YAAY;IACjB,MAAM,SAAS,WAAW,OAAO,CAAC,CAAC,SAAS;IAE5C,MAAM,0BAAU,IAAI,IAAoB;IAExC,MAAM,cADI,OAAO,MAAM,2BACH,CAAC,GAAG;IACxB,IAAI,aACF,KAAK,MAAM,KAAK,YAAY,SAAS,qCAAqC,GAAG;KAC3E,MAAM,UAAU,EAAE;KAClB,MAAM,YAAY,EAAE;KACpB,IAAI,WAAW,WAAW,QAAQ,IAAI,SAAS,SAAS;IAC1D;IAGF,KAAK,MAAM,MAAM,OAAO,SAAS,+BAA+B,GAAG;KACjE,MAAM,YAAY,GAAG;KACrB,IAAI,CAAC,WAAW;KAChB,KAAK,MAAM,KAAK,UAAU,SAAS,0CAA0C,GAAG;MAC9E,MAAM,KAAK,EAAE;MACb,IAAI,CAAC,IAAI;MACT,MAAM,YAAY,QAAQ,IAAI,EAAE;MAChC,MAAM,OAAO,YAAY,GAAG,UAAU,OAAO,GAAG,GAAG;MACnD,IAAI,CAAC,QAAQ,IAAI,IAAI,GACnB,YAAY,OAAO,qBACjB,IAAI,MACF,IAAI,KAAK,KAAK,UAAU,MAAM,uBAAuB,GAAG,IAAI,KAAK,mIACnE,CACF;KAEJ;IACF;GACF,CAAC;EACH,CAAC;CACH;AACF"}
|
|
@@ -3,7 +3,7 @@ const require_shared_deps_spec = require('../shared-deps-spec.cjs');
|
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
|
|
5
5
|
//#region src/runtime/mf-config.ts
|
|
6
|
-
const PLUGIN_VERSION = "3.0.0-rc.
|
|
6
|
+
const PLUGIN_VERSION = "3.0.0-rc.7";
|
|
7
7
|
const MF_CORE_SHARED_DEPS = require_shared_deps_spec.buildMfCoreSharedDependencies({ ownVersion: PLUGIN_VERSION });
|
|
8
8
|
|
|
9
9
|
//#endregion
|
|
@@ -2,7 +2,7 @@ import { buildMfCoreSharedDependencies } from "../shared-deps-spec.mjs";
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
|
|
4
4
|
//#region src/runtime/mf-config.ts
|
|
5
|
-
const PLUGIN_VERSION = "3.0.0-rc.
|
|
5
|
+
const PLUGIN_VERSION = "3.0.0-rc.7";
|
|
6
6
|
const MF_CORE_SHARED_DEPS = buildMfCoreSharedDependencies({ ownVersion: PLUGIN_VERSION });
|
|
7
7
|
|
|
8
8
|
//#endregion
|
package/package.json
CHANGED
|
@@ -60,7 +60,8 @@ import { RPCLink } from "@orpc/client/fetch";
|
|
|
60
60
|
const HOST = "https://dev.everything.dev";
|
|
61
61
|
|
|
62
62
|
const link = new RPCLink({
|
|
63
|
-
|
|
63
|
+
origin: HOST,
|
|
64
|
+
url: "/api/rpc",
|
|
64
65
|
fetch: globalThis.fetch,
|
|
65
66
|
headers: {
|
|
66
67
|
"x-api-key": process.env.EVERYTHING_DEV_API_KEY!,
|
|
@@ -70,6 +71,8 @@ const link = new RPCLink({
|
|
|
70
71
|
const client = createORPCClient(link);
|
|
71
72
|
```
|
|
72
73
|
|
|
74
|
+
`RPCLink` takes `origin` plus a relative `url` — its `url` option is typed as `StandardUrl` (`/${string}`), so a concatenated absolute URL like `url: \`${HOST}/api/rpc\`` fails typechecking at the link boundary.
|
|
75
|
+
|
|
73
76
|
### URL Structure
|
|
74
77
|
|
|
75
78
|
oRPC's RPC protocol encodes the procedure path in the URL segment after the RPC base:
|
|
@@ -114,7 +117,8 @@ Two credential mechanisms:
|
|
|
114
117
|
|
|
115
118
|
```ts
|
|
116
119
|
const link = new RPCLink({
|
|
117
|
-
|
|
120
|
+
origin: HOST,
|
|
121
|
+
url: "/api/rpc",
|
|
118
122
|
fetch: globalThis.fetch,
|
|
119
123
|
headers: { "x-api-key": "edk_xxxxxxxxxxxxxxx" },
|
|
120
124
|
});
|
|
@@ -124,7 +128,8 @@ const link = new RPCLink({
|
|
|
124
128
|
|
|
125
129
|
```ts
|
|
126
130
|
const link = new RPCLink({
|
|
127
|
-
|
|
131
|
+
origin: HOST,
|
|
132
|
+
url: "/api/rpc",
|
|
128
133
|
fetch: (url, options) => fetch(url, { ...options, credentials: "include" }),
|
|
129
134
|
});
|
|
130
135
|
```
|
|
@@ -268,7 +273,8 @@ Pass the key in the `x-api-key` header:
|
|
|
268
273
|
|
|
269
274
|
```ts
|
|
270
275
|
const link = new RPCLink({
|
|
271
|
-
|
|
276
|
+
origin: HOST,
|
|
277
|
+
url: "/api/rpc",
|
|
272
278
|
fetch: globalThis.fetch,
|
|
273
279
|
headers: { "x-api-key": "edk_xxxxxxxxxxxxxxx" },
|
|
274
280
|
});
|
|
@@ -225,6 +225,7 @@ export default defineConfig({
|
|
|
225
225
|
- Forgetting `vite-tsconfig-paths` plugin — package subpath imports like `every-plugin/errors` won't resolve
|
|
226
226
|
- Omitting the `registry` object when calling `createPluginRuntime(...)` — the runtime requires explicit plugin entries
|
|
227
227
|
- Testing only happy paths — always test error channels (Effect failures, ORPCError throws)
|
|
228
|
+
- Asserting errors by message from a client call — oRPC v2 does not transport undefined-error messages, so message-based assertions are brittle. Match on `error.code` instead: `await expect(client.getById({ id: "x" })).rejects.toMatchObject({ code: "NOT_FOUND" })`.
|
|
228
229
|
|
|
229
230
|
## The tasks you will actually be given
|
|
230
231
|
|
|
@@ -28,20 +28,29 @@ export class ChunkCompletenessPlugin implements RspackPluginInstance {
|
|
|
28
28
|
if (!entry) return;
|
|
29
29
|
|
|
30
30
|
const jsFiles = new Set(names.filter((n) => n.endsWith(".js")));
|
|
31
|
-
const
|
|
31
|
+
const entryAsset = assets[entry];
|
|
32
|
+
if (!entryAsset) return;
|
|
33
|
+
const source = entryAsset.source().toString();
|
|
32
34
|
|
|
33
35
|
const special = new Map<string, string>();
|
|
34
36
|
const u = source.match(/\.u\s*=\s*(\w+)=>([^,;]+)/);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
const uExpression = u?.[2];
|
|
38
|
+
if (uExpression) {
|
|
39
|
+
for (const m of uExpression.matchAll(/(\d+)\s*===\s*\w+\s*\?\s*"([^"]+)"/g)) {
|
|
40
|
+
const chunkId = m[1];
|
|
41
|
+
const chunkName = m[2];
|
|
42
|
+
if (chunkId && chunkName) special.set(chunkId, chunkName);
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
for (const pa of source.matchAll(/Promise\.all\(\[([^\]]*)\]\)/g)) {
|
|
42
|
-
|
|
47
|
+
const eagerList = pa[1];
|
|
48
|
+
if (!eagerList) continue;
|
|
49
|
+
for (const m of eagerList.matchAll(/(?:__webpack_require__|\w+)\.e\((\d+)\)/g)) {
|
|
43
50
|
const id = m[1];
|
|
44
|
-
|
|
51
|
+
if (!id) continue;
|
|
52
|
+
const chunkName = special.get(id);
|
|
53
|
+
const file = chunkName ? `${chunkName}.js` : `${id}.js`;
|
|
45
54
|
if (!jsFiles.has(file)) {
|
|
46
55
|
compilation.errors.push(
|
|
47
56
|
new Error(
|