diff --git a/packages/bundle-source/demo/dir1/index.js b/packages/bundle-source/demo/dir1/index.js index deec7419fe7..126dc299106 100644 --- a/packages/bundle-source/demo/dir1/index.js +++ b/packages/bundle-source/demo/dir1/index.js @@ -6,6 +6,7 @@ export default function makeEncourager() { return harden({ encourage, makeError, + makeError2: msg => TypeError(msg), more, }); } diff --git a/packages/bundle-source/src/index.js b/packages/bundle-source/src/index.js index bbaf682ffd1..16739443269 100644 --- a/packages/bundle-source/src/index.js +++ b/packages/bundle-source/src/index.js @@ -13,14 +13,9 @@ const DEFAULT_MODULE_FORMAT = 'nestedEvaluate'; const DEFAULT_FILE_PREFIX = '/bundled-source'; const SUPPORTED_FORMATS = ['getExport', 'nestedEvaluate']; -const removeComments = comments => { - if (!comments) { - return; - } - // We remove all the JS comments to prevent misidentifying HTML - // comments, or import expressions. - comments.splice(0, comments.length); -}; +const IMPORT_RE = new RegExp('\\b(import)(\\s*(?:\\(|/[/*]))', 'sg'); +const HTML_COMMENT_START_RE = new RegExp(`${'<'}!--`, 'g'); +const HTML_COMMENT_END_RE = new RegExp(`--${'>'}`, 'g'); export function tildotPlugin() { const transformer = makeTransform(babelParser, babelGenerate); @@ -92,11 +87,14 @@ export default async function bundleSource( // its source lines back to the right place. // eslint-disable-next-line no-await-in-loop const consumer = await new SourceMapConsumer(chunk.map); + const unmapped = new WeakSet(); let lastPos = ast.loc.start; unmapLoc = loc => { - if (!loc) { + if (!loc || unmapped.has(loc)) { return; } + // Ensure we start in the right position... doesn't matter where we end. + loc.end = loc.start; for (const pos of ['start', 'end']) { if (loc[pos]) { const newPos = consumer.originalPositionFor(loc[pos]); @@ -108,29 +106,46 @@ export default async function bundleSource( loc[pos] = lastPos; } } + unmapped.add(loc); }; } + const rewriteComment = node => { + node.type = 'CommentBlock'; + node.value = node.value + .replace(/^\s*/gm, '') // Strip extraneous comment whitespace. + .replace(HTML_COMMENT_START_RE, '') + .replace(IMPORT_RE, 'X$1$2'); + if (unmapLoc) { + unmapLoc(node.loc); + } + // console.log(JSON.stringify(node, undefined, 2)); + }; + babelTraverse(ast, { enter(p) { const { loc, leadingComments, trailingComments } = p.node; - // Remove all comments. - removeComments(leadingComments); - removeComments(trailingComments); + if (p.node.comments) { + p.node.comments = []; + } + // Rewrite all comments. + (leadingComments || []).forEach(rewriteComment); if (p.node.type.startsWith('Comment')) { - p.replaceWithMultiple([]); - return; + rewriteComment(p.node); } // If not a comment, and we are unmapping the source maps, // then do it for this location. if (unmapLoc) { unmapLoc(loc); } + (trailingComments || []).forEach(rewriteComment); }, }); // Now generate the sources with the new positions. sourceBundle[fileName] = babelGenerate(ast, { retainLines: true }).code; + // console.log(`==== sourceBundle[${fileName}]\n${sourceBundle[fileName]}\n====`); } if (!entrypoint) { diff --git a/packages/bundle-source/test/sanity.js b/packages/bundle-source/test/sanity.js index d2403c9d7bf..9ae0d25c6f3 100644 --- a/packages/bundle-source/test/sanity.js +++ b/packages/bundle-source/test/sanity.js @@ -39,6 +39,12 @@ test('nestedEvaluate', async t => { 'bundled source is in stack trace with correct line number', ); + const err2 = bundle.makeError2('bar'); + t.assert( + err2.stack.indexOf('(/bundled-source/index.js:9:') >= 0, + 'bundled source is in second stack trace with correct line number', + ); + const { moduleFormat: mf2, source: src2,