@bleedingdev/modern-js-create 3.5.0-ultramodern.2 → 3.5.0-ultramodern.21
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/README.md +22 -15
- package/dist/cjs/ultramodern-tooling/commands.cjs +393 -3
- package/dist/cjs/ultramodern-workspace/app-files.cjs +8 -11
- package/dist/cjs/ultramodern-workspace/module-federation.cjs +13 -6
- package/dist/cjs/ultramodern-workspace/package-json.cjs +15 -8
- package/dist/cjs/ultramodern-workspace/versions.cjs +7 -2
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +2 -0
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +2 -0
- package/dist/esm/ultramodern-tooling/commands.js +393 -3
- package/dist/esm/ultramodern-workspace/app-files.js +8 -11
- package/dist/esm/ultramodern-workspace/module-federation.js +13 -6
- package/dist/esm/ultramodern-workspace/package-json.js +5 -8
- package/dist/esm/ultramodern-workspace/versions.js +5 -3
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +3 -1
- package/dist/esm/ultramodern-workspace/write-workspace.js +3 -1
- package/dist/esm-node/ultramodern-tooling/commands.js +393 -3
- package/dist/esm-node/ultramodern-workspace/app-files.js +8 -11
- package/dist/esm-node/ultramodern-workspace/module-federation.js +13 -6
- package/dist/esm-node/ultramodern-workspace/package-json.js +5 -8
- package/dist/esm-node/ultramodern-workspace/versions.js +5 -3
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +3 -1
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +3 -1
- package/dist/types/ultramodern-workspace/versions.d.ts +4 -2
- package/package.json +3 -3
- package/template-workspace/.gitignore.handlebars +3 -0
- package/template-workspace/README.md.handlebars +19 -13
- package/template-workspace/patches/@module-federation__bridge-react@2.6.0.patch +140 -0
- package/template-workspace/patches/@module-federation__modern-js-v3@2.6.0.patch +57 -0
- package/template-workspace/patches/drizzle-orm-ts7-strict-declarations.patch +452 -0
- package/template-workspace/patches/effect-schema-error-type-id.patch +18 -0
- package/template-workspace/pnpm-workspace.yaml.handlebars +9 -0
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +95 -5
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
3
12
|
(()=>{
|
|
4
13
|
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
14
|
var define = (defs, kind)=>{
|
|
@@ -44,6 +53,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
44
53
|
createZephyrDependencies: ()=>createZephyrDependencies,
|
|
45
54
|
effectDiagnostics: ()=>effectDiagnostics
|
|
46
55
|
});
|
|
56
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
57
|
+
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
47
58
|
const external_ultramodern_package_source_cjs_namespaceObject = require("../ultramodern-package-source.cjs");
|
|
48
59
|
const external_descriptors_cjs_namespaceObject = require("./descriptors.cjs");
|
|
49
60
|
const external_fs_io_cjs_namespaceObject = require("./fs-io.cjs");
|
|
@@ -294,7 +305,6 @@ function createTsConfigBase() {
|
|
|
294
305
|
noFallthroughCasesInSwitch: true,
|
|
295
306
|
noPropertyAccessFromIndexSignature: true,
|
|
296
307
|
noImplicitReturns: true,
|
|
297
|
-
skipLibCheck: true,
|
|
298
308
|
resolveJsonModule: true,
|
|
299
309
|
plugins: [
|
|
300
310
|
{
|
|
@@ -326,7 +336,7 @@ function createReferences(packageDir, references) {
|
|
|
326
336
|
return [
|
|
327
337
|
...new Set(references)
|
|
328
338
|
].filter((reference)=>reference !== packageDir).map((reference)=>({
|
|
329
|
-
path:
|
|
339
|
+
path: external_node_path_default().relative(packageDir, reference).split(external_node_path_default().sep).join('/')
|
|
330
340
|
}));
|
|
331
341
|
}
|
|
332
342
|
function createPackageTsConfig(packageDir, options = {}) {
|
|
@@ -336,8 +346,6 @@ function createPackageTsConfig(packageDir, options = {}) {
|
|
|
336
346
|
const include = resolvedOptions.include ?? [
|
|
337
347
|
'src',
|
|
338
348
|
'locales/**/*.json',
|
|
339
|
-
'modern.config.ts',
|
|
340
|
-
'module-federation.config.ts',
|
|
341
349
|
'package.json',
|
|
342
350
|
'shared'
|
|
343
351
|
];
|
|
@@ -371,9 +379,9 @@ function createAppTsConfig(app, remotes = []) {
|
|
|
371
379
|
});
|
|
372
380
|
}
|
|
373
381
|
function createAppMfTypesTsConfig(app) {
|
|
374
|
-
const exposedFiles = Object.
|
|
382
|
+
const exposedFiles = Object.entries(app.exposes ?? {}).sort(([left], [right])=>'./Route' === left ? -1 : './Route' === right ? 1 : 0).map(([, exposePath])=>exposePath.replace(/^\.\//u, ''));
|
|
375
383
|
return {
|
|
376
|
-
extends:
|
|
384
|
+
extends: `${(0, external_naming_cjs_namespaceObject.relativeRootFor)(app.directory)}/tsconfig.base.json`,
|
|
377
385
|
include: [
|
|
378
386
|
...new Set([
|
|
379
387
|
...exposedFiles,
|
|
@@ -404,7 +412,6 @@ function createRootTsConfig(apps = []) {
|
|
|
404
412
|
}
|
|
405
413
|
function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [], bridge) {
|
|
406
414
|
const publicSurfaceBuildCommand = (0, external_public_surface_cjs_namespaceObject.createPublicSurfaceGenerationCommand)(app, 'dist');
|
|
407
|
-
const publicSurfaceCloudflareBuildCommand = (0, external_public_surface_cjs_namespaceObject.createPublicSurfaceGenerationCommand)(app, 'dist');
|
|
408
415
|
const publicSurfaceCloudflareOutputCommand = (0, external_public_surface_cjs_namespaceObject.createPublicSurfaceGenerationCommand)(app, 'cloudflare');
|
|
409
416
|
const packageExports = Object.fromEntries(Object.entries(app.exposes ?? {}).map(([expose, source])=>[
|
|
410
417
|
expose,
|
|
@@ -417,7 +424,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
|
|
|
417
424
|
scripts: {
|
|
418
425
|
dev: 'modern dev',
|
|
419
426
|
build: app.exposes ? `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand} && node ${(0, external_naming_cjs_namespaceObject.relativeRootFor)(app.directory)}/scripts/assert-mf-types.mts` : `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand}`,
|
|
420
|
-
'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build &&
|
|
427
|
+
'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
|
|
421
428
|
'cloudflare:deploy': 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json',
|
|
422
429
|
'cloudflare:preview': 'pnpm run cloudflare:build && wrangler dev --config .output/wrangler.json',
|
|
423
430
|
'cloudflare:proof': `node ${(0, external_naming_cjs_namespaceObject.relativeRootFor)(app.directory)}/scripts/proof-cloudflare-version.mts --app ${app.id}`,
|
|
@@ -37,9 +37,10 @@ const CLOUDFLARE_COMPATIBILITY_DATE = '2026-06-02';
|
|
|
37
37
|
const TAILWIND_VERSION = '4.3.1';
|
|
38
38
|
const TAILWIND_POSTCSS_VERSION = '4.3.1';
|
|
39
39
|
const POSTCSS_VERSION = '8.5.15';
|
|
40
|
-
const EFFECT_VERSION = '4.0.0-beta.
|
|
41
|
-
const EFFECT_VITEST_VERSION = '4.0.0-beta.
|
|
40
|
+
const EFFECT_VERSION = '4.0.0-beta.92';
|
|
41
|
+
const EFFECT_VITEST_VERSION = '4.0.0-beta.92';
|
|
42
42
|
const EFFECT_TSGO_VERSION = '0.14.6';
|
|
43
|
+
const DRIZZLE_ORM_VERSION = '1.0.0-rc.4';
|
|
43
44
|
const TYPESCRIPT_STABLE_VERSION = '6.0.3';
|
|
44
45
|
const TYPESCRIPT_NATIVE_PREVIEW_VERSION = '7.0.0-dev.20260628.1';
|
|
45
46
|
const TYPESCRIPT_VERSION = TYPESCRIPT_STABLE_VERSION;
|
|
@@ -64,11 +65,13 @@ const ultramodernWorkspaceVersions = {
|
|
|
64
65
|
moduleFederation: MODULE_FEDERATION_VERSION,
|
|
65
66
|
effect: EFFECT_VERSION,
|
|
66
67
|
effectVitest: EFFECT_VITEST_VERSION,
|
|
68
|
+
drizzleOrm: DRIZZLE_ORM_VERSION,
|
|
67
69
|
tailwind: TAILWIND_VERSION,
|
|
68
70
|
tailwindPostcss: TAILWIND_POSTCSS_VERSION
|
|
69
71
|
};
|
|
70
72
|
__webpack_require__.d(__webpack_exports__, {}, {
|
|
71
73
|
CLOUDFLARE_COMPATIBILITY_DATE: CLOUDFLARE_COMPATIBILITY_DATE,
|
|
74
|
+
DRIZZLE_ORM_VERSION: DRIZZLE_ORM_VERSION,
|
|
72
75
|
EFFECT_TSGO_VERSION: EFFECT_TSGO_VERSION,
|
|
73
76
|
EFFECT_VERSION: EFFECT_VERSION,
|
|
74
77
|
EFFECT_VITEST_VERSION: EFFECT_VITEST_VERSION,
|
|
@@ -102,6 +105,7 @@ __webpack_require__.d(__webpack_exports__, {}, {
|
|
|
102
105
|
ultramodernWorkspaceVersions: ultramodernWorkspaceVersions
|
|
103
106
|
});
|
|
104
107
|
exports.CLOUDFLARE_COMPATIBILITY_DATE = __webpack_exports__.CLOUDFLARE_COMPATIBILITY_DATE;
|
|
108
|
+
exports.DRIZZLE_ORM_VERSION = __webpack_exports__.DRIZZLE_ORM_VERSION;
|
|
105
109
|
exports.EFFECT_TSGO_VERSION = __webpack_exports__.EFFECT_TSGO_VERSION;
|
|
106
110
|
exports.EFFECT_VERSION = __webpack_exports__.EFFECT_VERSION;
|
|
107
111
|
exports.EFFECT_VITEST_VERSION = __webpack_exports__.EFFECT_VITEST_VERSION;
|
|
@@ -135,6 +139,7 @@ exports.ZEPHYR_RSPACK_PLUGIN_VERSION = __webpack_exports__.ZEPHYR_RSPACK_PLUGIN_
|
|
|
135
139
|
exports.ultramodernWorkspaceVersions = __webpack_exports__.ultramodernWorkspaceVersions;
|
|
136
140
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
137
141
|
"CLOUDFLARE_COMPATIBILITY_DATE",
|
|
142
|
+
"DRIZZLE_ORM_VERSION",
|
|
138
143
|
"EFFECT_TSGO_VERSION",
|
|
139
144
|
"EFFECT_VERSION",
|
|
140
145
|
"EFFECT_VITEST_VERSION",
|
|
@@ -174,6 +174,8 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
|
|
|
174
174
|
const expectedCloudflareSecurity = (0, external_policy_cjs_namespaceObject.createCloudflareSecurityContract)();
|
|
175
175
|
return (0, external_fs_io_cjs_namespaceObject.renderFileTemplate)("workspace-scripts/validate-ultramodern-workspace.mjs", {
|
|
176
176
|
packageScope: scope,
|
|
177
|
+
effectVersion: external_versions_cjs_namespaceObject.EFFECT_VERSION,
|
|
178
|
+
moduleFederationVersion: external_versions_cjs_namespaceObject.MODULE_FEDERATION_VERSION,
|
|
177
179
|
nodeVersion: external_versions_cjs_namespaceObject.NODE_VERSION,
|
|
178
180
|
pnpmVersion: external_versions_cjs_namespaceObject.PNPM_VERSION,
|
|
179
181
|
tailwindEnabledJson: JSON.stringify(enableTailwind),
|
|
@@ -175,8 +175,10 @@ function generateUltramodernWorkspace(options) {
|
|
|
175
175
|
nodeVersion: external_versions_cjs_namespaceObject.NODE_VERSION,
|
|
176
176
|
pnpmVersion: external_versions_cjs_namespaceObject.PNPM_VERSION,
|
|
177
177
|
nodeFetchVersion: external_versions_cjs_namespaceObject.NODE_FETCH_VERSION,
|
|
178
|
+
drizzleOrmVersion: external_versions_cjs_namespaceObject.DRIZZLE_ORM_VERSION,
|
|
178
179
|
effectVersion: external_versions_cjs_namespaceObject.EFFECT_VERSION,
|
|
179
180
|
effectVitestVersion: external_versions_cjs_namespaceObject.EFFECT_VITEST_VERSION,
|
|
181
|
+
moduleFederationVersion: external_versions_cjs_namespaceObject.MODULE_FEDERATION_VERSION,
|
|
180
182
|
tanstackRouterCoreVersion: external_versions_cjs_namespaceObject.TANSTACK_ROUTER_CORE_VERSION,
|
|
181
183
|
tanstackRouterVersion: external_versions_cjs_namespaceObject.TANSTACK_ROUTER_VERSION,
|
|
182
184
|
typescriptVersion: external_versions_cjs_namespaceObject.TYPESCRIPT_VERSION,
|
|
@@ -5,7 +5,11 @@ import node_path from "node:path";
|
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { resolveCreatePackageRoot } from "../create-package-root.js";
|
|
7
7
|
import { BLEEDINGDEV_PACKAGE_NAME_PREFIX, BLEEDINGDEV_PACKAGE_SCOPE, ULTRAMODERN_SINGLE_APP_MODERN_PACKAGES, ULTRAMODERN_WORKSPACE_MODERN_PACKAGES, WORKSPACE_PACKAGE_VERSION, modernPackageSpecifier } from "../ultramodern-package-source.js";
|
|
8
|
+
import { createAppEnvDts } from "../ultramodern-workspace/app-files.js";
|
|
8
9
|
import { validateModuleFederationTypes } from "../ultramodern-workspace/mf-validation.js";
|
|
10
|
+
import { createAppModernConfig } from "../ultramodern-workspace/module-federation.js";
|
|
11
|
+
import { createAppMfTypesTsConfig, createAppTsConfig, createSharedPackageTsConfig, createTsConfigBase } from "../ultramodern-workspace/package-json.js";
|
|
12
|
+
import { DRIZZLE_ORM_VERSION, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, MODULE_FEDERATION_VERSION, OXFMT_VERSION, OXLINT_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION } from "../ultramodern-workspace/versions.js";
|
|
9
13
|
import { createWorkspaceValidationScript } from "../ultramodern-workspace/workspace-scripts.js";
|
|
10
14
|
import { readUltramodernConfig, workspaceAppsFromToolingConfig } from "./config.js";
|
|
11
15
|
const commands_dirname = node_path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -151,6 +155,91 @@ function updateModernDependencies(packageJson, packageSource) {
|
|
|
151
155
|
}
|
|
152
156
|
return changed;
|
|
153
157
|
}
|
|
158
|
+
const generatedToolingDependencyPins = new Map([
|
|
159
|
+
[
|
|
160
|
+
'@effect/tsgo',
|
|
161
|
+
EFFECT_TSGO_VERSION
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"@typescript/native-preview",
|
|
165
|
+
TYPESCRIPT_NATIVE_PREVIEW_VERSION
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
'oxfmt',
|
|
169
|
+
OXFMT_VERSION
|
|
170
|
+
],
|
|
171
|
+
[
|
|
172
|
+
'oxlint',
|
|
173
|
+
OXLINT_VERSION
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
'wrangler',
|
|
177
|
+
WRANGLER_VERSION
|
|
178
|
+
],
|
|
179
|
+
[
|
|
180
|
+
'zephyr-agent',
|
|
181
|
+
ZEPHYR_AGENT_VERSION
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
'zephyr-rspack-plugin',
|
|
185
|
+
ZEPHYR_RSPACK_PLUGIN_VERSION
|
|
186
|
+
]
|
|
187
|
+
]);
|
|
188
|
+
const strictEffectPackageVersionPolicyExclusions = [
|
|
189
|
+
`effect@${EFFECT_VERSION}`,
|
|
190
|
+
`@effect/opentelemetry@${EFFECT_VERSION}`
|
|
191
|
+
];
|
|
192
|
+
const moduleFederationModernJsPatchPath = `patches/@module-federation__modern-js-v3@${MODULE_FEDERATION_VERSION}.patch`;
|
|
193
|
+
const moduleFederationModernJsPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', moduleFederationModernJsPatchPath);
|
|
194
|
+
const moduleFederationBridgeReactPatchPath = `patches/@module-federation__bridge-react@${MODULE_FEDERATION_VERSION}.patch`;
|
|
195
|
+
const moduleFederationBridgeReactPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', moduleFederationBridgeReactPatchPath);
|
|
196
|
+
const effectDeclarationPatchPath = 'patches/effect-schema-error-type-id.patch';
|
|
197
|
+
const effectDeclarationPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', effectDeclarationPatchPath);
|
|
198
|
+
const drizzleOrmDeclarationPatchPath = 'patches/drizzle-orm-ts7-strict-declarations.patch';
|
|
199
|
+
const drizzleOrmDeclarationPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', drizzleOrmDeclarationPatchPath);
|
|
200
|
+
function updateGeneratedToolingDependencies(packageJson) {
|
|
201
|
+
let changed = false;
|
|
202
|
+
for (const section of [
|
|
203
|
+
'dependencies',
|
|
204
|
+
'devDependencies',
|
|
205
|
+
'peerDependencies',
|
|
206
|
+
'optionalDependencies'
|
|
207
|
+
]){
|
|
208
|
+
const dependencies = packageJson[section];
|
|
209
|
+
if (!(!dependencies || 'object' != typeof dependencies || Array.isArray(dependencies))) {
|
|
210
|
+
for (const [packageName, version] of generatedToolingDependencyPins)if (Object.prototype.hasOwnProperty.call(dependencies, packageName) && dependencies[packageName] !== version) {
|
|
211
|
+
dependencies[packageName] = version;
|
|
212
|
+
changed = true;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return changed;
|
|
217
|
+
}
|
|
218
|
+
const cloudflareModernDeployCommand = 'ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy';
|
|
219
|
+
const cloudflareModernDeploySkipBuildCommand = `${cloudflareModernDeployCommand} --skip-build`;
|
|
220
|
+
const cloudflareWranglerDeployCommand = 'wrangler deploy --config .output/wrangler.json';
|
|
221
|
+
const cloudflareWranglerDeployInvalidSkipBuildCommand = `${cloudflareWranglerDeployCommand} --skip-build`;
|
|
222
|
+
function updateGeneratedPackageScripts(packageJson) {
|
|
223
|
+
const scripts = packageJson.scripts;
|
|
224
|
+
if (!scripts || 'object' != typeof scripts || Array.isArray(scripts)) return false;
|
|
225
|
+
let changed = false;
|
|
226
|
+
const cloudflareBuild = scripts['cloudflare:build'];
|
|
227
|
+
if ('string' == typeof cloudflareBuild) {
|
|
228
|
+
let nextCloudflareBuild = cloudflareBuild;
|
|
229
|
+
if (nextCloudflareBuild.includes(cloudflareModernDeployCommand) && !nextCloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) nextCloudflareBuild = nextCloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
|
|
230
|
+
nextCloudflareBuild = nextCloudflareBuild.replace(/ && node \S*scripts\/generate-public-surface-assets\.m[ct]s --app [^&]+ --target dist(?= && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build)/u, '');
|
|
231
|
+
if (nextCloudflareBuild !== cloudflareBuild) {
|
|
232
|
+
scripts['cloudflare:build'] = nextCloudflareBuild;
|
|
233
|
+
changed = true;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const cloudflareDeploy = scripts['cloudflare:deploy'];
|
|
237
|
+
if ('string' == typeof cloudflareDeploy && cloudflareDeploy.includes(cloudflareWranglerDeployInvalidSkipBuildCommand)) {
|
|
238
|
+
scripts['cloudflare:deploy'] = cloudflareDeploy.replace(cloudflareWranglerDeployInvalidSkipBuildCommand, cloudflareWranglerDeployCommand);
|
|
239
|
+
changed = true;
|
|
240
|
+
}
|
|
241
|
+
return changed;
|
|
242
|
+
}
|
|
154
243
|
function normalizeStrictEffectApiMetadata(value) {
|
|
155
244
|
const api = value.api;
|
|
156
245
|
if (!api || 'object' != typeof api || Array.isArray(api)) return false;
|
|
@@ -216,6 +305,236 @@ function normalizeStrictEffectApiMetadata(value) {
|
|
|
216
305
|
}
|
|
217
306
|
return changed;
|
|
218
307
|
}
|
|
308
|
+
function replaceYamlLine(source, pattern, replacement) {
|
|
309
|
+
const updated = source.replace(pattern, replacement);
|
|
310
|
+
return {
|
|
311
|
+
source: updated,
|
|
312
|
+
changed: updated !== source
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
function ensureYamlListItem(source, key, item) {
|
|
316
|
+
const itemLine = ` - '${item}'`;
|
|
317
|
+
const headerPattern = new RegExp(`^${key}:\\n(?:(?: - .+\\n)*)`, 'mu');
|
|
318
|
+
const header = source.match(headerPattern);
|
|
319
|
+
if (header) {
|
|
320
|
+
if (header[0].split('\n').includes(itemLine)) return {
|
|
321
|
+
source,
|
|
322
|
+
changed: false
|
|
323
|
+
};
|
|
324
|
+
return {
|
|
325
|
+
source: source.replace(headerPattern, `${header[0]}${itemLine}\n`),
|
|
326
|
+
changed: true
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
const block = `${key}:\n${itemLine}\n`;
|
|
330
|
+
const afterTrustPolicyIgnore = source.replace(/^(trustPolicyIgnoreAfter: .+\n)/mu, `$1${block}`);
|
|
331
|
+
if (afterTrustPolicyIgnore !== source) return {
|
|
332
|
+
source: afterTrustPolicyIgnore,
|
|
333
|
+
changed: true
|
|
334
|
+
};
|
|
335
|
+
return {
|
|
336
|
+
source: `${source.trimEnd()}\n${block}`,
|
|
337
|
+
changed: true
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function ensureYamlMapEntry(source, key, entryKey, value) {
|
|
341
|
+
const entryLine = ` '${entryKey}': ${value}`;
|
|
342
|
+
const packageName = entryKey.includes('@') ? entryKey.slice(0, entryKey.lastIndexOf('@')) : entryKey;
|
|
343
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
344
|
+
const currentEntryPattern = new RegExp(`^ {2}'${escapedPackageName}@[^']+': .+$`, 'mu');
|
|
345
|
+
const currentEntry = source.match(currentEntryPattern);
|
|
346
|
+
if (currentEntry) {
|
|
347
|
+
if (currentEntry[0] === entryLine) return {
|
|
348
|
+
source,
|
|
349
|
+
changed: false
|
|
350
|
+
};
|
|
351
|
+
return {
|
|
352
|
+
source: source.replace(currentEntryPattern, entryLine),
|
|
353
|
+
changed: true
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
const headerPattern = new RegExp(`^${key}:\\n(?:(?: .+\\n)*)`, 'mu');
|
|
357
|
+
const header = source.match(headerPattern);
|
|
358
|
+
if (header) {
|
|
359
|
+
if (header[0].split('\n').includes(entryLine)) return {
|
|
360
|
+
source,
|
|
361
|
+
changed: false
|
|
362
|
+
};
|
|
363
|
+
return {
|
|
364
|
+
source: source.replace(headerPattern, `${header[0]}${entryLine}\n`),
|
|
365
|
+
changed: true
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
return {
|
|
369
|
+
source: `${source.trimEnd()}\n${key}:\n${entryLine}\n`,
|
|
370
|
+
changed: true
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function ensureYamlScalarMapEntry(source, key, entryKey, value) {
|
|
374
|
+
const entryLine = ` ${entryKey}: ${value}`;
|
|
375
|
+
const escapedEntryKey = entryKey.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
376
|
+
const currentEntryPattern = new RegExp(`^ {2}${escapedEntryKey}: .+$`, 'mu');
|
|
377
|
+
const currentEntry = source.match(currentEntryPattern);
|
|
378
|
+
if (currentEntry) {
|
|
379
|
+
if (currentEntry[0] === entryLine) return {
|
|
380
|
+
source,
|
|
381
|
+
changed: false
|
|
382
|
+
};
|
|
383
|
+
return {
|
|
384
|
+
source: source.replace(currentEntryPattern, entryLine),
|
|
385
|
+
changed: true
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
const headerPattern = new RegExp(`^${key}:\\n(?:(?: .+\\n)*)`, 'mu');
|
|
389
|
+
const header = source.match(headerPattern);
|
|
390
|
+
if (header) return {
|
|
391
|
+
source: source.replace(headerPattern, `${header[0]}${entryLine}\n`),
|
|
392
|
+
changed: true
|
|
393
|
+
};
|
|
394
|
+
return {
|
|
395
|
+
source: `${source.trimEnd()}\n${key}:\n${entryLine}\n`,
|
|
396
|
+
changed: true
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function removeYamlMapEntry(source, entryKey) {
|
|
400
|
+
const packageName = entryKey.includes('@') ? entryKey.slice(0, entryKey.lastIndexOf('@')) : entryKey;
|
|
401
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
402
|
+
const currentEntryPattern = new RegExp(`^ {2}'${escapedPackageName}@[^']+': .+\\n?`, 'mu');
|
|
403
|
+
if (!currentEntryPattern.test(source)) return {
|
|
404
|
+
source,
|
|
405
|
+
changed: false
|
|
406
|
+
};
|
|
407
|
+
return {
|
|
408
|
+
source: source.replace(currentEntryPattern, ''),
|
|
409
|
+
changed: true
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function ensureGeneratedPatchFile(workspaceRoot, relativePatchPath, sourcePatchPath) {
|
|
413
|
+
const targetPath = node_path.join(workspaceRoot, relativePatchPath);
|
|
414
|
+
const patch = node_fs.readFileSync(sourcePatchPath, 'utf-8');
|
|
415
|
+
if (node_fs.existsSync(targetPath) && node_fs.readFileSync(targetPath, 'utf-8') === patch) return false;
|
|
416
|
+
node_fs.mkdirSync(node_path.dirname(targetPath), {
|
|
417
|
+
recursive: true
|
|
418
|
+
});
|
|
419
|
+
node_fs.writeFileSync(targetPath, patch, 'utf-8');
|
|
420
|
+
return true;
|
|
421
|
+
}
|
|
422
|
+
function removeGeneratedPatchFileIfUnchanged(workspaceRoot, relativePatchPath, sourcePatchPath) {
|
|
423
|
+
const targetPath = node_path.join(workspaceRoot, relativePatchPath);
|
|
424
|
+
if (!node_fs.existsSync(targetPath)) return false;
|
|
425
|
+
const patch = node_fs.readFileSync(sourcePatchPath, 'utf-8');
|
|
426
|
+
if (node_fs.readFileSync(targetPath, 'utf-8') !== patch) return false;
|
|
427
|
+
node_fs.rmSync(targetPath);
|
|
428
|
+
return true;
|
|
429
|
+
}
|
|
430
|
+
function workspaceUsesDependency(workspaceRoot, packageName) {
|
|
431
|
+
const packageJsonPaths = [
|
|
432
|
+
node_path.join(workspaceRoot, 'package.json')
|
|
433
|
+
];
|
|
434
|
+
for (const workspaceDir of [
|
|
435
|
+
'apps',
|
|
436
|
+
'verticals',
|
|
437
|
+
'packages'
|
|
438
|
+
]){
|
|
439
|
+
const absoluteWorkspaceDir = node_path.join(workspaceRoot, workspaceDir);
|
|
440
|
+
if (node_fs.existsSync(absoluteWorkspaceDir)) for (const entry of node_fs.readdirSync(absoluteWorkspaceDir, {
|
|
441
|
+
withFileTypes: true
|
|
442
|
+
})){
|
|
443
|
+
if (!entry.isDirectory()) continue;
|
|
444
|
+
const packageJsonPath = node_path.join(absoluteWorkspaceDir, entry.name, 'package.json');
|
|
445
|
+
if (node_fs.existsSync(packageJsonPath)) packageJsonPaths.push(packageJsonPath);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
for (const packageJsonPath of packageJsonPaths){
|
|
449
|
+
const packageJson = JSON.parse(node_fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
450
|
+
for (const field of [
|
|
451
|
+
'dependencies',
|
|
452
|
+
'devDependencies',
|
|
453
|
+
'peerDependencies',
|
|
454
|
+
'optionalDependencies'
|
|
455
|
+
]){
|
|
456
|
+
const dependencies = packageJson[field];
|
|
457
|
+
if (dependencies && 'object' == typeof dependencies) {
|
|
458
|
+
if (Object.prototype.hasOwnProperty.call(dependencies, packageName)) return true;
|
|
459
|
+
for (const specifier of Object.values(dependencies))if ('string' == typeof specifier && specifier.startsWith(`npm:${packageName}@`)) return true;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
function ensureGeneratedDeclarationPatches(workspaceRoot, options) {
|
|
466
|
+
let changed = false;
|
|
467
|
+
changed = ensureGeneratedPatchFile(workspaceRoot, moduleFederationModernJsPatchPath, moduleFederationModernJsPatchSourcePath) || changed;
|
|
468
|
+
changed = ensureGeneratedPatchFile(workspaceRoot, moduleFederationBridgeReactPatchPath, moduleFederationBridgeReactPatchSourcePath) || changed;
|
|
469
|
+
changed = ensureGeneratedPatchFile(workspaceRoot, effectDeclarationPatchPath, effectDeclarationPatchSourcePath) || changed;
|
|
470
|
+
changed = options.includeDrizzleOrmPatch ? ensureGeneratedPatchFile(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed : removeGeneratedPatchFileIfUnchanged(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed;
|
|
471
|
+
return changed;
|
|
472
|
+
}
|
|
473
|
+
function updateGeneratedPnpmWorkspacePolicy(workspaceRoot) {
|
|
474
|
+
const workspaceFile = node_path.join(workspaceRoot, 'pnpm-workspace.yaml');
|
|
475
|
+
if (!node_fs.existsSync(workspaceFile)) return false;
|
|
476
|
+
let source = node_fs.readFileSync(workspaceFile, 'utf-8');
|
|
477
|
+
let changed = false;
|
|
478
|
+
const usesDrizzleOrm = workspaceUsesDependency(workspaceRoot, 'drizzle-orm');
|
|
479
|
+
const replacements = [
|
|
480
|
+
[
|
|
481
|
+
/^ {4}'@effect\/vitest>effect': .+$/mu,
|
|
482
|
+
` '@effect/vitest>effect': '${EFFECT_VERSION}'`
|
|
483
|
+
]
|
|
484
|
+
];
|
|
485
|
+
for (const [pattern, replacement] of replacements){
|
|
486
|
+
const result = replaceYamlLine(source, pattern, replacement);
|
|
487
|
+
source = result.source;
|
|
488
|
+
changed = result.changed || changed;
|
|
489
|
+
}
|
|
490
|
+
for (const [entryKey, version] of [
|
|
491
|
+
[
|
|
492
|
+
"'@effect/opentelemetry'",
|
|
493
|
+
EFFECT_VERSION
|
|
494
|
+
],
|
|
495
|
+
[
|
|
496
|
+
"'@effect/vitest'",
|
|
497
|
+
EFFECT_VITEST_VERSION
|
|
498
|
+
],
|
|
499
|
+
[
|
|
500
|
+
'effect',
|
|
501
|
+
EFFECT_VERSION
|
|
502
|
+
]
|
|
503
|
+
]){
|
|
504
|
+
const result = ensureYamlScalarMapEntry(source, 'overrides', entryKey, version);
|
|
505
|
+
source = result.source;
|
|
506
|
+
changed = result.changed || changed;
|
|
507
|
+
}
|
|
508
|
+
for (const item of strictEffectPackageVersionPolicyExclusions){
|
|
509
|
+
const packageName = item.slice(0, item.lastIndexOf('@'));
|
|
510
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
511
|
+
const currentVersion = replaceYamlLine(source, new RegExp(`^ {2}- '${escapedPackageName}@[^']+'$`, 'gmu'), ` - '${item}'`);
|
|
512
|
+
source = currentVersion.source;
|
|
513
|
+
changed = currentVersion.changed || changed;
|
|
514
|
+
for (const policyKey of [
|
|
515
|
+
'minimumReleaseAgeExclude',
|
|
516
|
+
'trustPolicyExclude'
|
|
517
|
+
]){
|
|
518
|
+
const policyExclude = ensureYamlListItem(source, policyKey, item);
|
|
519
|
+
source = policyExclude.source;
|
|
520
|
+
changed = policyExclude.changed || changed;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
const effectPatch = ensureYamlMapEntry(source, 'patchedDependencies', `effect@${EFFECT_VERSION}`, effectDeclarationPatchPath);
|
|
524
|
+
source = effectPatch.source;
|
|
525
|
+
changed = effectPatch.changed || changed;
|
|
526
|
+
const moduleFederationModernJsPatch = ensureYamlMapEntry(source, 'patchedDependencies', `@module-federation/modern-js-v3@${MODULE_FEDERATION_VERSION}`, moduleFederationModernJsPatchPath);
|
|
527
|
+
source = moduleFederationModernJsPatch.source;
|
|
528
|
+
changed = moduleFederationModernJsPatch.changed || changed;
|
|
529
|
+
const moduleFederationBridgeReactPatch = ensureYamlMapEntry(source, 'patchedDependencies', `@module-federation/bridge-react@${MODULE_FEDERATION_VERSION}`, moduleFederationBridgeReactPatchPath);
|
|
530
|
+
source = moduleFederationBridgeReactPatch.source;
|
|
531
|
+
changed = moduleFederationBridgeReactPatch.changed || changed;
|
|
532
|
+
const drizzleOrmPatch = usesDrizzleOrm ? ensureYamlMapEntry(source, 'patchedDependencies', `drizzle-orm@${DRIZZLE_ORM_VERSION}`, drizzleOrmDeclarationPatchPath) : removeYamlMapEntry(source, `drizzle-orm@${DRIZZLE_ORM_VERSION}`);
|
|
533
|
+
source = drizzleOrmPatch.source;
|
|
534
|
+
changed = drizzleOrmPatch.changed || changed;
|
|
535
|
+
if (changed) node_fs.writeFileSync(workspaceFile, source, 'utf-8');
|
|
536
|
+
return changed;
|
|
537
|
+
}
|
|
219
538
|
function updateUltramodernConfig(workspaceRoot, packageSource) {
|
|
220
539
|
const configPath = node_path.join(workspaceRoot, '.modernjs/ultramodern.json');
|
|
221
540
|
const config = readJsonFile(configPath);
|
|
@@ -235,6 +554,64 @@ function updateUltramodernConfig(workspaceRoot, packageSource) {
|
|
|
235
554
|
for (const app of config.topology?.apps ?? [])if (app && 'object' == typeof app && !Array.isArray(app)) normalizeStrictEffectApiMetadata(app);
|
|
236
555
|
writeJsonFile(configPath, config);
|
|
237
556
|
}
|
|
557
|
+
function writeJsonIfChanged(filePath, value) {
|
|
558
|
+
const next = `${JSON.stringify(value, null, 2)}\n`;
|
|
559
|
+
if (node_fs.existsSync(filePath) && node_fs.readFileSync(filePath, 'utf-8') === next) return false;
|
|
560
|
+
node_fs.mkdirSync(node_path.dirname(filePath), {
|
|
561
|
+
recursive: true
|
|
562
|
+
});
|
|
563
|
+
node_fs.writeFileSync(filePath, next, 'utf-8');
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
function writeTextIfChanged(filePath, value) {
|
|
567
|
+
if (node_fs.existsSync(filePath) && node_fs.readFileSync(filePath, 'utf-8') === value) return false;
|
|
568
|
+
node_fs.mkdirSync(node_path.dirname(filePath), {
|
|
569
|
+
recursive: true
|
|
570
|
+
});
|
|
571
|
+
node_fs.writeFileSync(filePath, value, 'utf-8');
|
|
572
|
+
return true;
|
|
573
|
+
}
|
|
574
|
+
function ensureGeneratedIgnoreRules(workspaceRoot) {
|
|
575
|
+
const gitignorePath = node_path.join(workspaceRoot, '.gitignore');
|
|
576
|
+
const existing = node_fs.existsSync(gitignorePath) ? node_fs.readFileSync(gitignorePath, 'utf-8') : '';
|
|
577
|
+
const lines = 0 === existing.trimEnd().length ? [] : existing.trimEnd().split(/\r?\n/u);
|
|
578
|
+
let changed = false;
|
|
579
|
+
for (const rule of [
|
|
580
|
+
'.mf/',
|
|
581
|
+
'**/.mf/',
|
|
582
|
+
'dist-cloudflare/'
|
|
583
|
+
])if (!lines.includes(rule)) {
|
|
584
|
+
lines.push(rule);
|
|
585
|
+
changed = true;
|
|
586
|
+
}
|
|
587
|
+
if (!changed) return false;
|
|
588
|
+
const next = `${lines.join('\n')}\n`;
|
|
589
|
+
node_fs.writeFileSync(gitignorePath, next, 'utf-8');
|
|
590
|
+
return true;
|
|
591
|
+
}
|
|
592
|
+
function updateGeneratedTypeScriptSurfaces(workspaceRoot, config) {
|
|
593
|
+
let changed = false;
|
|
594
|
+
const apps = workspaceAppsFromToolingConfig(config);
|
|
595
|
+
const remotes = apps.filter((app)=>'shell' !== app.kind);
|
|
596
|
+
changed = writeJsonIfChanged(node_path.join(workspaceRoot, 'tsconfig.base.json'), createTsConfigBase()) || changed;
|
|
597
|
+
changed = ensureGeneratedIgnoreRules(workspaceRoot) || changed;
|
|
598
|
+
for (const sharedPackage of [
|
|
599
|
+
'packages/shared-contracts',
|
|
600
|
+
'packages/shared-design-tokens'
|
|
601
|
+
])changed = writeJsonIfChanged(node_path.join(workspaceRoot, sharedPackage, 'tsconfig.json'), createSharedPackageTsConfig(sharedPackage)) || changed;
|
|
602
|
+
for (const app of apps){
|
|
603
|
+
changed = writeJsonIfChanged(node_path.join(workspaceRoot, app.directory, 'tsconfig.json'), createAppTsConfig(app, remotes)) || changed;
|
|
604
|
+
changed = writeJsonIfChanged(node_path.join(workspaceRoot, app.directory, 'tsconfig.mf-types.json'), createAppMfTypesTsConfig(app)) || changed;
|
|
605
|
+
changed = writeTextIfChanged(node_path.join(workspaceRoot, app.directory, 'src/modern-app-env.d.ts'), createAppEnvDts(app, remotes)) || changed;
|
|
606
|
+
}
|
|
607
|
+
return changed;
|
|
608
|
+
}
|
|
609
|
+
function updateGeneratedModernConfigs(workspaceRoot, config) {
|
|
610
|
+
let changed = false;
|
|
611
|
+
const apps = workspaceAppsFromToolingConfig(config);
|
|
612
|
+
for (const app of apps)changed = writeTextIfChanged(node_path.join(workspaceRoot, app.directory, 'modern.config.ts'), createAppModernConfig(config.workspace.packageScope, app)) || changed;
|
|
613
|
+
return changed;
|
|
614
|
+
}
|
|
238
615
|
function updateReferenceTopology(workspaceRoot) {
|
|
239
616
|
const topologyPath = node_path.join(workspaceRoot, 'topology/reference-topology.json');
|
|
240
617
|
if (!node_fs.existsSync(topologyPath)) return false;
|
|
@@ -297,8 +674,10 @@ function runMigrateStrictEffect(args, context) {
|
|
|
297
674
|
modern-js-create ultramodern migrate-strict-effect --version <version> [--skip-install]
|
|
298
675
|
|
|
299
676
|
Updates generated UltraModern package-source metadata, Modern package aliases,
|
|
300
|
-
direct Effect API topology metadata,
|
|
301
|
-
|
|
677
|
+
framework-owned toolchain pins, direct Effect API topology metadata, strict
|
|
678
|
+
Effect pnpm overrides/trust policy, framework-owned TypeScript config
|
|
679
|
+
surfaces, and the pnpm lockfile. Source code still has to pass pnpm api:check
|
|
680
|
+
and pnpm contract:check.
|
|
302
681
|
`);
|
|
303
682
|
return 0;
|
|
304
683
|
}
|
|
@@ -306,6 +685,9 @@ workspaces. Source code still has to pass pnpm api:check and pnpm contract:check
|
|
|
306
685
|
const packageSource = createMigrationPackageSource(args, current);
|
|
307
686
|
updateUltramodernConfig(context.workspaceRoot, packageSource);
|
|
308
687
|
updateReferenceTopology(context.workspaceRoot);
|
|
688
|
+
const migrated = readUltramodernConfig(context.workspaceRoot);
|
|
689
|
+
updateGeneratedTypeScriptSurfaces(context.workspaceRoot, migrated);
|
|
690
|
+
updateGeneratedModernConfigs(context.workspaceRoot, migrated);
|
|
309
691
|
for (const relativePackageFile of listWorkspacePackageFiles(context.workspaceRoot)){
|
|
310
692
|
const packageFile = node_path.join(context.workspaceRoot, relativePackageFile);
|
|
311
693
|
const packageJson = readJsonFile(packageFile);
|
|
@@ -316,9 +698,17 @@ workspaces. Source code still has to pass pnpm api:check and pnpm contract:check
|
|
|
316
698
|
config: './.modernjs/ultramodern.json'
|
|
317
699
|
};
|
|
318
700
|
}
|
|
319
|
-
|
|
701
|
+
const modernDependenciesChanged = updateModernDependencies(packageJson, packageSource);
|
|
702
|
+
const toolingDependenciesChanged = updateGeneratedToolingDependencies(packageJson);
|
|
703
|
+
const generatedScriptsChanged = updateGeneratedPackageScripts(packageJson);
|
|
704
|
+
const changed = modernDependenciesChanged || toolingDependenciesChanged || generatedScriptsChanged;
|
|
705
|
+
if (changed) writeJsonFile(packageFile, packageJson);
|
|
320
706
|
else if ('package.json' === relativePackageFile) writeJsonFile(packageFile, packageJson);
|
|
321
707
|
}
|
|
708
|
+
updateGeneratedPnpmWorkspacePolicy(context.workspaceRoot);
|
|
709
|
+
ensureGeneratedDeclarationPatches(context.workspaceRoot, {
|
|
710
|
+
includeDrizzleOrmPatch: workspaceUsesDependency(context.workspaceRoot, 'drizzle-orm')
|
|
711
|
+
});
|
|
322
712
|
if (!hasFlag(args, '--skip-install')) {
|
|
323
713
|
const status = runPnpmLockfileRefresh(context);
|
|
324
714
|
if (0 !== status) return status;
|
|
@@ -27,17 +27,14 @@ function createAppEnvDts(app, remotes = []) {
|
|
|
27
27
|
}
|
|
28
28
|
`;
|
|
29
29
|
})).join('\n');
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
declare module '*.css';
|
|
40
|
-
${remoteModuleDeclarations ? `\n${remoteModuleDeclarations}` : ''}`;
|
|
30
|
+
const reactTypeImport = remoteModuleDeclarations ? "import type React from 'react';\n" : '';
|
|
31
|
+
return [
|
|
32
|
+
`import '@modern-js/app-tools/types';\n${reactTypeImport}`.trimEnd(),
|
|
33
|
+
`declare global {
|
|
34
|
+
const ULTRAMODERN_SITE_URL: string;
|
|
35
|
+
}`,
|
|
36
|
+
remoteModuleDeclarations.trimEnd()
|
|
37
|
+
].filter((section)=>section.length > 0).join('\n\n').concat('\n');
|
|
41
38
|
}
|
|
42
39
|
function createAppRuntimeConfig(app, scope, remotes = []) {
|
|
43
40
|
const pluginsConfig = 'shell' === app.kind ? ` plugins: [
|
|
@@ -25,6 +25,11 @@ function createAppModernConfig(scope, app) {
|
|
|
25
25
|
(cloudflareDeployEnabled ? '/' : \`http://localhost:\${port}\`);
|
|
26
26
|
const defaultRemoteAssetPrefix = \`\${remoteAssetOrigin.replace(/\\/+$/u, '')}/\`;
|
|
27
27
|
const defaultAssetPrefix = defaultRemoteAssetPrefix;`;
|
|
28
|
+
const devAssetPrefixSource = 'shell' === app.kind ? ` // Keep shell dev assets origin-relative so the shell works through
|
|
29
|
+
// tunnels and local previews without rewriting its own chunks.
|
|
30
|
+
assetPrefix: '/',` : ` // Remote dev manifests must publish an absolute publicPath so host
|
|
31
|
+
// shells load remoteEntry.js and exposed chunks from this dev server.
|
|
32
|
+
assetPrefix,`;
|
|
28
33
|
return `// @effect-diagnostics processEnv:off
|
|
29
34
|
import {
|
|
30
35
|
appTools,
|
|
@@ -93,8 +98,10 @@ ${defaultAssetPrefixSource}
|
|
|
93
98
|
// load remoteEntry.js and exposed chunks from the remote origin, not the host.
|
|
94
99
|
const assetPrefix =
|
|
95
100
|
configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix;
|
|
96
|
-
const
|
|
97
|
-
const
|
|
101
|
+
const buildTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';
|
|
102
|
+
const buildOutputRoot = cloudflareDeployEnabled ? 'dist-cloudflare' : 'dist';
|
|
103
|
+
const buildTempDirectory = \`node_modules/.modern-js-\${appId}-\${buildTarget}\`;
|
|
104
|
+
const buildCacheDirectory = \`node_modules/.cache/rspack-\${appId}-\${buildTarget}\`;
|
|
98
105
|
|
|
99
106
|
if (
|
|
100
107
|
cloudflareDeployEnabled &&
|
|
@@ -124,9 +131,7 @@ ${bffConfig} ...(cloudflareDeployEnabled
|
|
|
124
131
|
}
|
|
125
132
|
: {}),
|
|
126
133
|
dev: {
|
|
127
|
-
|
|
128
|
-
// http://localhost:<port> prefix breaks pages served through tunnels.
|
|
129
|
-
assetPrefix: '/',
|
|
134
|
+
${devAssetPrefixSource}
|
|
130
135
|
},
|
|
131
136
|
html: {
|
|
132
137
|
outputStructure: 'flat',
|
|
@@ -136,13 +141,15 @@ ${bffConfig} ...(cloudflareDeployEnabled
|
|
|
136
141
|
disableTsChecker: false,
|
|
137
142
|
distPath: {
|
|
138
143
|
html: './',
|
|
144
|
+
root: buildOutputRoot,
|
|
139
145
|
},
|
|
140
146
|
polyfill: 'off',
|
|
141
147
|
splitRouteChunks: true,
|
|
148
|
+
tempDir: buildTempDirectory,
|
|
142
149
|
},
|
|
143
150
|
performance: {
|
|
144
151
|
buildCache: {
|
|
145
|
-
cacheDigest: [appId,
|
|
152
|
+
cacheDigest: [appId, buildTarget],
|
|
146
153
|
cacheDirectory: buildCacheDirectory,
|
|
147
154
|
},
|
|
148
155
|
rsdoctor: {
|