From c39ac4cb636f3f9f92ff4375f377414d2ff93c16 Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Wed, 20 Apr 2022 08:32:56 -0400 Subject: [PATCH] refactor!: migrate from source-map to TraceMap [trace-mapping](https://github.com/jridgewell/trace-mapping) is faster, smaller, and lighter than the `source-map` package, and doesn't require WASM, manual memory management, or async/await to use. Fixes #185. --- README.md | 2 +- index.d.ts | 4 ++-- lib/source.js | 16 +++++++------- lib/v8-to-istanbul.js | 11 ++++------ package-lock.json | 50 ++++++++++++++++++++++++++++++++++++++++--- package.json | 5 +++-- test/source.js | 6 +++--- 7 files changed, 68 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 7e9bf696..30eaf657 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ const v8toIstanbul = require('v8-to-istanbul') // the path to the original source-file is required, as its contents are // used during the conversion algorithm. const converter = v8toIstanbul('./path-to-instrumented-file.js') -await converter.load() // this is required due to the async source-map dependency. +await converter.load() // this is required due to async file reading. // provide an array of coverage information in v8 format. converter.applyCoverage([ { diff --git a/index.d.ts b/index.d.ts index 3470f4e8..ee7b2868 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,7 +2,7 @@ import { Profiler } from 'inspector' import { CoverageMapData } from 'istanbul-lib-coverage' -import { RawSourceMap } from 'source-map' +import { SourceMapInput } from '@jridgewell/trace-mapping' declare type Sources = | { @@ -11,7 +11,7 @@ declare type Sources = | { source: string originalSource: string - sourceMap: { sourcemap: RawSourceMap } + sourceMap: { sourcemap: SourceMapInput } } declare class V8ToIstanbul { load(): Promise diff --git a/lib/source.js b/lib/source.js index 21deb684..08ad3989 100644 --- a/lib/source.js +++ b/lib/source.js @@ -1,6 +1,6 @@ const CovLine = require('./line') const { sliceRange } = require('./range') -const { GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND } = require('source-map').SourceMapConsumer +const { originalPositionFor, generatedPositionFor, GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND } = require('@jridgewell/trace-mapping') module.exports = class CovSource { constructor (sourceRaw, wrapperLength) { @@ -102,7 +102,7 @@ module.exports = class CovSource { } if (start.line === end.line && start.column === end.column) { - end = sourceMap.originalPositionFor({ + end = originalPositionFor(sourceMap, { line: lines[lines.length - 1].line, column: endCol - lines[lines.length - 1].startCol, bias: LEAST_UPPER_BOUND @@ -168,7 +168,7 @@ function originalEndPositionFor (sourceMap, line, column) { // for mappings in the original-order sorted list, this will find the // mapping that corresponds to the one immediately after the // beforeEndMapping mapping. - const afterEndMapping = sourceMap.generatedPositionFor({ + const afterEndMapping = generatedPositionFor(sourceMap, { source: beforeEndMapping.source, line: beforeEndMapping.line, column: beforeEndMapping.column + 1, @@ -181,7 +181,7 @@ function originalEndPositionFor (sourceMap, line, column) { // If these don't match, it means that the call to // 'generatedPositionFor' didn't find any other original mappings on // the line we gave, so consider the binding to extend to infinity. - sourceMap.originalPositionFor(afterEndMapping).line !== + originalPositionFor(sourceMap, afterEndMapping).line !== beforeEndMapping.line ) { return { @@ -192,17 +192,17 @@ function originalEndPositionFor (sourceMap, line, column) { } // Convert the end mapping into the real original position. - return sourceMap.originalPositionFor(afterEndMapping) + return originalPositionFor(sourceMap, afterEndMapping) } function originalPositionTryBoth (sourceMap, line, column) { - let original = sourceMap.originalPositionFor({ + let original = originalPositionFor(sourceMap, { line, column, bias: GREATEST_LOWER_BOUND }) if (original.line === null) { - original = sourceMap.originalPositionFor({ + original = originalPositionFor(sourceMap, { line, column, bias: LEAST_UPPER_BOUND @@ -220,7 +220,7 @@ function originalPositionTryBoth (sourceMap, line, column) { // } else { ... } // ^ ^ // l5 l3 - const min = sourceMap.originalPositionFor({ + const min = originalPositionFor(sourceMap, { line, column: 0, bias: GREATEST_LOWER_BOUND diff --git a/lib/v8-to-istanbul.js b/lib/v8-to-istanbul.js index 1b56af18..cb21fbe7 100644 --- a/lib/v8-to-istanbul.js +++ b/lib/v8-to-istanbul.js @@ -15,7 +15,7 @@ try { } catch (_err) { // most likely we're on an older version of Node.js. } -const { SourceMapConsumer } = require('source-map') +const { TraceMap } = require('@jridgewell/trace-mapping') const isOlderNode10 = /^v10\.(([0-9]\.)|(1[0-5]\.))/u.test(process.version) const isNode8 = /^v8\./.test(process.version) @@ -53,7 +53,7 @@ module.exports = class V8ToIstanbul { if (this.rawSourceMap) { if (this.rawSourceMap.sourcemap.sources.length > 1) { - this.sourceMap = await new SourceMapConsumer(this.rawSourceMap.sourcemap) + this.sourceMap = new TraceMap(this.rawSourceMap.sourcemap) if (!this.sourceMap.sourcesContent) { this.sourceMap.sourcesContent = await this.sourcesContentFromSources() } @@ -62,7 +62,7 @@ module.exports = class V8ToIstanbul { } else { const candidatePath = this.rawSourceMap.sourcemap.sources.length >= 1 ? this.rawSourceMap.sourcemap.sources[0] : this.rawSourceMap.sourcemap.file this.path = this._resolveSource(this.rawSourceMap, candidatePath || this.path) - this.sourceMap = await new SourceMapConsumer(this.rawSourceMap.sourcemap) + this.sourceMap = new TraceMap(this.rawSourceMap.sourcemap) let originalRawSource if (this.sources.sourceMap && this.sources.sourceMap.sourcemap && this.sources.sourceMap.sourcemap.sourcesContent && this.sources.sourceMap.sourcemap.sourcesContent.length === 1) { @@ -102,10 +102,7 @@ module.exports = class V8ToIstanbul { } destroy () { - if (this.sourceMap) { - this.sourceMap.destroy() - this.sourceMap = undefined - } + this.sourceMap = undefined } _resolveSource (rawSourceMap, sourcePath) { diff --git a/package-lock.json b/package-lock.json index f0b1a6e1..f911c41a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,15 +9,16 @@ "version": "8.1.1", "license": "ISC", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.7", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^1.6.0" }, "devDependencies": { "@types/node": "^16.0.0", "c8": "^7.2.1", "semver": "^7.3.2", "should": "13.2.3", + "source-map": "^0.7.3", "standard": "^16.0.4", "tap": "^15.1.6" }, @@ -501,6 +502,28 @@ "node": ">=8" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.7.tgz", + "integrity": "sha512-8XC0l0PwCbdg2Uc8zIIf6djNX3lYiz9GqQlC1LJ9WQvTYvcfP8IA9K2IKRnPm5tAX6X/+orF+WwKZ0doGcgJlg==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -4412,6 +4435,7 @@ "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, "engines": { "node": ">= 8" } @@ -7525,6 +7549,25 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.7.tgz", + "integrity": "sha512-8XC0l0PwCbdg2Uc8zIIf6djNX3lYiz9GqQlC1LJ9WQvTYvcfP8IA9K2IKRnPm5tAX6X/+orF+WwKZ0doGcgJlg==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -10500,7 +10543,8 @@ "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true }, "source-map-support": { "version": "0.5.20", diff --git a/package.json b/package.json index 50abafb4..06efb1fa 100644 --- a/package.json +++ b/package.json @@ -25,15 +25,16 @@ "author": "Ben Coe ", "license": "ISC", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.7", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^1.6.0" }, "devDependencies": { "@types/node": "^16.0.0", "c8": "^7.2.1", "semver": "^7.3.2", "should": "13.2.3", + "source-map": "^0.7.3", "standard": "^16.0.4", "tap": "^15.1.6" }, diff --git a/test/source.js b/test/source.js index 6dd4d3af..b00074a2 100644 --- a/test/source.js +++ b/test/source.js @@ -1,7 +1,7 @@ /* global describe, it */ const CovSource = require('../lib/source') -const { SourceMapConsumer } = require('source-map') +const { TraceMap } = require('@jridgewell/trace-mapping') require('tap').mochaGlobals() require('should') @@ -45,7 +45,7 @@ describe('Source', () => { new CovSource(sourceRaw, 0).should.ok() }) - it('range crossing two sourcemaps', async () => { + it('range crossing two sourcemaps', () => { const sourceRaw = `\ (() => { // hello.ts @@ -59,7 +59,7 @@ describe('Source', () => { //# sourceMappingURL=greet.js.map\ ` const source = new CovSource(sourceRaw, 0) - const sourceMap = await new SourceMapConsumer({ + const sourceMap = new TraceMap({ version: 3, sources: ['../hello.ts', '../greet.ts'], sourcesContent: ['export function hello() {\r\n console.log("hello world")\r\n}', 'import {hello} from "./hello"\r\n\r\nhello()\r\n'],