UNPKG

vue-simple-compiler

Version:

A lib to compile Vue Single-File Component into plain JavaScript & CSS.

206 lines (205 loc) 7.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.shiftSourceMap = exports.bundleSourceMap = exports.chainSourceMap = exports.hackGeneratorProps = exports.getGeneratorSources = exports.getConsumerSources = void 0; const source_map_1 = require("source-map"); const getConsumerSources = (consumer) => { // source-map's type definition is incomplete const con = consumer; return con.sources; }; exports.getConsumerSources = getConsumerSources; const getGeneratorSources = (generator) => { // source-map's type definition is incomplete const gen = generator; return gen._sources.toArray(); }; exports.getGeneratorSources = getGeneratorSources; const hackGeneratorProps = (generator, props) => { // source-map's type definition is incomplete const gen = generator; if (props.file) { gen._file = props.file; } if (props.sourceRoot) { gen._sourceRoot = props.sourceRoot; } if (props.sources) { gen._sources = { toArray() { return props.sources; }, indexOf(source) { return props.sources.indexOf(source); }, }; } }; exports.hackGeneratorProps = hackGeneratorProps; const genJSON = (generator) => { // source-map's type definition is incomplete const gen = generator; return gen.toJSON(); }; /** * Chain source maps of two code blocks. * credit: https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/compileTemplate.ts */ const chainSourceMap = (oldMap, newMap) => { if (!oldMap) return newMap; if (!newMap) return oldMap; const oldMapConsumer = new source_map_1.SourceMapConsumer(oldMap); const newMapConsumer = new source_map_1.SourceMapConsumer(newMap); const mergedMapGenerator = new source_map_1.SourceMapGenerator(); newMapConsumer.eachMapping((m) => { if (m.originalLine == null) { return; } const origPosInOldMap = oldMapConsumer.originalPositionFor({ line: m.originalLine, column: m.originalColumn, }); if (origPosInOldMap.source == null) { return; } mergedMapGenerator.addMapping({ generated: { line: m.generatedLine, column: m.generatedColumn, }, original: { line: origPosInOldMap.line ?? 0, column: m.originalColumn, }, source: origPosInOldMap.source, name: origPosInOldMap.name ?? '', }); }); const sourceFileSet = new Set((0, exports.getGeneratorSources)(mergedMapGenerator)); (0, exports.getConsumerSources)(oldMapConsumer).forEach((sourceFile) => { sourceFileSet.add(sourceFile); }); const sources = Array.from(sourceFileSet); (0, exports.hackGeneratorProps)(mergedMapGenerator, { file: oldMap.file, sourceRoot: oldMap.sourceRoot, sources, }); sources.forEach((sourceFile) => { const sourceContent = oldMapConsumer.sourceContentFor(sourceFile); if (sourceContent) { mergedMapGenerator.setSourceContent(sourceFile, sourceContent); } }); return genJSON(mergedMapGenerator); }; exports.chainSourceMap = chainSourceMap; /** * Bundle source maps of multiple code blocks into one. * - assume source roots of all the blocks are the same * - pick the generated file name from the first block */ const bundleSourceMap = (list) => { if (list.length === 1) { return list[0]; } let code = ''; let lineOffset = 0; const generator = new source_map_1.SourceMapGenerator(); // for hack the source map let firstSourceMap; const sourceFileSet = new Set(); const sourceFileMap = new Map(); // const gen = generator as any list.forEach((block) => { code += `${block.code}\n`; if (block.sourceMap) { firstSourceMap = firstSourceMap || block.sourceMap; block.sourceMap.sources.forEach((sourceFile, index) => { sourceFileSet.add(sourceFile); if (block.sourceMap.sourcesContent[index] && !sourceFileMap.has(sourceFile)) { sourceFileMap.set(sourceFile, block.sourceMap.sourcesContent[index]); } }); const consumer = new source_map_1.SourceMapConsumer(block.sourceMap); consumer.eachMapping((m) => { generator.addMapping({ generated: { line: m.generatedLine + lineOffset, column: m.generatedColumn, }, original: { line: m.originalLine, column: m.originalColumn, }, source: m.source, name: m.name, }); }); } lineOffset += block.code.split(/\r?\n/).length; }); if (firstSourceMap) { const sources = Array.from(sourceFileSet); (0, exports.hackGeneratorProps)(generator, { file: firstSourceMap.file, sourceRoot: firstSourceMap.sourceRoot, sources, }); sources.forEach((sourceFile) => { const sourceContent = sourceFileMap.get(sourceFile); if (sourceContent) { generator.setSourceContent(sourceFile, sourceContent); } }); } return { code, sourceMap: genJSON(generator) }; }; exports.bundleSourceMap = bundleSourceMap; /** * Shift the source map of a single source file. * It's used for adjusting the source map when you generate it from a block of the whole file, which causes line offset. */ const shiftSourceMap = (map, offset, newFileMap) => { const consumer = new source_map_1.SourceMapConsumer(map); const generator = new source_map_1.SourceMapGenerator(); const sourceFileSet = new Set(); const sourceFileMap = new Map(); consumer.eachMapping((m) => { const source = (newFileMap || {})[m.source] || { name: m.source, code: consumer.sourceContentFor(m.source) || '', }; sourceFileSet.add(source.name); if (source.code) { sourceFileMap.set(source.name, source.code); } generator.addMapping({ generated: { line: m.generatedLine, column: m.generatedColumn, }, original: { line: m.originalLine + offset, column: m.originalColumn, }, source: source.name, name: m.name, }); }); (0, exports.hackGeneratorProps)(generator, { file: map.file, sourceRoot: map.sourceRoot, sources: Array.from(sourceFileSet), }); Array.from(sourceFileSet).forEach((sourceFile) => { const sourceContent = sourceFileMap.get(sourceFile); if (sourceContent) { generator.setSourceContent(sourceFile, sourceContent); } }); return genJSON(generator); }; exports.shiftSourceMap = shiftSourceMap;