|
1 | 1 | import { DecodedSourceMap, RawSourceMap, SourceMapLoader } from '@ampproject/remapping/dist/types/types';
|
2 | 2 | import remapping from '@ampproject/remapping';
|
3 | 3 | import { SourceMap } from 'magic-string';
|
| 4 | +import { Processed } from '../preprocess'; |
4 | 5 |
|
5 | 6 | type SourceLocation = {
|
6 | 7 | line: number;
|
@@ -255,6 +256,7 @@ export function combine_sourcemaps(
|
255 | 256 |
|
256 | 257 | // browser vs node.js
|
257 | 258 | const b64enc = typeof btoa == 'function' ? btoa : b => Buffer.from(b).toString('base64');
|
| 259 | +const b64dec = typeof atob == 'function' ? atob : a => Buffer.from(a, 'base64').toString(); |
258 | 260 |
|
259 | 261 | export function apply_preprocessor_sourcemap(filename: string, svelte_map: SourceMap, preprocessor_map_input: string | DecodedSourceMap | RawSourceMap): SourceMap {
|
260 | 262 | if (!svelte_map || !preprocessor_map_input) return svelte_map;
|
@@ -288,3 +290,39 @@ export function apply_preprocessor_sourcemap(filename: string, svelte_map: Sourc
|
288 | 290 |
|
289 | 291 | return result_map as SourceMap;
|
290 | 292 | }
|
| 293 | + |
| 294 | +// parse attached sourcemap in processed.code |
| 295 | +export function parse_attached_sourcemap(processed: Processed, tag_name: 'script' | 'style'): void { |
| 296 | + const r_in = '[#@]\\s*sourceMappingURL\\s*=\\s*(\\S*)'; |
| 297 | + const regex = (tag_name == 'script') |
| 298 | + ? new RegExp('(?://'+r_in+')|(?:/\\*'+r_in+'\\s*\\*/)$') |
| 299 | + : new RegExp('/\\*'+r_in+'\\s*\\*/$'); |
| 300 | + function log_warning(message) { |
| 301 | + // code_start: help to find preprocessor |
| 302 | + const code_start = processed.code.length < 100 ? processed.code : (processed.code.slice(0, 100) + ' [...]'); |
| 303 | + console.warn(`warning: ${message}. processed.code = ${JSON.stringify(code_start)}`); |
| 304 | + } |
| 305 | + processed.code = processed.code.replace(regex, (_, match1, match2) => { |
| 306 | + const map_url = (tag_name == 'script') ? (match1 || match2) : match1; |
| 307 | + const map_data = (map_url.match(/data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(\S*)/) || [])[1]; |
| 308 | + if (map_data) { |
| 309 | + // sourceMappingURL is data URL |
| 310 | + if (processed.map) { |
| 311 | + log_warning('Not implemented. ' + |
| 312 | + 'Found sourcemap in both processed.code and processed.map. ' + |
| 313 | + 'Please update your preprocessor to return only one sourcemap.'); |
| 314 | + // ignore attached sourcemap |
| 315 | + return ''; |
| 316 | + } |
| 317 | + processed.map = b64dec(map_data); // use attached sourcemap |
| 318 | + return ''; // remove from processed.code |
| 319 | + } |
| 320 | + // sourceMappingURL is path or URL |
| 321 | + if (!processed.map) { |
| 322 | + log_warning(`Found sourcemap path ${JSON.stringify(map_url)} in processed.code, but no sourcemap data. ` + |
| 323 | + 'Please update your preprocessor to return sourcemap data directly.'); |
| 324 | + } |
| 325 | + // ignore sourcemap path |
| 326 | + return ''; // remove from processed.code |
| 327 | + }); |
| 328 | +} |
0 commit comments