attached sourcemap: support single line comments in script

pull/5854/head
Milan Hauth 6 years ago
parent 9d17d78729
commit a5ae6b3b7e

@ -175,7 +175,8 @@ function get_replacement(
original: string, original: string,
processed: Processed, processed: Processed,
prefix: string, prefix: string,
suffix: string suffix: string,
tag_name: 'script' | 'style'
): StringWithSourcemap { ): StringWithSourcemap {
// Convert the unchanged prefix and suffix to StringWithSourcemap // Convert the unchanged prefix and suffix to StringWithSourcemap
@ -184,7 +185,7 @@ function get_replacement(
const suffix_with_map = StringWithSourcemap.from_source( const suffix_with_map = StringWithSourcemap.from_source(
file_basename, suffix, get_location(offset + prefix.length + original.length)); file_basename, suffix, get_location(offset + prefix.length + original.length));
parse_attached_sourcemap(processed); parse_attached_sourcemap(processed, tag_name);
// Convert the preprocessed code and its sourcemap to a StringWithSourcemap // Convert the preprocessed code and its sourcemap to a StringWithSourcemap
let decoded_map: DecodedSourceMap; let decoded_map: DecodedSourceMap;
@ -289,7 +290,7 @@ export default async function preprocess(
if (!processed || !processed.map && processed.code === content) { if (!processed || !processed.map && processed.code === content) {
return no_change(); return no_change();
} }
return get_replacement(file_basename, offset, get_location, content, processed, `<${tag_name}${attributes}>`, `</${tag_name}>`); return get_replacement(file_basename, offset, get_location, content, processed, `<${tag_name}${attributes}>`, `</${tag_name}>`, tag_name);
} }
); );
source = res.string; source = res.string;

@ -292,13 +292,14 @@ export function apply_preprocessor_sourcemap(filename: string, svelte_map: Sourc
} }
// parse attached sourcemap in processed.code // parse attached sourcemap in processed.code
export function parse_attached_sourcemap(processed: Processed): void { export function parse_attached_sourcemap(processed: Processed, tag_name: 'script' | 'style'): void {
const magic_prefix = '\n/*# sourceMappingURL=data:application/json;'; const magic_prefix = '# sourceMappingURL=data:application/json;';
const cut_index = processed.code.lastIndexOf('\n'); const cut_index = processed.code.lastIndexOf('\n');
const last_line = processed.code.slice(cut_index); const last_line = processed.code.slice(cut_index);
if (magic_prefix != last_line.slice(0, magic_prefix.length)) { const line_start = last_line.slice(1, 3); // last_line[0] == '\n'
return; // attachment not found if ((line_start != '/*' && (tag_name == 'script' && line_start != '//')) ||
} magic_prefix != last_line.slice(3, 3 + magic_prefix.length)
) return; // attachment not found
if (processed.map) { if (processed.map) {
throw 'not implemented. '+ throw 'not implemented. '+
'found sourcemap in both processed.code and processed.map. '+ 'found sourcemap in both processed.code and processed.map. '+
@ -306,9 +307,8 @@ export function parse_attached_sourcemap(processed: Processed): void {
'processed.code:\n'+ 'processed.code:\n'+
processed.code.slice(0, 100)+' [....]'; // help to find preprocessor processed.code.slice(0, 100)+' [....]'; // help to find preprocessor
} }
// remove last line processed.code = processed.code.slice(0, cut_index); // remove last line
processed.code = processed.code.slice(0, cut_index); const slice_to = (line_start == '/*') ? -2 : undefined;
// slice to -2 --> remove trailing '*/' const b64map = last_line.slice(last_line.indexOf('base64,')+7, slice_to).trim();
const b64map = last_line.slice(last_line.indexOf('base64,')+7, -2).trim();
processed.map = b64dec(b64map); processed.map = b64dec(b64map);
} }

@ -42,7 +42,7 @@ describe('sourcemaps', () => {
filename: 'input.svelte' filename: 'input.svelte'
} }
); );
const { js, css } = svelte.compile( const { js, css } = svelte.compile(
preprocessed.code, { preprocessed.code, {
filename: 'input.svelte', filename: 'input.svelte',

@ -1,37 +1,44 @@
import MagicString from 'magic-string'; import MagicString from 'magic-string';
let indent_size = 4; let indent_size = 4;
function get_processor(search, replace) { let comment_multi = true;
return ({ content, filename }) => { function get_processor(tag_name, search, replace) {
let code = content.slice(); return {
const ms = new MagicString(code); [tag_name]: ({ content, filename }) => {
let code = content.slice();
const idx = ms.original.indexOf(search); const ms = new MagicString(code);
if (idx == -1) throw new Error('search not found in src');
ms.overwrite(idx, idx + search.length, replace, { storeName: true }); const idx = ms.original.indexOf(search);
if (idx == -1) throw new Error('search not found in src');
// change line + column ms.overwrite(idx, idx + search.length, replace, { storeName: true });
const indent = Array.from({ length: indent_size }).join(' ');
ms.prependLeft(idx, '\n'+indent); // change line + column
const indent = Array.from({ length: indent_size }).join(' ');
const map_opts = { source: filename, hires: true, includeContent: false }; ms.prependLeft(idx, '\n'+indent);
const map = ms.generateMap(map_opts);
const attach_line = `\n/*# sourceMappingURL=${map.toUrl()} */`; const map_opts = { source: filename, hires: true, includeContent: false };
code = ms.toString() + attach_line; const map = ms.generateMap(map_opts);
const attach_line = (tag_name == 'style' || comment_multi)
indent_size += 2; ? `\n/*# sourceMappingURL=${map.toUrl()} */`
return { code }; : `\n//# sourceMappingURL=${map.toUrl()}` // only in script
;
code = ms.toString() + attach_line;
indent_size += 2;
if (tag_name == 'script') comment_multi = !comment_multi;
return { code };
}
}; };
} }
export default { export default {
preprocess: [ preprocess: [
{ script: get_processor('replace_me_script', 'done_replace_script_1') }, get_processor('script', 'replace_me_script', 'done_replace_script_1'),
{ script: get_processor('done_replace_script_1', 'done_replace_script_2') }, get_processor('script', 'done_replace_script_1', 'done_replace_script_2'),
{ style: get_processor('.replace_me_style', '.done_replace_style_1') }, get_processor('style', '.replace_me_style', '.done_replace_style_1'),
{ style: get_processor('.done_replace_style_1', '.done_replace_style_2') } get_processor('style', '.done_replace_style_1', '.done_replace_style_2')
] ]
}; };

Loading…
Cancel
Save