@bleedingdev/modern-js-app-tools 3.5.0-ultramodern.101 → 3.5.0-ultramodern.103
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/cjs/builder/generator/getBuilderEnvironments.js +73 -11
- package/dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/index.js +1 -1
- package/dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.js +94 -18
- package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
- package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
- package/dist/cjs/ultramodern-release-envelope/framework-output.js +109 -57
- package/dist/esm/builder/generator/getBuilderEnvironments.mjs +63 -10
- package/dist/esm/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +1 -1
- package/dist/esm/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.mjs +93 -18
- package/dist/esm/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
- package/dist/esm/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
- package/dist/esm/ultramodern-release-envelope/framework-output.mjs +107 -58
- package/dist/esm-node/builder/generator/getBuilderEnvironments.mjs +63 -10
- package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +1 -1
- package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.mjs +93 -18
- package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
- package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
- package/dist/esm-node/ultramodern-release-envelope/framework-output.mjs +107 -58
- package/dist/types/builder/generator/getBuilderEnvironments.d.ts +29 -0
- package/dist/types/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.d.ts +1 -1
- package/dist/types/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.d.mts +1 -1
- package/dist/types/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +13 -0
- package/dist/types/ultramodern-release-envelope/framework-output.d.ts +1 -0
- package/docs/configure/app/bff/effect.md +13 -15
- package/docs/configure/app/server/rsc.md +8 -12
- package/docs/guides/basic-features/render/rsc.md +5 -14
- package/docs/guides/get-started/quick-start.md +1 -1
- package/docs/guides/get-started/ultramodern.md +19 -7
- package/docs/guides/get-started/upgrade.md +5 -10
- package/docs/llms.txt +1 -1
- package/package.json +12 -12
|
@@ -10,6 +10,8 @@ import { dirname as __rspack_dirname } from "node:path";
|
|
|
10
10
|
var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
11
11
|
const BFF_EFFECT_WORKER_ENTRY_NAME = '__modern_bff_effect';
|
|
12
12
|
const BFF_EFFECT_WORKER_RUNTIME_QUERY = 'modern-bff-runtime';
|
|
13
|
+
const MF_SSR_DATA_FETCH_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-inject-data-fetch-function-plugin';
|
|
14
|
+
const MF_SSR_DEV_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-dev-plugin';
|
|
13
15
|
const JS_OR_TS_EXTS = [
|
|
14
16
|
'.js',
|
|
15
17
|
'.jsx',
|
|
@@ -90,6 +92,64 @@ function getCloudflareWorkerNodeExternals() {
|
|
|
90
92
|
];
|
|
91
93
|
}));
|
|
92
94
|
}
|
|
95
|
+
const reserveWorkerChunkName = (baseName, reservedOutputNames)=>{
|
|
96
|
+
let name = baseName;
|
|
97
|
+
while(reservedOutputNames.has(normalizeWorkerOutputName(name)))name = `${name}_`;
|
|
98
|
+
return name;
|
|
99
|
+
};
|
|
100
|
+
const normalizeWorkerOutputName = (name)=>node_path.posix.normalize(name.replace(/\\/gu, '/')).toLowerCase();
|
|
101
|
+
function getCloudflareWorkerRspackConfig(workerEntryNames) {
|
|
102
|
+
const entryNames = [
|
|
103
|
+
...workerEntryNames
|
|
104
|
+
];
|
|
105
|
+
for (const entryName of entryNames){
|
|
106
|
+
const slashName = entryName.replace(/\\/gu, '/');
|
|
107
|
+
const normalizedName = node_path.posix.normalize(slashName);
|
|
108
|
+
if (entryName !== slashName || normalizedName !== slashName || '.' === normalizedName || normalizedName.startsWith('../') || node_path.posix.isAbsolute(normalizedName) || node_path.win32.isAbsolute(slashName) || /^[A-Za-z]:/u.test(slashName)) throw new Error(`Cloudflare worker entry name "${entryName}" must be a canonical relative output path without dot segments or backslashes.`);
|
|
109
|
+
}
|
|
110
|
+
const reservedNames = new Set(entryNames.map(normalizeWorkerOutputName));
|
|
111
|
+
const runtimeName = reserveWorkerChunkName('__modern_worker_runtime', reservedNames);
|
|
112
|
+
reservedNames.add(normalizeWorkerOutputName(runtimeName));
|
|
113
|
+
const sharedName = reserveWorkerChunkName('__modern_worker_shared', reservedNames);
|
|
114
|
+
return {
|
|
115
|
+
experiments: {
|
|
116
|
+
outputModule: true
|
|
117
|
+
},
|
|
118
|
+
externals: getCloudflareWorkerNodeExternals(),
|
|
119
|
+
externalsType: 'module-import',
|
|
120
|
+
module: {
|
|
121
|
+
parser: {
|
|
122
|
+
javascript: {
|
|
123
|
+
dynamicImportMode: 'eager'
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
optimization: {
|
|
128
|
+
runtimeChunk: {
|
|
129
|
+
name: runtimeName
|
|
130
|
+
},
|
|
131
|
+
splitChunks: {
|
|
132
|
+
chunks: 'all',
|
|
133
|
+
minSize: 0,
|
|
134
|
+
name: sharedName
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function applyCloudflareWorkerRspackConfig(chain, workerEntryNames) {
|
|
140
|
+
const config = getCloudflareWorkerRspackConfig(workerEntryNames);
|
|
141
|
+
chain.experiments(config.experiments);
|
|
142
|
+
chain.externals(config.externals);
|
|
143
|
+
chain.externalsType(config.externalsType);
|
|
144
|
+
chain.module.parser.merge(config.module.parser);
|
|
145
|
+
chain.optimization.runtimeChunk(config.optimization.runtimeChunk);
|
|
146
|
+
chain.optimization.splitChunks(config.optimization.splitChunks);
|
|
147
|
+
}
|
|
148
|
+
function applyCloudflareWorkerMfRuntimeBoundary(chain) {
|
|
149
|
+
chain.plugins.delete('plugin-module-federation');
|
|
150
|
+
chain.resolve.alias.set(`${MF_SSR_DATA_FETCH_RUNTIME_PLUGIN}$`, getCloudflareWorkerCompatFile('cloudflare-worker-mf-ssr-runtime-plugin.mjs'));
|
|
151
|
+
chain.resolve.alias.set(`${MF_SSR_DEV_RUNTIME_PLUGIN}$`, getCloudflareWorkerCompatFile('cloudflare-worker-mf-ssr-runtime-plugin.mjs'));
|
|
152
|
+
}
|
|
93
153
|
function getEffectBffEntry(normalizedConfig, appContext) {
|
|
94
154
|
if (!normalizedConfig.bff || 'hono' === normalizedConfig.bff.runtimeFramework) return;
|
|
95
155
|
const configuredEntry = normalizedConfig.bff.effect?.entry;
|
|
@@ -248,17 +308,10 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
|
|
|
248
308
|
htmlPlugin: false,
|
|
249
309
|
...useCloudflareModuleWorker ? {
|
|
250
310
|
bundlerChain: (chain)=>{
|
|
251
|
-
chain.
|
|
252
|
-
experiments: {
|
|
253
|
-
outputModule: true
|
|
254
|
-
},
|
|
255
|
-
externals: getCloudflareWorkerNodeExternals(),
|
|
256
|
-
externalsType: 'module-import'
|
|
257
|
-
});
|
|
311
|
+
applyCloudflareWorkerRspackConfig(chain, Object.keys(workerEntries));
|
|
258
312
|
chain.output.module(true).library({
|
|
259
313
|
type: 'module'
|
|
260
314
|
}).publicPath('/').chunkFormat('module').chunkLoading('import').workerChunkLoading('import');
|
|
261
|
-
chain.optimization.usedExports(false).providedExports(true).innerGraph(false).sideEffects(false);
|
|
262
315
|
for (const condition of [
|
|
263
316
|
'workerd',
|
|
264
317
|
'worker',
|
|
@@ -268,7 +321,7 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
|
|
|
268
321
|
'require',
|
|
269
322
|
'module'
|
|
270
323
|
])chain.resolve.conditionNames.add(condition);
|
|
271
|
-
chain
|
|
324
|
+
applyCloudflareWorkerMfRuntimeBoundary(chain);
|
|
272
325
|
if (tanstackRouterSsrServerFile) {
|
|
273
326
|
chain.resolve.alias.set('@tanstack/router-core/ssr/server$', tanstackRouterSsrServerFile);
|
|
274
327
|
chain.resolve.alias.set('@tanstack/router-core/ssr/server', tanstackRouterSsrServerFile);
|
|
@@ -309,4 +362,4 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
|
|
|
309
362
|
builderConfig: tempBuilderConfig
|
|
310
363
|
};
|
|
311
364
|
}
|
|
312
|
-
export { getBuilderEnvironments };
|
|
365
|
+
export { applyCloudflareWorkerMfRuntimeBoundary, applyCloudflareWorkerRspackConfig, getBuilderEnvironments, getCloudflareWorkerRspackConfig };
|
|
@@ -117,7 +117,7 @@ const verifyCloudflareOutput = async (options)=>{
|
|
|
117
117
|
path: publicPath
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
|
-
if (false !== options.importWorker && await pathExists(outputPlan.paths.workerEntry)) await verifyWorkerImport(issues, outputPlan.paths.workerEntry);
|
|
120
|
+
if (false !== options.importWorker && await pathExists(outputPlan.paths.workerEntry)) await verifyWorkerImport(issues, outputPlan.paths.workerEntry, manifest);
|
|
121
121
|
return {
|
|
122
122
|
ok: 0 === issues.length,
|
|
123
123
|
issues
|
package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.mjs
CHANGED
|
@@ -2,7 +2,9 @@ import "node:module";
|
|
|
2
2
|
import promises from "node:fs/promises";
|
|
3
3
|
import node_path from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { isDeepStrictEqual } from "node:util";
|
|
5
6
|
import { parse } from "@babel/parser";
|
|
7
|
+
import traverse from "@babel/traverse";
|
|
6
8
|
import { CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_NODE_BUILTINS } from "../cloudflare-output-contract.mjs";
|
|
7
9
|
import { addIssue } from "./issues.mjs";
|
|
8
10
|
const getReferencedRouteWorkers = (manifest)=>Array.isArray(manifest?.routeSpec?.routes) ? manifest.routeSpec.routes.map((route)=>'string' == typeof route?.worker && route.worker.length > 0 ? route.worker : void 0).filter((worker)=>'string' == typeof worker) : [];
|
|
@@ -46,6 +48,7 @@ const getNodeName = (node)=>{
|
|
|
46
48
|
if (!isAstNode(node)) return;
|
|
47
49
|
return 'Identifier' === node.type && 'string' == typeof node.name ? node.name : 'StringLiteral' === node.type && 'string' == typeof node.value ? node.value : void 0;
|
|
48
50
|
};
|
|
51
|
+
const getStringLiteralValue = (node)=>isAstNode(node) && 'StringLiteral' === node.type && 'string' == typeof node.value ? node.value : void 0;
|
|
49
52
|
const collectBindingNames = (node, names)=>{
|
|
50
53
|
if (!isAstNode(node)) return;
|
|
51
54
|
const name = getNodeName(node);
|
|
@@ -55,7 +58,11 @@ const collectBindingNames = (node, names)=>{
|
|
|
55
58
|
} else if ('ArrayPattern' === node.type && Array.isArray(node.elements)) for (const element of node.elements)collectBindingNames(element, names);
|
|
56
59
|
else if ('AssignmentPattern' === node.type || 'RestElement' === node.type) collectBindingNames('AssignmentPattern' === node.type ? node.left : node.argument, names);
|
|
57
60
|
};
|
|
58
|
-
const getMemberPropertyName = (node)=>
|
|
61
|
+
const getMemberPropertyName = (node)=>{
|
|
62
|
+
if ('MemberExpression' !== node.type) return;
|
|
63
|
+
return true === node.computed ? getStringLiteralValue(node.property) : getNodeName(node.property);
|
|
64
|
+
};
|
|
65
|
+
const isAmbientModuleRequire = (node, modulePath)=>isAstNode(node) && 'MemberExpression' === node.type && isAstNode(node.object) && 'Identifier' === node.object.type && 'module' === node.object.name && void 0 === modulePath.scope.getBinding('module') && 'require' === getMemberPropertyName(node);
|
|
59
66
|
const isModuleExports = (node)=>isAstNode(node) && 'MemberExpression' === node.type && isAstNode(node.object) && 'Identifier' === node.object.type && 'module' === node.object.name && 'exports' === getMemberPropertyName(node);
|
|
60
67
|
const collectCommonJsExports = (statement, exports)=>{
|
|
61
68
|
if ('ExpressionStatement' !== statement.type || !isAstNode(statement.expression) || 'AssignmentExpression' !== statement.expression.type) return;
|
|
@@ -90,19 +97,31 @@ const collectEsmExports = (statement, exports)=>{
|
|
|
90
97
|
}
|
|
91
98
|
}
|
|
92
99
|
};
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
const getStaticImport = (modulePath)=>{
|
|
101
|
+
const node = modulePath.node;
|
|
102
|
+
if (('ImportDeclaration' === node.type || 'ExportNamedDeclaration' === node.type || 'ExportAllDeclaration' === node.type) && isAstNode(node.source)) return getStringLiteralValue(node.source);
|
|
103
|
+
if ('ImportExpression' === node.type && isAstNode(node.source)) return getStringLiteralValue(node.source);
|
|
104
|
+
if ('CallExpression' === node.type && Array.isArray(node.arguments) && 1 === node.arguments.length && isAstNode(node.callee) && ('Identifier' === node.callee.type && 'require' === node.callee.name && void 0 === modulePath.scope.getBinding('require') || isAmbientModuleRequire(node.callee, modulePath) || 'Import' === node.callee.type)) return getStringLiteralValue(node.arguments[0]);
|
|
105
|
+
};
|
|
106
|
+
const isAmbientLoaderWrite = (modulePath)=>{
|
|
107
|
+
let targetPath = modulePath;
|
|
108
|
+
while(targetPath.parentPath){
|
|
109
|
+
const parentPath = targetPath.parentPath;
|
|
110
|
+
if (parentPath.isAssignmentExpression()) return 'left' === targetPath.key;
|
|
111
|
+
if (parentPath.isUpdateExpression()) return 'argument' === targetPath.key;
|
|
112
|
+
if (parentPath.isForInStatement() || parentPath.isForOfStatement()) return 'left' === targetPath.key;
|
|
113
|
+
if (parentPath.isObjectProperty()) {
|
|
114
|
+
if ('value' !== targetPath.key) return false;
|
|
115
|
+
targetPath = parentPath;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (parentPath.isObjectPattern() || parentPath.isArrayPattern() || parentPath.isRestElement() || parentPath.isAssignmentPattern()) {
|
|
119
|
+
targetPath = parentPath;
|
|
120
|
+
continue;
|
|
99
121
|
}
|
|
122
|
+
break;
|
|
100
123
|
}
|
|
101
|
-
|
|
102
|
-
const getStaticImport = (node)=>{
|
|
103
|
-
if (('ImportDeclaration' === node.type || 'ExportNamedDeclaration' === node.type || 'ExportAllDeclaration' === node.type) && isAstNode(node.source)) return getNodeName(node.source);
|
|
104
|
-
if ('ImportExpression' === node.type && isAstNode(node.source)) return getNodeName(node.source);
|
|
105
|
-
if ('CallExpression' === node.type && Array.isArray(node.arguments) && 1 === node.arguments.length && isAstNode(node.callee) && ('Identifier' === node.callee.type && 'require' === node.callee.name || 'Import' === node.callee.type)) return getNodeName(node.arguments[0]);
|
|
124
|
+
return false;
|
|
106
125
|
};
|
|
107
126
|
const analyzeWorkerModule = (source)=>{
|
|
108
127
|
const ast = parse(source, {
|
|
@@ -110,17 +129,49 @@ const analyzeWorkerModule = (source)=>{
|
|
|
110
129
|
});
|
|
111
130
|
const exports = new Set();
|
|
112
131
|
const imports = new Set();
|
|
132
|
+
let unsafeCommonJsLoaderUsage = false;
|
|
133
|
+
let unsafeDynamicImport = false;
|
|
113
134
|
for (const statement of ast.program.body){
|
|
114
135
|
collectEsmExports(statement, exports);
|
|
115
136
|
collectCommonJsExports(statement, exports);
|
|
116
137
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
138
|
+
traverse(ast, {
|
|
139
|
+
enter (modulePath) {
|
|
140
|
+
const node = modulePath.node;
|
|
141
|
+
if (('ImportExpression' === node.type || 'CallExpression' === node.type && isAstNode(node.callee) && 'Import' === node.callee.type) && void 0 === getStaticImport(modulePath)) unsafeDynamicImport = true;
|
|
142
|
+
if (modulePath.isReferencedIdentifier({
|
|
143
|
+
name: 'require'
|
|
144
|
+
}) && void 0 === modulePath.scope.getBinding('require')) {
|
|
145
|
+
const parentPath = modulePath.parentPath;
|
|
146
|
+
const isStaticRequireCall = parentPath?.isCallExpression() && 'callee' === modulePath.key && void 0 !== getStaticImport(parentPath);
|
|
147
|
+
const isAvailabilityCheck = parentPath?.isUnaryExpression({
|
|
148
|
+
operator: 'typeof'
|
|
149
|
+
});
|
|
150
|
+
if (!isStaticRequireCall && !isAvailabilityCheck) unsafeCommonJsLoaderUsage = true;
|
|
151
|
+
}
|
|
152
|
+
if ('Identifier' === node.type && isAmbientLoaderWrite(modulePath) && ('require' === node.name || 'module' === node.name) && void 0 === modulePath.scope.getBinding(node.name)) unsafeCommonJsLoaderUsage = true;
|
|
153
|
+
if (modulePath.isReferencedIdentifier({
|
|
154
|
+
name: 'module'
|
|
155
|
+
}) && void 0 === modulePath.scope.getBinding('module')) {
|
|
156
|
+
const parentPath = modulePath.parentPath;
|
|
157
|
+
const isExportsAccess = null !== parentPath && isModuleExports(parentPath.node);
|
|
158
|
+
const isStaticModuleRequireCall = null !== parentPath && isAmbientModuleRequire(parentPath.node, parentPath) && parentPath.parentPath?.isCallExpression() === true && 'callee' === parentPath.key && void 0 !== getStaticImport(parentPath.parentPath);
|
|
159
|
+
if (!isExportsAccess && !isStaticModuleRequireCall) unsafeCommonJsLoaderUsage = true;
|
|
160
|
+
}
|
|
161
|
+
if (isAmbientModuleRequire(node, modulePath)) {
|
|
162
|
+
const parentPath = modulePath.parentPath;
|
|
163
|
+
const isStaticRequireCall = parentPath?.isCallExpression() && 'callee' === modulePath.key && void 0 !== getStaticImport(parentPath);
|
|
164
|
+
if (!isStaticRequireCall) unsafeCommonJsLoaderUsage = true;
|
|
165
|
+
}
|
|
166
|
+
const specifier = getStaticImport(modulePath);
|
|
167
|
+
if (void 0 !== specifier) imports.add(specifier);
|
|
168
|
+
}
|
|
120
169
|
});
|
|
121
170
|
return {
|
|
122
171
|
exports,
|
|
123
|
-
imports
|
|
172
|
+
imports,
|
|
173
|
+
unsafeCommonJsLoaderUsage,
|
|
174
|
+
unsafeDynamicImport
|
|
124
175
|
};
|
|
125
176
|
};
|
|
126
177
|
const getPackageName = (specifier)=>specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0];
|
|
@@ -171,7 +222,25 @@ const verifyWorkerModuleClosure = async (issues, entryPath, entrySource, contrac
|
|
|
171
222
|
return;
|
|
172
223
|
}
|
|
173
224
|
if (isEntry) entryAnalysis = analysis;
|
|
225
|
+
if (analysis.unsafeCommonJsLoaderUsage) addIssue(issues, {
|
|
226
|
+
code: 'invalid-worker-bundle',
|
|
227
|
+
message: 'Cloudflare worker bundles must use exactly one string-literal specifier in ambient CommonJS loader calls and must not pass or alias the loader.',
|
|
228
|
+
path: modulePath
|
|
229
|
+
});
|
|
230
|
+
if (analysis.unsafeDynamicImport) addIssue(issues, {
|
|
231
|
+
code: 'invalid-worker-bundle',
|
|
232
|
+
message: 'Cloudflare worker bundles must not contain non-static dynamic module imports.',
|
|
233
|
+
path: modulePath
|
|
234
|
+
});
|
|
174
235
|
for (const specifier of analysis.imports){
|
|
236
|
+
if (0 === specifier.length) {
|
|
237
|
+
addIssue(issues, {
|
|
238
|
+
code: 'invalid-worker-bundle',
|
|
239
|
+
message: 'Cloudflare worker bundle module specifiers must not be empty.',
|
|
240
|
+
path: modulePath
|
|
241
|
+
});
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
175
244
|
if (!specifier.startsWith('.') && !node_path.isAbsolute(specifier)) {
|
|
176
245
|
if (CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS.has(specifier)) continue;
|
|
177
246
|
if (specifier.startsWith('node:')) {
|
|
@@ -220,14 +289,20 @@ const verifyWorkerBundleReferences = async (issues, worker, source, contract)=>{
|
|
|
220
289
|
path: worker.path
|
|
221
290
|
});
|
|
222
291
|
};
|
|
223
|
-
const verifyWorkerImport = async (issues, entryPath)=>{
|
|
292
|
+
const verifyWorkerImport = async (issues, entryPath, expectedManifest)=>{
|
|
224
293
|
try {
|
|
225
|
-
const
|
|
294
|
+
const workerModule = await import(`${pathToFileURL(entryPath).href}?t=${Date.now()}`);
|
|
295
|
+
const worker = workerModule.default;
|
|
226
296
|
if (!worker || 'function' != typeof worker.fetch) addIssue(issues, {
|
|
227
297
|
code: 'worker-import-failed',
|
|
228
298
|
message: 'Cloudflare server entry must default-export a Worker with fetch.',
|
|
229
299
|
path: entryPath
|
|
230
300
|
});
|
|
301
|
+
if (void 0 !== expectedManifest && !isDeepStrictEqual(workerModule.modernWorkerManifest, expectedManifest)) addIssue(issues, {
|
|
302
|
+
code: 'worker-import-failed',
|
|
303
|
+
message: 'Cloudflare server entry runtime manifest must exactly match modern-worker-manifest.json.',
|
|
304
|
+
path: entryPath
|
|
305
|
+
});
|
|
231
306
|
} catch (error) {
|
|
232
307
|
addIssue(issues, {
|
|
233
308
|
code: 'worker-import-failed',
|
package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const ASSETS_BINDING = 'ASSETS';
|
|
2
2
|
const MODERN_WORKER_MANIFEST = p_workerManifest;
|
|
3
|
+
export const modernWorkerManifest = MODERN_WORKER_MANIFEST;
|
|
3
4
|
const WORKER_MODULE_LOADERS = p_workerModuleLoaders;
|
|
4
5
|
const workerModulePromises = new Map();
|
|
5
6
|
const effectBffDispatcherPromises = new Map();
|
package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workerd cannot initialize Module Federation's Node-oriented SSR data-fetch
|
|
3
|
+
* runtime. Cloudflare workers do not load native MF remotes, so retain the
|
|
4
|
+
* runtime-plugin contract without installing its server data-fetch hooks.
|
|
5
|
+
*/
|
|
6
|
+
export const injectDataFetchFunctionPlugin = () => ({
|
|
7
|
+
name: '@module-federation/inject-data-fetch-function-plugin',
|
|
8
|
+
setup() {},
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const mfSSRDevPlugin = () => ({
|
|
12
|
+
name: '@module-federation/modern-js-v3',
|
|
13
|
+
setup() {},
|
|
14
|
+
});
|
|
@@ -1,43 +1,16 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
import promises from "node:fs/promises";
|
|
3
4
|
import node_path from "node:path";
|
|
4
|
-
import { parse } from "@babel/parser";
|
|
5
5
|
import { BACKEND_FEDERATION_MANIFEST_FILE, BACKEND_FEDERATION_REMOTE_ENTRY_FILE, ULTRAMODERN_BUILD_ARTIFACT_FILE, isUltramodernBuildArtifact } from "@modern-js/utils/universal";
|
|
6
6
|
import { canonicalSerializeMicroVerticalReleaseEnvelope, createMicroVerticalReleaseEnvelope, verifyMicroVerticalReleaseEnvelope } from "./index.mjs";
|
|
7
7
|
const MICROVERTICAL_RELEASE_ENVELOPE_PATH = 'release/microvertical-release-envelope.json';
|
|
8
|
+
const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH = 'release/microvertical-release-identity-carriers.json';
|
|
9
|
+
const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND = 'ultramodern-release-identity-carriers';
|
|
10
|
+
const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION = 1;
|
|
8
11
|
const COMPILED_MODULE_PATTERN = /\.(?:c|m)?js$/u;
|
|
9
12
|
const EFFECT_BFF_WORKER_PATTERN = /^worker\/__modern_bff_effect\.(?:c|m)?js$/u;
|
|
10
13
|
const isRecord = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
11
|
-
const isAstNode = (value)=>isRecord(value) && 'string' == typeof value.type;
|
|
12
|
-
const visitAst = (node, visitor)=>{
|
|
13
|
-
visitor(node);
|
|
14
|
-
for (const value of Object.values(node))if (isAstNode(value)) visitAst(value, visitor);
|
|
15
|
-
else if (Array.isArray(value)) {
|
|
16
|
-
for (const item of value)if (isAstNode(item)) visitAst(item, visitor);
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
const compiledModuleIdentityValues = (source)=>{
|
|
20
|
-
const values = new Set();
|
|
21
|
-
const ast = parse(source, {
|
|
22
|
-
sourceType: 'unambiguous'
|
|
23
|
-
});
|
|
24
|
-
visitAst(ast.program, (node)=>{
|
|
25
|
-
if ('StringLiteral' === node.type && 'string' == typeof node.value) values.add(node.value);
|
|
26
|
-
else if ('TemplateElement' === node.type && isRecord(node.value) && 'string' == typeof node.value.cooked) values.add(node.value.cooked);
|
|
27
|
-
});
|
|
28
|
-
return values;
|
|
29
|
-
};
|
|
30
|
-
const assertEveryCompiledIdentityCarrier = async (distDirectory, logicalPaths, identity, surface)=>{
|
|
31
|
-
const compiledLogicalPaths = logicalPaths.filter((pathname)=>COMPILED_MODULE_PATTERN.test(pathname));
|
|
32
|
-
if (0 === compiledLogicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no compiled execution module carrying release identity.`);
|
|
33
|
-
for (const logicalPath of compiledLogicalPaths){
|
|
34
|
-
const source = await promises.readFile(node_path.join(distDirectory, logicalPath), {
|
|
35
|
-
encoding: 'utf8'
|
|
36
|
-
});
|
|
37
|
-
const values = compiledModuleIdentityValues(source);
|
|
38
|
-
if (!values.has(identity.buildMarker) || !values.has(identity.sourceRevision) || !values.has(identity.releaseVersion)) throw new Error(`[ultramodern-release-envelope] ${surface} execution module ${logicalPath} does not carry exact buildMarker ${identity.buildMarker}, sourceRevision ${identity.sourceRevision}, and releaseVersion ${identity.releaseVersion}.`);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
14
|
const flattenStrings = (value)=>'string' == typeof value ? [
|
|
42
15
|
value
|
|
43
16
|
] : Array.isArray(value) ? value.flatMap(flattenStrings) : [];
|
|
@@ -180,6 +153,49 @@ const releaseArtifact = (logicalPath, runtime)=>({
|
|
|
180
153
|
logicalPath,
|
|
181
154
|
runtime
|
|
182
155
|
});
|
|
156
|
+
const writeReleaseIdentityCarrierMetadata = async (artifactRoot, identity, carrierPaths)=>{
|
|
157
|
+
const surfacesByPath = new Map();
|
|
158
|
+
for (const [surface, logicalPaths] of Object.entries(carrierPaths)){
|
|
159
|
+
if (0 === logicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no declared release-identity carrier artifact.`);
|
|
160
|
+
for (const logicalPath of logicalPaths){
|
|
161
|
+
const surfaces = surfacesByPath.get(logicalPath) ?? new Set();
|
|
162
|
+
surfaces.add(surface);
|
|
163
|
+
surfacesByPath.set(logicalPath, surfaces);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const carriers = await Promise.all([
|
|
167
|
+
...surfacesByPath
|
|
168
|
+
].sort(([left], [right])=>left.localeCompare(right)).map(async ([logicalPath, surfaces])=>{
|
|
169
|
+
const bytes = await promises.readFile(node_path.join(artifactRoot, logicalPath));
|
|
170
|
+
return {
|
|
171
|
+
logicalPath,
|
|
172
|
+
byteLength: bytes.byteLength,
|
|
173
|
+
sha256: createHash('sha256').update(bytes).digest('hex'),
|
|
174
|
+
surfaces: [
|
|
175
|
+
...surfaces
|
|
176
|
+
].sort((left, right)=>left.localeCompare(right))
|
|
177
|
+
};
|
|
178
|
+
}));
|
|
179
|
+
const releaseEnvelopePath = await resolveSafeReleaseEnvelopePath({
|
|
180
|
+
artifactRoot,
|
|
181
|
+
createDirectory: true
|
|
182
|
+
});
|
|
183
|
+
if (!releaseEnvelopePath) throw new Error('[ultramodern-release-envelope] could not resolve private release metadata directory.');
|
|
184
|
+
const metadataPath = node_path.join(node_path.dirname(releaseEnvelopePath), node_path.basename(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH));
|
|
185
|
+
try {
|
|
186
|
+
const metadataStat = await promises.lstat(metadataPath);
|
|
187
|
+
if (metadataStat.isSymbolicLink() || !metadataStat.isFile()) throw new Error('[ultramodern-release-envelope] release identity carrier metadata must be a real file inside artifactRoot.');
|
|
188
|
+
} catch (error) {
|
|
189
|
+
if (!isMissingPathError(error)) throw error;
|
|
190
|
+
}
|
|
191
|
+
await promises.writeFile(metadataPath, `${JSON.stringify({
|
|
192
|
+
schemaVersion: MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION,
|
|
193
|
+
kind: MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND,
|
|
194
|
+
identity,
|
|
195
|
+
carriers
|
|
196
|
+
}, null, 2)}\n`);
|
|
197
|
+
return releaseArtifact(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, 'release-identity-metadata');
|
|
198
|
+
};
|
|
183
199
|
const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
184
200
|
const files = await collectFiles(distDirectory);
|
|
185
201
|
if ('node' === target && files.some((logicalPath)=>EFFECT_BFF_WORKER_PATTERN.test(logicalPath))) throw new Error('[ultramodern-release-envelope] Node target conflicts with a Cloudflare Effect API/BFF worker artifact; resolve the canonical deploy target instead of emitting a Node envelope for Cloudflare output.');
|
|
@@ -203,13 +219,7 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
203
219
|
const clientExecutionPaths = await manifestReferencedClientModules(distDirectory, files);
|
|
204
220
|
if (0 === clientExecutionPaths.length) throw new Error('[ultramodern-release-envelope] UI/client manifest references no compiled execution module.');
|
|
205
221
|
const ssrExecutionPaths = await routeReferencedSsrModules(distDirectory, files, target);
|
|
206
|
-
|
|
207
|
-
await assertEveryCompiledIdentityCarrier(distDirectory, ssrExecutionPaths, identity, 'node' === target ? 'route-referenced Node SSR' : 'route-referenced Cloudflare SSR');
|
|
208
|
-
await assertEveryCompiledIdentityCarrier(distDirectory, ssrPaths, identity, 'node' === target ? 'compiled Node SSR closure' : 'compiled Cloudflare SSR/workerd closure');
|
|
209
|
-
await assertEveryCompiledIdentityCarrier(distDirectory, 'node' === target ? nodeApiEntryPaths : apiBackendPaths, identity, 'node' === target ? 'Node API/backend' : 'Cloudflare API/backend');
|
|
210
|
-
await assertEveryCompiledIdentityCarrier(distDirectory, [
|
|
211
|
-
BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
212
|
-
], identity, 'backend Module Federation container');
|
|
222
|
+
if (0 === ssrExecutionPaths.length) throw new Error(`[ultramodern-release-envelope] route manifest references no emitted ${'node' === target ? 'Node' : 'Cloudflare'} SSR execution module.`);
|
|
213
223
|
const runtimeByPath = new Map();
|
|
214
224
|
const add = (paths, runtime)=>{
|
|
215
225
|
for (const logicalPath of paths){
|
|
@@ -245,8 +255,25 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
245
255
|
const artifacts = [
|
|
246
256
|
...runtimeByPath
|
|
247
257
|
].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath));
|
|
258
|
+
const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(distDirectory, identity, {
|
|
259
|
+
apiBackend: apiBackendPaths,
|
|
260
|
+
backendFederation: [
|
|
261
|
+
BACKEND_FEDERATION_MANIFEST_FILE,
|
|
262
|
+
BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
263
|
+
],
|
|
264
|
+
ssr: [
|
|
265
|
+
...new Set([
|
|
266
|
+
...ssrExecutionPaths,
|
|
267
|
+
...ssrPaths
|
|
268
|
+
])
|
|
269
|
+
],
|
|
270
|
+
uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
|
|
271
|
+
});
|
|
248
272
|
return {
|
|
249
|
-
artifacts
|
|
273
|
+
artifacts: [
|
|
274
|
+
...artifacts,
|
|
275
|
+
identityCarrierMetadata
|
|
276
|
+
].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
|
|
250
277
|
surfaces
|
|
251
278
|
};
|
|
252
279
|
};
|
|
@@ -368,13 +395,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
368
395
|
])if (0 === paths.length) throw new Error(`[ultramodern-release-envelope] final Node staging has no ${surface} artifacts.`);
|
|
369
396
|
const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files);
|
|
370
397
|
const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'node');
|
|
371
|
-
|
|
372
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, ssrExecutionPaths, identity, 'final route-referenced Node SSR');
|
|
373
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath), identity, 'final compiled Node SSR closure');
|
|
374
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, apiBackendPaths.filter((logicalPath)=>logicalPath.startsWith('api/')), identity, 'final Node API/backend');
|
|
375
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, [
|
|
376
|
-
BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
377
|
-
], identity, 'final Node backend Module Federation container');
|
|
398
|
+
if (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length) throw new Error('[ultramodern-release-envelope] final Node manifests must reference emitted UI/client and SSR execution modules.');
|
|
378
399
|
const runtimeByPath = new Map(files.filter((logicalPath)=>!backendFederationPaths.has(logicalPath)).map((logicalPath)=>[
|
|
379
400
|
logicalPath,
|
|
380
401
|
'nodejs-deployment'
|
|
@@ -384,10 +405,27 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
384
405
|
for (const logicalPath of apiBackendPaths)runtimeByPath.set(logicalPath, 'nodejs');
|
|
385
406
|
runtimeByPath.set(BACKEND_FEDERATION_MANIFEST_FILE, 'module-federation-manifest');
|
|
386
407
|
runtimeByPath.set(BACKEND_FEDERATION_REMOTE_ENTRY_FILE, 'nodejs');
|
|
408
|
+
const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
|
|
409
|
+
apiBackend: apiBackendPaths,
|
|
410
|
+
backendFederation: [
|
|
411
|
+
BACKEND_FEDERATION_MANIFEST_FILE,
|
|
412
|
+
BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
413
|
+
],
|
|
414
|
+
ssr: [
|
|
415
|
+
...new Set([
|
|
416
|
+
...ssrExecutionPaths,
|
|
417
|
+
...ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath)
|
|
418
|
+
])
|
|
419
|
+
],
|
|
420
|
+
uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
|
|
421
|
+
});
|
|
387
422
|
return {
|
|
388
423
|
artifacts: [
|
|
389
|
-
...
|
|
390
|
-
|
|
424
|
+
...[
|
|
425
|
+
...runtimeByPath
|
|
426
|
+
].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)),
|
|
427
|
+
identityCarrierMetadata
|
|
428
|
+
].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
|
|
391
429
|
surfaces: {
|
|
392
430
|
uiClient: [
|
|
393
431
|
...uiClientPaths
|
|
@@ -461,13 +499,7 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
461
499
|
])if (!files.includes(logicalPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${logicalPath}.`);
|
|
462
500
|
const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files, 'public/mf-manifest.json');
|
|
463
501
|
const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'cloudflare', 'server/route.json');
|
|
464
|
-
|
|
465
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, ssrExecutionPaths, identity, 'final route-referenced Cloudflare SSR');
|
|
466
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/')), identity, 'final compiled Cloudflare SSR/workerd closure');
|
|
467
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, apiBackendPaths, identity, 'final Cloudflare API/backend');
|
|
468
|
-
await assertEveryCompiledIdentityCarrier(outputDirectory, [
|
|
469
|
-
backendContainerPath
|
|
470
|
-
], identity, 'final Cloudflare backend Module Federation container');
|
|
502
|
+
if (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length) throw new Error('[ultramodern-release-envelope] final Cloudflare manifests must reference emitted UI/client and SSR execution modules.');
|
|
471
503
|
const runtimeByPath = new Map();
|
|
472
504
|
for (const logicalPath of files)runtimeByPath.set(logicalPath, 'cloudflare-deployment');
|
|
473
505
|
const add = (paths, runtime)=>{
|
|
@@ -482,10 +514,27 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
482
514
|
add([
|
|
483
515
|
backendContainerPath
|
|
484
516
|
], 'commonjs-module');
|
|
517
|
+
const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
|
|
518
|
+
apiBackend: apiBackendPaths,
|
|
519
|
+
backendFederation: [
|
|
520
|
+
backendManifestPath,
|
|
521
|
+
backendContainerPath
|
|
522
|
+
],
|
|
523
|
+
ssr: [
|
|
524
|
+
...new Set([
|
|
525
|
+
...ssrExecutionPaths,
|
|
526
|
+
...ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/'))
|
|
527
|
+
])
|
|
528
|
+
],
|
|
529
|
+
uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
|
|
530
|
+
});
|
|
485
531
|
return {
|
|
486
532
|
artifacts: [
|
|
487
|
-
...
|
|
488
|
-
|
|
533
|
+
...[
|
|
534
|
+
...runtimeByPath
|
|
535
|
+
].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)),
|
|
536
|
+
identityCarrierMetadata
|
|
537
|
+
].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
|
|
489
538
|
surfaces: {
|
|
490
539
|
uiClient: [
|
|
491
540
|
...uiClientPaths
|
|
@@ -522,4 +571,4 @@ const verifyCloudflareReleaseEnvelopeStaging = async (outputDirectory)=>readFram
|
|
|
522
571
|
expectedTarget: 'cloudflare',
|
|
523
572
|
required: true
|
|
524
573
|
});
|
|
525
|
-
export { MICROVERTICAL_RELEASE_ENVELOPE_PATH, emitCloudflareStagedReleaseEnvelope, emitFrameworkMicroVerticalReleaseEnvelope, emitNodeStagedReleaseEnvelope, readFrameworkMicroVerticalReleaseEnvelope, stageCloudflareReleaseEnvelope, verifyBuildOutputReleaseEnvelope, verifyCloudflareReleaseEnvelopeStaging, verifyNodeReleaseEnvelopeStaging };
|
|
574
|
+
export { MICROVERTICAL_RELEASE_ENVELOPE_PATH, MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, emitCloudflareStagedReleaseEnvelope, emitFrameworkMicroVerticalReleaseEnvelope, emitNodeStagedReleaseEnvelope, readFrameworkMicroVerticalReleaseEnvelope, stageCloudflareReleaseEnvelope, verifyBuildOutputReleaseEnvelope, verifyCloudflareReleaseEnvelopeStaging, verifyNodeReleaseEnvelopeStaging };
|
|
@@ -1,5 +1,34 @@
|
|
|
1
|
+
import type { ModifyBundlerChainFn } from '@rsbuild/core';
|
|
1
2
|
import type { AppNormalizedConfig } from '../../types';
|
|
2
3
|
import type { AppToolsContext } from '../../types/plugin';
|
|
4
|
+
export declare function getCloudflareWorkerRspackConfig(workerEntryNames: Iterable<string>): {
|
|
5
|
+
readonly experiments: {
|
|
6
|
+
readonly outputModule: true;
|
|
7
|
+
};
|
|
8
|
+
readonly externals: {
|
|
9
|
+
[k: string]: string;
|
|
10
|
+
};
|
|
11
|
+
readonly externalsType: 'module-import';
|
|
12
|
+
readonly module: {
|
|
13
|
+
readonly parser: {
|
|
14
|
+
readonly javascript: {
|
|
15
|
+
readonly dynamicImportMode: 'eager';
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
readonly optimization: {
|
|
20
|
+
readonly runtimeChunk: {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
};
|
|
23
|
+
readonly splitChunks: {
|
|
24
|
+
readonly chunks: 'all';
|
|
25
|
+
readonly minSize: 0;
|
|
26
|
+
readonly name: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare function applyCloudflareWorkerRspackConfig(chain: Parameters<ModifyBundlerChainFn>[0], workerEntryNames: Iterable<string>): void;
|
|
31
|
+
export declare function applyCloudflareWorkerMfRuntimeBoundary(chain: Parameters<ModifyBundlerChainFn>[0]): void;
|
|
3
32
|
export declare function getBuilderEnvironments(normalizedConfig: AppNormalizedConfig, appContext: AppToolsContext, tempBuilderConfig: Omit<AppNormalizedConfig, 'plugins'>): {
|
|
4
33
|
environments: Record<string, import("@rsbuild/core").EnvironmentConfig>;
|
|
5
34
|
builderConfig: Omit<AppNormalizedConfig, "plugins">;
|
|
@@ -16,5 +16,5 @@ interface WorkerBundleVerificationContract {
|
|
|
16
16
|
workerRoot: string;
|
|
17
17
|
}
|
|
18
18
|
export declare const verifyWorkerBundleReferences: (issues: CloudflareOutputVerifierIssue[], worker: ResolvedWorkerBundleReference, source: string, contract: WorkerBundleVerificationContract) => Promise<void>;
|
|
19
|
-
export declare const verifyWorkerImport: (issues: CloudflareOutputVerifierIssue[], entryPath: string) => Promise<void>;
|
|
19
|
+
export declare const verifyWorkerImport: (issues: CloudflareOutputVerifierIssue[], entryPath: string, expectedManifest?: JsonObject) => Promise<void>;
|
|
20
20
|
export {};
|
package/dist/types/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export declare const modernWorkerManifest: any;
|
package/dist/types/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workerd cannot initialize Module Federation's Node-oriented SSR data-fetch
|
|
3
|
+
* runtime. Cloudflare workers do not load native MF remotes, so retain the
|
|
4
|
+
* runtime-plugin contract without installing its server data-fetch hooks.
|
|
5
|
+
*/
|
|
6
|
+
export declare const injectDataFetchFunctionPlugin: () => {
|
|
7
|
+
name: string;
|
|
8
|
+
setup(): void;
|
|
9
|
+
};
|
|
10
|
+
export declare const mfSSRDevPlugin: () => {
|
|
11
|
+
name: string;
|
|
12
|
+
setup(): void;
|
|
13
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MicroVerticalReleaseArtifact, MicroVerticalReleaseEnvelope, MicroVerticalReleaseTarget } from './types';
|
|
2
2
|
export declare const MICROVERTICAL_RELEASE_ENVELOPE_PATH = "release/microvertical-release-envelope.json";
|
|
3
|
+
export declare const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH = "release/microvertical-release-identity-carriers.json";
|
|
3
4
|
export declare const emitFrameworkMicroVerticalReleaseEnvelope: ({ apiOnly, distDirectory, target, }: {
|
|
4
5
|
apiOnly: boolean;
|
|
5
6
|
distDirectory: string;
|