diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 3e2bf99c7c..5f3605b04b 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -83,7 +83,9 @@ async function replace_async( return out.concat(final_content); } -// Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap +/** + * Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap + */ function get_replacement( filename: string, offset: number, @@ -124,7 +126,9 @@ export default async function preprocess( const filename = (options && options.filename) || preprocessor.filename; // legacy const dependencies = []; - const preprocessors = Array.isArray(preprocessor) ? preprocessor : [preprocessor || {}]; + const preprocessors = preprocessor + ? Array.isArray(preprocessor) ? preprocessor : [preprocessor] + : []; const markup = preprocessors.map(p => p.markup).filter(Boolean); const script = preprocessors.map(p => p.script).filter(Boolean); @@ -145,24 +149,30 @@ export default async function preprocess( filename }); - if (processed && processed.dependencies) dependencies.push(...processed.dependencies); - source = processed ? processed.code : source; - if (processed && processed.map) { - sourcemap_list.unshift( - typeof(processed.map) === 'string' - ? JSON.parse(processed.map) - : processed.map - ); + if (processed) { + if (processed.dependencies) dependencies.push(...processed.dependencies); + source = processed.code; + if (processed.map) { + sourcemap_list.unshift( + typeof(processed.map) === 'string' + ? JSON.parse(processed.map) + : processed.map + ); + } } } - for (const fn of script) { + async function preprocess_tag_content(tag_name: 'style' | 'script', preprocessor: Preprocessor) { const get_location = getLocator(source); + const tag_regex = tag_name == 'style' + ? /|([^]*?)<\/style>|\/>)/gi + : /|([^]*?)<\/script>|\/>)/gi; + const res = await replace_async( filename, source, get_location, - /|([^]*?)<\/script>|\/>)/gi, + tag_regex, async (match, attributes = '', content = '', offset) => { const no_change = () => StringWithSourcemap.from_source( filename, match, get_location(offset)); @@ -173,51 +183,27 @@ export default async function preprocess( content = content || ''; // run script preprocessor - const processed = await fn({ + const processed = await preprocessor({ content, attributes: parse_attributes(attributes), filename }); - if (processed && processed.dependencies) dependencies.push(...processed.dependencies); - return processed - ? get_replacement(filename, offset, get_location, content, processed, ``, '') - : no_change(); + + if (!processed) return no_change(); + if (processed.dependencies) dependencies.push(...processed.dependencies); + return get_replacement(filename, offset, get_location, content, processed, `<${tag_name}${attributes}>`, ``); } ); source = res.string; sourcemap_list.unshift(res.map); } - for (const fn of style) { - const get_location = getLocator(source); - const res = await replace_async( - filename, - source, - get_location, - /|([^]*?)<\/style>|\/>)/gi, - async (match, attributes = '', content = '', offset) => { - const no_change = () => StringWithSourcemap.from_source( - filename, match, get_location(offset)); - if (!attributes && !content) { - return no_change(); - } - attributes = attributes || ''; - content = content || ''; + for (const fn of script) { + await preprocess_tag_content('script', fn); + } - // run style preprocessor - const processed: Processed = await fn({ - content, - attributes: parse_attributes(attributes), - filename - }); - if (processed && processed.dependencies) dependencies.push(...processed.dependencies); - return processed - ? get_replacement(filename, offset, get_location, content, processed, ``, '') - : no_change(); - } - ); - source = res.string; - sourcemap_list.unshift(res.map); + for (const fn of style) { + await preprocess_tag_content('style', fn); } // Combine all the source maps for each preprocessor function into one diff --git a/src/compiler/utils/string_with_sourcemap.ts b/src/compiler/utils/string_with_sourcemap.ts index ebd44221e1..7fb38323d4 100644 --- a/src/compiler/utils/string_with_sourcemap.ts +++ b/src/compiler/utils/string_with_sourcemap.ts @@ -32,7 +32,7 @@ export function sourcemap_add_offset( } } -function merge_tables(this_table: T[], other_table): [T[], number[], boolean, boolean] { +function merge_tables(this_table: T[], other_table: T[]): [T[], number[], boolean, boolean] { const new_table = this_table.slice(); const idx_map = []; other_table = other_table || []; @@ -68,7 +68,7 @@ export class StringWithSourcemap { string: string; map: DecodedSourceMap; - constructor(string = '', map = null) { + constructor(string = '', map: DecodedSourceMap = null) { this.string = string; if (map) { this.map = map as DecodedSourceMap; @@ -82,8 +82,10 @@ export class StringWithSourcemap { } } - // concat in-place (mutable), return this (chainable) - // will also mutate the `other` object + /** + * concat in-place (mutable), return this (chainable) + * will also mutate the `other` object + */ concat(other: StringWithSourcemap): StringWithSourcemap { // noop: if one is empty, return the other if (other.string == '') return this; @@ -250,8 +252,8 @@ export function apply_preprocessor_sourcemap(filename: string, svelte_map: Sourc ] ) as RawSourceMap; - //Svelte expects a SourceMap which includes toUrl and toString. Instead of using the magic-string constructor that takes a decoded map - //we just tack on the extra properties. + // Svelte expects a SourceMap which includes toUrl and toString. Instead of wrapping our output in a class, + // we just tack on the extra properties. Object.defineProperties(result_map, { toString: { enumerable: false, diff --git a/test/sourcemaps/samples/compile-option-dev/input.svelte b/test/sourcemaps/samples/compile-option-dev/input.svelte index f16bf0d5d8..6d5f91158d 100644 --- a/test/sourcemaps/samples/compile-option-dev/input.svelte +++ b/test/sourcemaps/samples/compile-option-dev/input.svelte @@ -12,4 +12,4 @@ div { --keep-me: blue; } - \ No newline at end of file +