@nativescript/vite 8.0.0-alpha.14 → 8.0.0-alpha.16
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/configuration/base.js +20 -1
- package/configuration/base.js.map +1 -1
- package/configuration/solid.js +25 -19
- package/configuration/solid.js.map +1 -1
- package/helpers/main-entry.js +43 -8
- package/helpers/main-entry.js.map +1 -1
- package/helpers/ns-core-url.d.ts +8 -3
- package/helpers/ns-core-url.js +32 -8
- package/helpers/ns-core-url.js.map +1 -1
- package/helpers/solid-jsx-deps.d.ts +15 -0
- package/helpers/solid-jsx-deps.js +178 -0
- package/helpers/solid-jsx-deps.js.map +1 -0
- package/hmr/client/index.js +36 -5
- package/hmr/client/index.js.map +1 -1
- package/hmr/client/vue-sfc-update-overlay.d.ts +82 -0
- package/hmr/client/vue-sfc-update-overlay.js +133 -0
- package/hmr/client/vue-sfc-update-overlay.js.map +1 -0
- package/hmr/entry-runtime.d.ts +1 -1
- package/hmr/entry-runtime.js +59 -14
- package/hmr/entry-runtime.js.map +1 -1
- package/hmr/helpers/ast-normalizer.js +45 -5
- package/hmr/helpers/ast-normalizer.js.map +1 -1
- package/hmr/server/core-sanitize.d.ts +25 -6
- package/hmr/server/core-sanitize.js +69 -28
- package/hmr/server/core-sanitize.js.map +1 -1
- package/hmr/server/import-map.js +22 -5
- package/hmr/server/import-map.js.map +1 -1
- package/hmr/server/websocket-core-bridge.d.ts +41 -4
- package/hmr/server/websocket-core-bridge.js +42 -42
- package/hmr/server/websocket-core-bridge.js.map +1 -1
- package/hmr/server/websocket-ns-m-finalize.js +6 -6
- package/hmr/server/websocket-ns-m-finalize.js.map +1 -1
- package/hmr/server/websocket-runtime-compat.js +6 -1
- package/hmr/server/websocket-runtime-compat.js.map +1 -1
- package/hmr/server/websocket-served-module-helpers.js +2 -2
- package/hmr/server/websocket-served-module-helpers.js.map +1 -1
- package/hmr/server/websocket-vue-sfc.d.ts +0 -1
- package/hmr/server/websocket-vue-sfc.js +0 -16
- package/hmr/server/websocket-vue-sfc.js.map +1 -1
- package/hmr/server/websocket.d.ts +1 -1
- package/hmr/server/websocket.js +153 -78
- package/hmr/server/websocket.js.map +1 -1
- package/hmr/shared/runtime/boot-placeholder-ui.d.ts +1 -1
- package/hmr/shared/runtime/boot-placeholder-ui.js +1 -1
- package/hmr/shared/runtime/boot-progress.d.ts +1 -1
- package/hmr/shared/runtime/boot-progress.js +2 -2
- package/hmr/shared/runtime/boot-progress.js.map +1 -1
- package/hmr/shared/vendor/manifest.js +73 -2
- package/hmr/shared/vendor/manifest.js.map +1 -1
- package/package.json +1 -1
package/hmr/server/websocket.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
|
-
import {
|
|
2
|
+
import { sanitizeStrayCoreReferences, isDeepCoreSubpath, rewriteSpecifiersForDevice } from './core-sanitize.js';
|
|
3
3
|
import { buildDefaultExportFooter, buildShapeInstallHeader, hasNamespaceReExport, rewriteNamespaceReExportsForShape } from './ns-core-cjs-shape.js';
|
|
4
4
|
// AST tooling for robust transformations
|
|
5
5
|
import { parse as babelParse } from '@babel/parser';
|
|
@@ -33,7 +33,7 @@ import { astExtractImportsAndStripTypes } from '../helpers/ast-extract.js';
|
|
|
33
33
|
import { getProjectAppPath, getProjectAppRelativePath, getProjectAppVirtualPath } from '../../helpers/utils.js';
|
|
34
34
|
import { buildRuntimeConfig, generateImportMap } from './import-map.js';
|
|
35
35
|
import { getCliFlags } from '../../helpers/cli-flags.js';
|
|
36
|
-
import { normalizeCoreSub as normalizeCoreSubCanonical } from '../../helpers/ns-core-url.js';
|
|
36
|
+
import { buildCoreUrl, buildCoreUrlPath, normalizeCoreSub as normalizeCoreSubCanonical } from '../../helpers/ns-core-url.js';
|
|
37
37
|
import { isRuntimeGraphExcludedPath, matchesRuntimeGraphModuleId, normalizeRuntimeGraphPath, shouldIncludeRuntimeGraphFile, shouldSkipRuntimeGraphDirectoryName } from './runtime-graph-filter.js';
|
|
38
38
|
import { resolveAngularCoreHmrImportSource, rewriteAngularEntryRegisterOnly } from './websocket-angular-entry.js';
|
|
39
39
|
import { angularSourceHasSemanticDecorator, canonicalizeTransformRequestCacheKey, collectAngularEvictionUrls, collectAngularHotUpdateRoots, collectAngularTransformCacheInvalidationUrls, collectAngularTransitiveImportersForInvalidation, collectGraphUpdateModulesForHotUpdate, normalizeHotReloadMatchPath, shouldInvalidateAngularTransitiveImporters, shouldSuppressDefaultViteHotUpdate, shouldSuppressViteFullReloadPayload } from './websocket-angular-hot-update.js';
|
|
@@ -43,13 +43,13 @@ import { classifyBootRoute, classifyHmrUpdateKind, createColdBootRequestCounter,
|
|
|
43
43
|
import { createHmrPendingMessage } from './websocket-hmr-pending.js';
|
|
44
44
|
import { extractVitePrebundleId, filterExistingNodeModulesTransformCandidates, getBlockedDeviceNodeModulesReason, getFlattenedManifestMap, isCoreGlobalsReference, isEsmFrameworkPackageSpecifier, isLikelyNativeScriptPluginSpecifier, isLikelyNativeScriptRuntimePluginSpecifier, isNativeScriptCoreModule, isNativeScriptPluginModule, normalizeNativeScriptCoreSpecifier, normalizeNodeModulesSpecifier, resolveCandidateFilePath, resolveInternalRuntimePluginBareSpecifier, resolveNodeModulesPackageBoundary, resolveVendorFromCandidate, resolveVendorRouting, rewriteFsAbsoluteToNsM, shouldPreserveBareRuntimePluginSubpathImport, stripDecoratedServePrefixes, tryReadRawExplicitJavaScriptModule, viteDepsPathToBareSpecifier, } from './websocket-module-specifiers.js';
|
|
45
45
|
import { ensureNativeScriptModuleBindings, getProcessCodeResolvedSpecifierOverrides } from './websocket-module-bindings.js';
|
|
46
|
-
import { collectStaticExportNamesFromFile, collectStaticExportOriginsFromFile,
|
|
46
|
+
import { collectStaticExportNamesFromFile, collectStaticExportOriginsFromFile, extractDirectExportedNames, normalizeCoreExportOriginsForRuntime, parseCoreBridgeRequest, resolveRuntimeCoreModulePath } from './websocket-core-bridge.js';
|
|
47
47
|
import { createSharedTransformRequestRunner } from './shared-transform-request.js';
|
|
48
48
|
import { formatNsMHmrServeTag, getNumericServeVersionTag, rewriteNsMImportPathForHmr } from './websocket-ns-m-paths.js';
|
|
49
49
|
import { ensureDynamicHmrImportHelper } from './websocket-served-module-helpers.js';
|
|
50
50
|
export { ensureNativeScriptModuleBindings, getProcessCodeResolvedSpecifierOverrides } from './websocket-module-bindings.js';
|
|
51
51
|
export { stripDecoratedServePrefixes, tryReadRawExplicitJavaScriptModule } from './websocket-module-specifiers.js';
|
|
52
|
-
export { collectStaticExportNamesFromFile, collectStaticExportOriginsFromFile,
|
|
52
|
+
export { collectStaticExportNamesFromFile, collectStaticExportOriginsFromFile, normalizeCoreExportOriginsForRuntime, parseCoreBridgeRequest } from './websocket-core-bridge.js';
|
|
53
53
|
export { rewriteAngularEntryRegisterOnly } from './websocket-angular-entry.js';
|
|
54
54
|
// Re-export the canonical URL rewriter from `websocket-ns-m-paths.js` so the
|
|
55
55
|
// existing test suites (which import from `./websocket.js`) keep working
|
|
@@ -458,8 +458,7 @@ function stripViteDynamicImportVirtual(code) {
|
|
|
458
458
|
// is install-once-per-isolate, dedupes per-URL (so semver's ~30 deep
|
|
459
459
|
// imports produce ~30 lines on the first boot and 0 on subsequent
|
|
460
460
|
// boots within the same isolate), and uses `console.warn` so the
|
|
461
|
-
// message reads as advisory
|
|
462
|
-
// LATEST-05-07-2026-HMR_ANGULAR_DEBUG_SESSION.md). Forensic detail
|
|
461
|
+
// message reads as advisory. Forensic detail
|
|
463
462
|
// (stack) lives on `globalThis.__NS_REQUIRE_GUARD_LAST__` for
|
|
464
463
|
// post-mortem inspection. Set `globalThis.__NS_REQUIRE_GUARD_VERBOSE__`
|
|
465
464
|
// to `true` before any module loads to restore per-call logging.
|
|
@@ -1209,6 +1208,22 @@ function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = fa
|
|
|
1209
1208
|
// Running the normalizer on libraries like tslib injects harmful destructures
|
|
1210
1209
|
// (e.g., `const { SuppressedError } = __ns_rt_ns_1`) that shadow globals.
|
|
1211
1210
|
if (!isNodeModule) {
|
|
1211
|
+
// CRITICAL ORDERING: canonicalise any bare `@nativescript/core[/sub]`
|
|
1212
|
+
// specifiers to `/ns/core[/sub]` BEFORE the AST normaliser sees them.
|
|
1213
|
+
// `astNormalizeModuleImportsAndHelpers` defensively rewrites bare
|
|
1214
|
+
// `@nativescript/core` imports and emits a one-shot
|
|
1215
|
+
// `[ast-normalizer] unexpected @nativescript/core spec` warning —
|
|
1216
|
+
// the warning means the upstream rewriter regressed. For Vue SFC
|
|
1217
|
+
// `<script>` blocks the bare specifier flows through Vite's
|
|
1218
|
+
// transform pipeline without a per-statement source-string rewrite
|
|
1219
|
+
// (Vite's resolver only edits the module graph, not the emitted
|
|
1220
|
+
// code), so the only upstream rewriter that can canonicalise these
|
|
1221
|
+
// in dev mode is this regex sweep. Running it here keeps the AST
|
|
1222
|
+
// normaliser purely a tripwire instead of an active rewriter.
|
|
1223
|
+
try {
|
|
1224
|
+
result = sanitizeStrayCoreReferences(result);
|
|
1225
|
+
}
|
|
1226
|
+
catch { }
|
|
1212
1227
|
try {
|
|
1213
1228
|
result = astNormalizeModuleImportsAndHelpers(result);
|
|
1214
1229
|
}
|
|
@@ -1413,8 +1428,7 @@ function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = fa
|
|
|
1413
1428
|
const vendorCoreRE1 = /globalThis\.__nsVendor\s*\(\s*["']@nativescript\/core["']\s*\)/g;
|
|
1414
1429
|
const vendorCoreRE2 = /__nsVendor\s*\(\s*["']@nativescript\/core["']\s*\)/g;
|
|
1415
1430
|
if (vendorCoreRE1.test(result) || vendorCoreRE2.test(result)) {
|
|
1416
|
-
|
|
1417
|
-
const hasImport = /import\s+__ns_core_bridge\s+from\s+["'][^"']*\/(?:\@ns|ns)\/core(?:\/[\d]+)?(?:\?p=[^"']+)?["']\s*;?/.test(result) || /(^|\n)\s*import\s+__ns_core_bridge\s+from\s+["']\/(?:\@ns|ns)\/core["']\s*;?/m.test(result);
|
|
1431
|
+
const hasImport = /import\s+__ns_core_bridge\s+from\s+["'][^"']*\/(?:\@ns|ns)\/core(?:\/[^"']+)?["']\s*;?/.test(result) || /(^|\n)\s*import\s+__ns_core_bridge\s+from\s+["']\/(?:\@ns|ns)\/core["']\s*;?/m.test(result);
|
|
1418
1432
|
if (!hasImport) {
|
|
1419
1433
|
result = `import __ns_core_bridge from "/ns/core";\n` + result;
|
|
1420
1434
|
}
|
|
@@ -1428,7 +1442,7 @@ function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = fa
|
|
|
1428
1442
|
const reqCoreRE1 = /(^|[^.\w$])require\(\s*["']@nativescript\/core([^"'\n]*)["']\s*\)/g;
|
|
1429
1443
|
const reqCoreRE2 = /(?:globalThis|window|self)\.require\(\s*["']@nativescript\/core([^"'\n]*)["']\s*\)/g;
|
|
1430
1444
|
if (reqCoreRE1.test(result) || reqCoreRE2.test(result)) {
|
|
1431
|
-
const hasImport = /import\s+__ns_core_bridge\s+from\s+["'][^"']*\/(?:\@ns|ns)\/core(?:\/[
|
|
1445
|
+
const hasImport = /import\s+__ns_core_bridge\s+from\s+["'][^"']*\/(?:\@ns|ns)\/core(?:\/[^"']+)?["']\s*;?/.test(result) || /(^|\n)\s*import\s+__ns_core_bridge\s+from\s+["']\/(?:\@ns|ns)\/core["']\s*;?/m.test(result);
|
|
1432
1446
|
if (!hasImport) {
|
|
1433
1447
|
result = `import __ns_core_bridge from "/ns/core";\n` + result;
|
|
1434
1448
|
}
|
|
@@ -1437,21 +1451,11 @@ function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = fa
|
|
|
1437
1451
|
}
|
|
1438
1452
|
}
|
|
1439
1453
|
catch { }
|
|
1440
|
-
//
|
|
1441
|
-
//
|
|
1442
|
-
//
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
}
|
|
1446
|
-
catch { }
|
|
1447
|
-
try {
|
|
1448
|
-
result = fixDanglingCoreFrom(result);
|
|
1449
|
-
}
|
|
1450
|
-
catch { }
|
|
1451
|
-
try {
|
|
1452
|
-
result = normalizeAnyCoreSpecToBridge(result);
|
|
1453
|
-
}
|
|
1454
|
-
catch { }
|
|
1454
|
+
// Apply the three-pass safety net for stray @nativescript/core references
|
|
1455
|
+
// (naked string literals, dangling `from` merges, lingering resolved-path
|
|
1456
|
+
// references). Centralised in core-sanitize.sanitizeStrayCoreReferences so
|
|
1457
|
+
// every NS-M emitter applies the same passes in the same order.
|
|
1458
|
+
result = sanitizeStrayCoreReferences(result);
|
|
1455
1459
|
result = ensureVariableDynamicImportHelper(result);
|
|
1456
1460
|
// Normalize any lingering @nativescript/core imports to the /ns/core bridge (non-destructive best-effort)
|
|
1457
1461
|
try {
|
|
@@ -1468,7 +1472,7 @@ function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = fa
|
|
|
1468
1472
|
return m.length === 2 ? `${m[0].trim()}: ${m[1].trim()}` : seg;
|
|
1469
1473
|
})
|
|
1470
1474
|
.join(', ');
|
|
1471
|
-
const reNamed = /(^|\n)\s*import\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[
|
|
1475
|
+
const reNamed = /(^|\n)\s*import\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[^"']+)?)['"];?\s*/gm;
|
|
1472
1476
|
result = result.replace(reNamed, (_full, pfx, specList, src) => {
|
|
1473
1477
|
// Deep subpath URLs serve actual ESM with real named exports — skip.
|
|
1474
1478
|
if (isDeepCoreSubpath(src))
|
|
@@ -1478,7 +1482,7 @@ function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = fa
|
|
|
1478
1482
|
const decl = `const { ${toDestructureCore(specList)} } = ${tmp};`;
|
|
1479
1483
|
return `${pfx}import ${tmp} from ${JSON.stringify(src)};\n${decl}\n`;
|
|
1480
1484
|
});
|
|
1481
|
-
const reMixed = /(^|\n)\s*import\s+([A-Za-z_$][\w$]*)\s*,\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[
|
|
1485
|
+
const reMixed = /(^|\n)\s*import\s+([A-Za-z_$][\w$]*)\s*,\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[^"']+)?)['"];?\s*/gm;
|
|
1482
1486
|
result = result.replace(reMixed, (_full, pfx, defName, specList, src) => {
|
|
1483
1487
|
if (isDeepCoreSubpath(src))
|
|
1484
1488
|
return _full;
|
|
@@ -1723,7 +1727,10 @@ function assertNoOptimizedArtifacts(code, contextLabel) {
|
|
|
1723
1727
|
}
|
|
1724
1728
|
}
|
|
1725
1729
|
// Ensure there are no lingering named imports from the unified core bridge.
|
|
1726
|
-
// Converts named imports from
|
|
1730
|
+
// Converts named imports from `/ns/core[/<sub>]` into default import +
|
|
1731
|
+
// destructuring. The package-main bridge serves a shape-shifted module whose
|
|
1732
|
+
// named exports come from `__ns_core_bridge.default` rather than ESM named
|
|
1733
|
+
// exports, so a named-import binding would be `undefined` at evaluation.
|
|
1727
1734
|
function ensureDestructureCoreImports(code) {
|
|
1728
1735
|
try {
|
|
1729
1736
|
let result = code;
|
|
@@ -1737,8 +1744,8 @@ function ensureDestructureCoreImports(code) {
|
|
|
1737
1744
|
return m.length === 2 ? `${m[0].trim()}: ${m[1].trim()}` : seg;
|
|
1738
1745
|
})
|
|
1739
1746
|
.join(', ');
|
|
1740
|
-
// import { A, B } from '/ns/core[
|
|
1741
|
-
const reNamed = /(^|\n)\s*import\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[
|
|
1747
|
+
// import { A, B } from '/ns/core[/<sub>]'
|
|
1748
|
+
const reNamed = /(^|\n)\s*import\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[^"']+)?)['"];?\s*/gm;
|
|
1742
1749
|
result = result.replace(reNamed, (_full, pfx, specList, src) => {
|
|
1743
1750
|
// Deep subpath URLs serve actual ESM with real named exports — skip.
|
|
1744
1751
|
if (isDeepCoreSubpath(src))
|
|
@@ -1748,8 +1755,8 @@ function ensureDestructureCoreImports(code) {
|
|
|
1748
1755
|
const decl = `const { ${toDestructure(specList)} } = ${tmp};`;
|
|
1749
1756
|
return `${pfx}import ${tmp} from ${JSON.stringify(src)};\n${decl}\n`;
|
|
1750
1757
|
});
|
|
1751
|
-
// import Default, { A, B } from '/ns/core[
|
|
1752
|
-
const reMixed = /(^|\n)\s*import\s+([A-Za-z_$][\w$]*)\s*,\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[
|
|
1758
|
+
// import Default, { A, B } from '/ns/core[/<sub>]'
|
|
1759
|
+
const reMixed = /(^|\n)\s*import\s+([A-Za-z_$][\w$]*)\s*,\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[^"']+)?)['"];?\s*/gm;
|
|
1753
1760
|
result = result.replace(reMixed, (_full, pfx, defName, specList, src) => {
|
|
1754
1761
|
if (isDeepCoreSubpath(src))
|
|
1755
1762
|
return _full;
|
|
@@ -1866,6 +1873,27 @@ function dedupeRtNamedImportsAgainstDestructures(code) {
|
|
|
1866
1873
|
*/
|
|
1867
1874
|
export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, projectRoot, verbose = false, outputDirOverrideRel, httpOrigin, resolveVendorAsHttp = false) {
|
|
1868
1875
|
let result = code;
|
|
1876
|
+
// Pre-normalize concatenated imports onto their own lines.
|
|
1877
|
+
//
|
|
1878
|
+
// Babel's `genCode(ast, { retainLines: true })` in
|
|
1879
|
+
// `astNormalizeModuleImportsAndHelpers` (which runs before us in the SFC
|
|
1880
|
+
// asm pipeline, and in several other hot paths) can emit multiple
|
|
1881
|
+
// statements on a single line, e.g.:
|
|
1882
|
+
// `} = __ns_rt_ns_1;import { $goTo } from "../utils";import PageWrapper from ...;`
|
|
1883
|
+
//
|
|
1884
|
+
// IMPORT_PATTERN_1/_2/_3/SIDE_EFFECT all anchor on `(?:^|\n)\s*import`,
|
|
1885
|
+
// so any import past the first one on a single line is silently dropped
|
|
1886
|
+
// by the rewriter. Downstream that leaves bare relative specifiers like
|
|
1887
|
+
// `../utils` to be resolved by the iOS HTTP ESM loader, which interprets
|
|
1888
|
+
// them relative to the `/ns/asm/0?path=...` URL and 404s on the
|
|
1889
|
+
// resulting `/ns/utils`. Splitting `;import` onto its own line makes the
|
|
1890
|
+
// existing patterns match every import, restoring the rewrite contract.
|
|
1891
|
+
//
|
|
1892
|
+
// Mirrors the same normalization already performed in
|
|
1893
|
+
// `core-sanitize.ts::normalizeStrayCoreStringLiterals` (`;\s*import` →
|
|
1894
|
+
// `;\nimport`) but applied universally at the rewriter entry point so
|
|
1895
|
+
// every caller benefits without having to opt in.
|
|
1896
|
+
result = result.replace(/;\s*import\s+/g, ';\nimport ');
|
|
1869
1897
|
const httpOriginSafe = httpOrigin;
|
|
1870
1898
|
const mixedRuntimePluginHttpRootPackages = collectMixedRuntimePluginHttpRootPackages(result, projectRoot);
|
|
1871
1899
|
const isDynamicImportPrefix = (prefix) => /import\(\s*["']?$/.test(prefix.trimStart());
|
|
@@ -1883,10 +1911,31 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
|
|
|
1883
1911
|
try {
|
|
1884
1912
|
let coreAliasIdx = 0;
|
|
1885
1913
|
const mkAlias = () => `__NSC${coreAliasIdx++}`;
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1914
|
+
// Use the canonical PATH form `/ns/core/<sub>`. The iOS HTTP ESM
|
|
1915
|
+
// loader caches module records by URL string — every emitter
|
|
1916
|
+
// (`buildCoreUrl()` / `buildCoreUrlPath()`, the runtime import map,
|
|
1917
|
+
// vendor `require()` shims, app-side rewrites, the cold-boot
|
|
1918
|
+
// preload in `entry-runtime.ts`) MUST produce the same byte
|
|
1919
|
+
// string for the same logical core subpath. A divergence creates
|
|
1920
|
+
// two distinct V8 module records for the same source. Each gets
|
|
1921
|
+
// its own class
|
|
1922
|
+
// identities (TextBase, View, etc.), and side-effect patches
|
|
1923
|
+
// applied to one (e.g. @nativescript-community/text's
|
|
1924
|
+
// `TextBase.prototype.setTextDecorationAndTransform` override
|
|
1925
|
+
// installed when vendor.mjs evaluates `overrideSpanAndFormattedString()`
|
|
1926
|
+
// from `@nativescript-community/ui-label/index-common.js`) are
|
|
1927
|
+
// invisible to the other — manifesting as inconsistent line-height /
|
|
1928
|
+
// letter-spacing rendering between HMR and no-HMR.
|
|
1929
|
+
//
|
|
1930
|
+
// Mirrors `normalizeCoreSub()` (helpers/ns-core-url.ts) so the URL
|
|
1931
|
+
// produced here is byte-identical to what `buildCoreUrl()` produces
|
|
1932
|
+
// for the bundle entry, import map, and external-urls plugin.
|
|
1933
|
+
// Delegate to the ONE canonical URL builder so every emitter (this
|
|
1934
|
+
// rewriter, core-sanitize, the runtime import map, the ns-core-external-urls
|
|
1935
|
+
// build plugin, and main-entry) produces byte-identical URLs for
|
|
1936
|
+
// the same logical core module. Any drift here would re-introduce
|
|
1937
|
+
// the realm-split bug.
|
|
1938
|
+
const coreUrl = (sub) => (httpOriginSafe ? buildCoreUrl(httpOriginSafe, sub) : buildCoreUrlPath(sub));
|
|
1890
1939
|
// Case 1: import { A, B } from '@nativescript/core[/sub]'
|
|
1891
1940
|
result = result.replace(/(^|\n)\s*import\s*\{\s*([^}]+?)\s*\}\s*from\s+["']@nativescript\/core([^"'\n]*)["'];?/g, (_m, pfx, names, sub) => {
|
|
1892
1941
|
const alias = mkAlias();
|
|
@@ -2238,6 +2287,40 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
|
|
|
2238
2287
|
return `${prefix}./${depFile}${suffix}`;
|
|
2239
2288
|
}
|
|
2240
2289
|
}
|
|
2290
|
+
// ── Bare specifier vendor routing ────────────────────────────
|
|
2291
|
+
// Bare specifiers like `pinia`, `dayjs`, `lodash` never reach
|
|
2292
|
+
// the `nodeModulesSpecifier` branch above because
|
|
2293
|
+
// `normalizeNodeModulesSpecifier` keys on a literal
|
|
2294
|
+
// `/node_modules/` segment in the path. Without this check
|
|
2295
|
+
// they'd fall straight into the HTTP fallback below and get
|
|
2296
|
+
// rewritten to `/ns/m/node_modules/<spec>`, which serves the
|
|
2297
|
+
// package source over HTTP and bypasses the device-side import
|
|
2298
|
+
// map's `<pkg>` → `ns-vendor://<pkg>` entry. For CJS/UMD
|
|
2299
|
+
// packages (e.g. Pinia) the bare HTTP path doesn't expose the
|
|
2300
|
+
// full named-exports surface (only the default export round-
|
|
2301
|
+
// trips), so consumers like
|
|
2302
|
+
// `import { defineStore } from "pinia"` blow up at instantiate
|
|
2303
|
+
// time with `SyntaxError: ... does not provide an export named
|
|
2304
|
+
// 'defineStore'`. Preserving the bare spec lets the vendor
|
|
2305
|
+
// bridge serve it from the prebuilt `bundle.mjs`, which already
|
|
2306
|
+
// re-exports the full CJS surface. Subpath imports
|
|
2307
|
+
// (`pinia/plugins/foo`) intentionally fall through to the
|
|
2308
|
+
// HTTP fallback — `resolveVendorRouting` returns
|
|
2309
|
+
// `{ route: 'http' }` for non-main-entry subpaths even when the
|
|
2310
|
+
// root package is in the manifest, mirroring the
|
|
2311
|
+
// `nodeModulesSpecifier` branch.
|
|
2312
|
+
if (spec && !spec.startsWith('/') && !spec.startsWith('./') && !spec.startsWith('../') && !/^https?:\/\//i.test(spec) && !spec.startsWith('ns-vendor:') && !spec.startsWith('@nativescript/core')) {
|
|
2313
|
+
const bareNpmRe = /^(?:@[A-Za-z0-9][\w.-]*\/)?[A-Za-z0-9][\w.-]*(?:\/[\w.\-/]+)?$/;
|
|
2314
|
+
if (bareNpmRe.test(spec)) {
|
|
2315
|
+
const bareVendorRouting = resolveVendorRouting(spec, projectRoot);
|
|
2316
|
+
if (bareVendorRouting?.route === 'vendor') {
|
|
2317
|
+
if (verbose) {
|
|
2318
|
+
console.log(`[rewrite] bare vendor import: ${spec} → ${bareVendorRouting.bareSpec}`);
|
|
2319
|
+
}
|
|
2320
|
+
return `${prefix}${bareVendorRouting.bareSpec}${suffix}`;
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2241
2324
|
// Bare npm package specifier fallback — route to /ns/m/node_modules/.
|
|
2242
2325
|
// This catches specifiers like `source-map-js/lib/source-map-generator.js`
|
|
2243
2326
|
// emitted by helpers such as the CommonJS compat transform, which Vite
|
|
@@ -3133,7 +3216,6 @@ function createHmrWebSocketPlugin(opts) {
|
|
|
3133
3216
|
const origin = getServerOrigin(server);
|
|
3134
3217
|
code = ensureVersionedRtImports(code, origin, graphVersion);
|
|
3135
3218
|
code = ACTIVE_STRATEGY.ensureVersionedImports(code, origin, graphVersion);
|
|
3136
|
-
code = ensureVersionedCoreImports(code, origin, graphVersion);
|
|
3137
3219
|
}
|
|
3138
3220
|
catch { }
|
|
3139
3221
|
// Compute rel .mjs output path
|
|
@@ -3190,7 +3272,6 @@ function createHmrWebSocketPlugin(opts) {
|
|
|
3190
3272
|
try {
|
|
3191
3273
|
depCode = ensureVersionedRtImports(depCode, getServerOrigin(server), graphVersion);
|
|
3192
3274
|
depCode = ACTIVE_STRATEGY.ensureVersionedImports(depCode, getServerOrigin(server), graphVersion);
|
|
3193
|
-
depCode = ensureVersionedCoreImports(depCode, getServerOrigin(server), graphVersion);
|
|
3194
3275
|
}
|
|
3195
3276
|
catch { }
|
|
3196
3277
|
let depRel = depResolved.replace(/^\//, '').replace(/\.(tsx?|jsx?)$/i, '.mjs');
|
|
@@ -3838,16 +3919,14 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
3838
3919
|
code = ensureGuardPlainDynamicImports(code, getServerOrigin(server));
|
|
3839
3920
|
}
|
|
3840
3921
|
catch { }
|
|
3841
|
-
// Extra hardening
|
|
3842
|
-
// -
|
|
3843
|
-
//
|
|
3844
|
-
//
|
|
3845
|
-
//
|
|
3922
|
+
// Extra hardening before the fast-fail assertion: run the
|
|
3923
|
+
// consolidated stray-core-reference safety net. If any
|
|
3924
|
+
// rewrite occurred, leave a diagnostic marker so the
|
|
3925
|
+
// pipeline review log explains why the served code carries
|
|
3926
|
+
// it.
|
|
3846
3927
|
try {
|
|
3847
3928
|
const __before = code;
|
|
3848
|
-
code =
|
|
3849
|
-
code = fixDanglingCoreFrom(code);
|
|
3850
|
-
code = normalizeAnyCoreSpecToBridge(code);
|
|
3929
|
+
code = sanitizeStrayCoreReferences(code);
|
|
3851
3930
|
if (code !== __before) {
|
|
3852
3931
|
code = `// [hmr-sanitize] core-literal->bridge\n` + code;
|
|
3853
3932
|
}
|
|
@@ -3920,7 +3999,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
3920
3999
|
const verNum = 0;
|
|
3921
4000
|
code = ensureVersionedRtImports(code, getServerOrigin(server), verNum);
|
|
3922
4001
|
code = ACTIVE_STRATEGY.ensureVersionedImports(code, getServerOrigin(server), verNum);
|
|
3923
|
-
code = ensureVersionedCoreImports(code, getServerOrigin(server), verNum);
|
|
3924
4002
|
}
|
|
3925
4003
|
catch { }
|
|
3926
4004
|
// `/ns/m` URL finalize step.
|
|
@@ -4135,7 +4213,12 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
4135
4213
|
const origin = getServerOrigin(server);
|
|
4136
4214
|
let code = `// [ns-rt][v2.3] NativeScript-Vue runtime bridge (module-scoped cache, no globals)\n` +
|
|
4137
4215
|
`const __origin = ((typeof globalThis !== 'undefined' && globalThis && globalThis.__NS_HTTP_ORIGIN__) || (new URL(import.meta.url)).origin);\n` +
|
|
4138
|
-
|
|
4216
|
+
// Always target the canonical, unversioned `/ns/core` URL — the
|
|
4217
|
+
// runtime import map maps bare `@nativescript/core` to the same
|
|
4218
|
+
// URL, so vendor `require('@nativescript/core')` and this dynamic
|
|
4219
|
+
// import end up at one iOS HTTP-ESM module record (and one class
|
|
4220
|
+
// identity realm).
|
|
4221
|
+
`let __ns_core_bridge = null; try { import(__origin + "/ns/core").then(m => { __ns_core_bridge = m; }).catch(() => {}); } catch {}\n` +
|
|
4139
4222
|
`const g = globalThis;\n` +
|
|
4140
4223
|
`const reg = (g.__nsVendorRegistry ||= new Map());\n` +
|
|
4141
4224
|
`const req = reg && reg.get ? (g.__nsVendorRequire || g.__nsRequire || g.require) : (g.__nsRequire || g.require);\n` +
|
|
@@ -4358,7 +4441,7 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
4358
4441
|
return next();
|
|
4359
4442
|
}
|
|
4360
4443
|
});
|
|
4361
|
-
// 2.6) ESM bridge for @nativescript/core: GET /ns/core[/<
|
|
4444
|
+
// 2.6) ESM bridge for @nativescript/core: GET /ns/core[/<sub>]
|
|
4362
4445
|
//
|
|
4363
4446
|
// Since bundle.mjs no longer bundles @nativescript/core (it is
|
|
4364
4447
|
// declared external in the rolldown config under HMR), this
|
|
@@ -4382,12 +4465,29 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
4382
4465
|
const coreRequest = parseCoreBridgeRequest(urlObj.pathname, urlObj.searchParams, Number(graphVersion || 0));
|
|
4383
4466
|
if (!coreRequest)
|
|
4384
4467
|
return next();
|
|
4468
|
+
// Non-canonical incoming URL — every emitter is supposed
|
|
4469
|
+
// to canonicalize before hitting the device. Promote the
|
|
4470
|
+
// drift to a 301 redirect so iOS still gets the file at
|
|
4471
|
+
// the canonical URL (no realm split) but the offending
|
|
4472
|
+
// caller is forced to update. We log the offending raw
|
|
4473
|
+
// pathname so the regression source is easy to find.
|
|
4474
|
+
if (coreRequest.canonicalPath) {
|
|
4475
|
+
try {
|
|
4476
|
+
console.warn(`[ns-core-bridge] 301 ${urlObj.pathname}${urlObj.search} → ${coreRequest.canonicalPath} (non-canonical core URL — please update emitter)`);
|
|
4477
|
+
}
|
|
4478
|
+
catch { }
|
|
4479
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
4480
|
+
res.setHeader('Location', coreRequest.canonicalPath);
|
|
4481
|
+
res.statusCode = 301;
|
|
4482
|
+
res.end();
|
|
4483
|
+
return;
|
|
4484
|
+
}
|
|
4385
4485
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
4386
4486
|
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
|
4387
4487
|
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
|
|
4388
4488
|
res.setHeader('Pragma', 'no-cache');
|
|
4389
4489
|
res.setHeader('Expires', '0');
|
|
4390
|
-
const { normalizedSub, sub
|
|
4490
|
+
const { normalizedSub, sub } = coreRequest;
|
|
4391
4491
|
const resolveModuleId = async (moduleId) => {
|
|
4392
4492
|
const resolved = await server.pluginContainer?.resolveId?.(moduleId, undefined);
|
|
4393
4493
|
return typeof resolved === 'string' ? resolved : resolved?.id || null;
|
|
@@ -4413,7 +4513,7 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
4413
4513
|
// Vite's transform output references module IDs with /@fs,
|
|
4414
4514
|
// relative specifiers, or absolute project paths. Rewrite
|
|
4415
4515
|
// those to URLs iOS can fetch over HTTP.
|
|
4416
|
-
let rewritten = rewriteSpecifiersForDevice(transformed.code, getServerOrigin(server), Number(
|
|
4516
|
+
let rewritten = rewriteSpecifiersForDevice(transformed.code, getServerOrigin(server), Number(graphVersion || 0));
|
|
4417
4517
|
// Invariant D (CJS/ESM interop shape) — EXPORT-SIDE fix.
|
|
4418
4518
|
//
|
|
4419
4519
|
// `@nativescript/core/index.js` declares namespace
|
|
@@ -5144,17 +5244,16 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5144
5244
|
code = ensureVariableDynamicImportHelper(code);
|
|
5145
5245
|
try {
|
|
5146
5246
|
// For variant requests under /ns/sfc, prefer the version from the path segment when present
|
|
5147
|
-
// so that any internal '/ns/rt'
|
|
5247
|
+
// so that any internal '/ns/rt' or '/ns/sfc' imports are aligned with the same version.
|
|
5248
|
+
// `/ns/core` URLs are intentionally unversioned (realm-split history).
|
|
5148
5249
|
const verNum = Number(verFromPath || '0');
|
|
5149
5250
|
if (Number.isFinite(verNum) && verNum > 0) {
|
|
5150
5251
|
code = ensureVersionedRtImports(code, getServerOrigin(server), verNum);
|
|
5151
5252
|
code = ACTIVE_STRATEGY.ensureVersionedImports(code, getServerOrigin(server), verNum);
|
|
5152
|
-
code = ensureVersionedCoreImports(code, getServerOrigin(server), verNum);
|
|
5153
5253
|
}
|
|
5154
5254
|
else {
|
|
5155
5255
|
code = ensureVersionedRtImports(code, getServerOrigin(server), graphVersion);
|
|
5156
5256
|
code = ACTIVE_STRATEGY.ensureVersionedImports(code, getServerOrigin(server), graphVersion);
|
|
5157
|
-
code = ensureVersionedCoreImports(code, getServerOrigin(server), graphVersion);
|
|
5158
5257
|
}
|
|
5159
5258
|
}
|
|
5160
5259
|
catch { }
|
|
@@ -5164,7 +5263,7 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5164
5263
|
}
|
|
5165
5264
|
catch { }
|
|
5166
5265
|
// CRITICAL: As a last step for script/template variants, re-run AST normalization and strip
|
|
5167
|
-
// any sentinel destructures that could cause duplicate locals, then re-apply
|
|
5266
|
+
// any sentinel destructures that could cause duplicate locals, then re-apply rt versioning.
|
|
5168
5267
|
try {
|
|
5169
5268
|
code = astNormalizeModuleImportsAndHelpers(code);
|
|
5170
5269
|
}
|
|
@@ -5178,11 +5277,9 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5178
5277
|
const verNum = Number(verFromPath || '0');
|
|
5179
5278
|
if (Number.isFinite(verNum) && verNum > 0) {
|
|
5180
5279
|
code = ensureVersionedRtImports(code, getServerOrigin(server), verNum);
|
|
5181
|
-
code = ensureVersionedCoreImports(code, getServerOrigin(server), verNum);
|
|
5182
5280
|
}
|
|
5183
5281
|
else {
|
|
5184
5282
|
code = ensureVersionedRtImports(code, getServerOrigin(server), graphVersion);
|
|
5185
|
-
code = ensureVersionedCoreImports(code, getServerOrigin(server), graphVersion);
|
|
5186
5283
|
}
|
|
5187
5284
|
}
|
|
5188
5285
|
catch { }
|
|
@@ -5595,10 +5692,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5595
5692
|
parts.push(`export default __ns_sfc__`);
|
|
5596
5693
|
let inlineCode = parts.filter(Boolean).join('\n');
|
|
5597
5694
|
inlineCode = processCodeForDevice(inlineCode, false, true);
|
|
5598
|
-
try {
|
|
5599
|
-
inlineCode = ensureVersionedCoreImports(inlineCode, getServerOrigin(server), Number(ver));
|
|
5600
|
-
}
|
|
5601
|
-
catch { }
|
|
5602
5695
|
try {
|
|
5603
5696
|
inlineCode = ensureDestructureCoreImports(inlineCode);
|
|
5604
5697
|
}
|
|
@@ -5665,10 +5758,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5665
5758
|
outParts.push('export default __ns_sfc__');
|
|
5666
5759
|
let inlineCode2 = outParts.filter(Boolean).join('\n');
|
|
5667
5760
|
inlineCode2 = processCodeForDevice(inlineCode2, false, true);
|
|
5668
|
-
try {
|
|
5669
|
-
inlineCode2 = ensureVersionedCoreImports(inlineCode2, getServerOrigin(server), Number(ver));
|
|
5670
|
-
}
|
|
5671
|
-
catch { }
|
|
5672
5761
|
try {
|
|
5673
5762
|
inlineCode2 = ensureDestructureCoreImports(inlineCode2);
|
|
5674
5763
|
}
|
|
@@ -5872,7 +5961,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5872
5961
|
const origin = getServerOrigin(server);
|
|
5873
5962
|
inlineCode2 = ensureVersionedRtImports(inlineCode2, origin, Number(ver));
|
|
5874
5963
|
inlineCode2 = ACTIVE_STRATEGY.ensureVersionedImports(inlineCode2, origin, Number(ver));
|
|
5875
|
-
inlineCode2 = ensureVersionedCoreImports(inlineCode2, origin, Number(ver));
|
|
5876
5964
|
}
|
|
5877
5965
|
catch { }
|
|
5878
5966
|
// Normalize imports/helpers via AST to ensure _defineComponent and other helpers are bound once
|
|
@@ -5976,10 +6064,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5976
6064
|
// Run full device processing so helper aliasing and globals are consistent in this path too
|
|
5977
6065
|
let code = REQUIRE_GUARD_SNIPPET + asm;
|
|
5978
6066
|
code = processCodeForDevice(code, false, true, /(?:^|\/)node_modules\//.test(base), base);
|
|
5979
|
-
try {
|
|
5980
|
-
code = ensureVersionedCoreImports(code, getServerOrigin(server), Number(ver));
|
|
5981
|
-
}
|
|
5982
|
-
catch { }
|
|
5983
6067
|
code = rewriteImports(code, base, sfcFileMap, depFileMap, projectRoot, !!verbose, undefined, getServerOrigin(server));
|
|
5984
6068
|
try {
|
|
5985
6069
|
code = ensureDestructureCoreImports(code);
|
|
@@ -5991,7 +6075,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
5991
6075
|
const origin = getServerOrigin(server);
|
|
5992
6076
|
code = ensureVersionedRtImports(code, origin, Number(ver));
|
|
5993
6077
|
code = ACTIVE_STRATEGY.ensureVersionedImports(code, origin, Number(ver));
|
|
5994
|
-
code = ensureVersionedCoreImports(code, origin, Number(ver));
|
|
5995
6078
|
}
|
|
5996
6079
|
catch { }
|
|
5997
6080
|
// Inline-template body path already runs processCodeForDevice (AST + sanitizers); no additional _defineComponent fix needed
|
|
@@ -6149,10 +6232,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
6149
6232
|
// Reuse existing sanitation chain (lightweight)
|
|
6150
6233
|
code = cleanCode(code);
|
|
6151
6234
|
code = processCodeForDevice(code, false, true, /(?:^|\/)node_modules\//.test(resolvedCandidate || spec), resolvedCandidate || spec);
|
|
6152
|
-
try {
|
|
6153
|
-
code = ensureVersionedCoreImports(code, getServerOrigin(server), graphVersion);
|
|
6154
|
-
}
|
|
6155
|
-
catch { }
|
|
6156
6235
|
code = rewriteImports(code, spec, sfcFileMap, depFileMap, server.config?.root || process.cwd(), !!verbose, undefined, getServerOrigin(server));
|
|
6157
6236
|
code = ensureVariableDynamicImportHelper(code);
|
|
6158
6237
|
code = ensureGuardPlainDynamicImports(code, origin);
|
|
@@ -6204,10 +6283,6 @@ export const piniaSymbol = p.piniaSymbol;
|
|
|
6204
6283
|
let depCode = depTrans.code;
|
|
6205
6284
|
depCode = cleanCode(depCode);
|
|
6206
6285
|
depCode = processCodeForDevice(depCode, false, true, /(?:^|\/)node_modules\//.test(depResolved), depResolved);
|
|
6207
|
-
try {
|
|
6208
|
-
depCode = ensureVersionedCoreImports(depCode, getServerOrigin(server), graphVersion);
|
|
6209
|
-
}
|
|
6210
|
-
catch { }
|
|
6211
6286
|
depCode = rewriteImports(depCode, depResolved, sfcFileMap, depFileMap, server.config?.root || process.cwd(), !!verbose, undefined, getServerOrigin(server));
|
|
6212
6287
|
depCode = ensureVariableDynamicImportHelper(depCode);
|
|
6213
6288
|
depCode = ensureGuardPlainDynamicImports(depCode, origin);
|