mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Merge remote-tracking branch 'origin/main' into feat/v9-prerelease
This commit is contained in:
@@ -31,7 +31,50 @@ function getConsumer(mapPath: string, sourceMap: any) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAndExtractMap(mapPath: string) {
|
function safeReadText(path: string): string | null {
|
||||||
|
try {
|
||||||
|
if (File.exists(path)) {
|
||||||
|
return File.fromPath(path).readTextSync();
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findInlineOrLinkedMapFromJs(jsPath: string): { key: string; text: string } | null {
|
||||||
|
const jsText = safeReadText(jsPath);
|
||||||
|
if (!jsText) return null;
|
||||||
|
|
||||||
|
// Look for the last sourceMappingURL directive
|
||||||
|
// Supports both //# and /*# */ styles; capture up to line end or */
|
||||||
|
const re = /[#@]\s*sourceMappingURL=([^\s*]+)(?:\s*\*\/)?/g;
|
||||||
|
let match: RegExpExecArray | null = null;
|
||||||
|
let last: RegExpExecArray | null = null;
|
||||||
|
while ((match = re.exec(jsText))) last = match;
|
||||||
|
if (!last) return null;
|
||||||
|
|
||||||
|
const url = last[1];
|
||||||
|
if (url.startsWith('data:application/json')) {
|
||||||
|
const base64 = url.split(',')[1];
|
||||||
|
if (!base64) return null;
|
||||||
|
try {
|
||||||
|
const text = atob(base64);
|
||||||
|
return { key: `inline:${jsPath}`, text };
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Linked .map file (relative)
|
||||||
|
const jsDir = jsPath.substring(0, jsPath.lastIndexOf('/'));
|
||||||
|
const mapPath = `${jsDir}/${url}`;
|
||||||
|
const text = safeReadText(mapPath);
|
||||||
|
if (text) {
|
||||||
|
return { key: mapPath, text };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadAndExtractMap(mapPath: string, fallbackJsPath?: string) {
|
||||||
// check cache first
|
// check cache first
|
||||||
if (!loadedSourceMaps) {
|
if (!loadedSourceMaps) {
|
||||||
loadedSourceMaps = new Map();
|
loadedSourceMaps = new Map();
|
||||||
@@ -71,11 +114,23 @@ function loadAndExtractMap(mapPath: string) {
|
|||||||
console.debug && console.debug(`Failed to load source map ${mapPath}:`, error);
|
console.debug && console.debug(`Failed to load source map ${mapPath}:`, error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Try fallback: read inline or linked map from the JS file itself
|
||||||
|
if (fallbackJsPath) {
|
||||||
|
const alt = findInlineOrLinkedMapFromJs(fallbackJsPath);
|
||||||
|
if (alt && alt.text) {
|
||||||
|
mapText = alt.text;
|
||||||
|
// Cache under both the requested key and the alt key so future lookups are fast
|
||||||
|
loadedSourceMaps.set(alt.key, alt.text);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// no source maps
|
// no source maps
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
loadedSourceMaps.set(mapPath, mapText); // cache it
|
loadedSourceMaps.set(mapPath, mapText); // cache it
|
||||||
return mapText;
|
return mapText;
|
||||||
}
|
}
|
||||||
@@ -93,9 +148,19 @@ function remapFrame(file: string, line: number, column: number) {
|
|||||||
if (usingSourceMapFiles) {
|
if (usingSourceMapFiles) {
|
||||||
sourceMapFileExt = '.map';
|
sourceMapFileExt = '.map';
|
||||||
}
|
}
|
||||||
const mapPath = `${appPath}/${file.replace('file:///app/', '')}${sourceMapFileExt}`;
|
const rel = file.replace('file:///app/', '');
|
||||||
|
const jsPath = `${appPath}/${rel}`;
|
||||||
|
let mapPath = `${jsPath}${sourceMapFileExt}`; // default: same name + .map
|
||||||
|
|
||||||
const sourceMap = loadAndExtractMap(mapPath);
|
// Fallback: if .mjs.map missing, try .js.map
|
||||||
|
if (!File.exists(mapPath) && rel.endsWith('.mjs')) {
|
||||||
|
const jsMapFallback = `${appPath}/${rel.replace(/\.mjs$/, '.js.map')}`;
|
||||||
|
if (File.exists(jsMapFallback)) {
|
||||||
|
mapPath = jsMapFallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sourceMap = loadAndExtractMap(mapPath, jsPath);
|
||||||
|
|
||||||
if (!sourceMap) {
|
if (!sourceMap) {
|
||||||
return { source: null, line: 0, column: 0 };
|
return { source: null, line: 0, column: 0 };
|
||||||
|
|||||||
@@ -89,7 +89,14 @@ export default class FixSourceMapUrlPlugin {
|
|||||||
compiler.hooks.thisCompilation.tap(
|
compiler.hooks.thisCompilation.tap(
|
||||||
'FixSourceMapUrlPlugin',
|
'FixSourceMapUrlPlugin',
|
||||||
(compilation: any) => {
|
(compilation: any) => {
|
||||||
const stage = wp.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING;
|
// IMPORTANT:
|
||||||
|
// Run AFTER SourceMapDevToolPlugin has emitted external map assets.
|
||||||
|
// If we run at DEV_TOOLING and replace sources, we may drop mapping info
|
||||||
|
// before Webpack has a chance to write .map files. SUMMARIZE happens later.
|
||||||
|
const stage =
|
||||||
|
wp.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE ||
|
||||||
|
// Fallback to DEV_TOOLING if summarize is unavailable
|
||||||
|
wp.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING;
|
||||||
compilation.hooks.processAssets.tap(
|
compilation.hooks.processAssets.tap(
|
||||||
{ name: 'FixSourceMapUrlPlugin', stage },
|
{ name: 'FixSourceMapUrlPlugin', stage },
|
||||||
(assets: Record<string, any>) => {
|
(assets: Record<string, any>) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user