diff --git a/packages/gatsby-cli/package.json b/packages/gatsby-cli/package.json index 65505bf4c462c..fcebe11afbf72 100644 --- a/packages/gatsby-cli/package.json +++ b/packages/gatsby-cli/package.json @@ -18,6 +18,7 @@ "@babel/runtime": "^7.15.4", "@babel/template": "^7.16.7", "@babel/types": "^7.16.8", + "@jridgewell/trace-mapping": "^0.3.13", "@types/common-tags": "^1.8.1", "better-opn": "^2.1.1", "boxen": "^5.1.2", @@ -47,7 +48,6 @@ "resolve-cwd": "^3.0.0", "semver": "^7.3.7", "signal-exit": "^3.0.6", - "source-map": "0.7.3", "stack-trace": "^0.0.10", "strip-ansi": "^6.0.1", "update-notifier": "^5.1.0", diff --git a/packages/gatsby-cli/src/reporter/__tests__/errors.ts b/packages/gatsby-cli/src/reporter/__tests__/errors.ts index 23b9f96845bb8..83dd07e40bb84 100644 --- a/packages/gatsby-cli/src/reporter/__tests__/errors.ts +++ b/packages/gatsby-cli/src/reporter/__tests__/errors.ts @@ -5,8 +5,8 @@ const errorStr = `./src/pages/index.module.scss\nModule build failed: /project/s // TODO: Add tests for sourcemap mapping in prepareStackTrace[] describe(`createErrorFromString`, () => { - it(`converts a string to an Error object`, async () => { - const err = await createErrorFromString(errorStr, ``) + it(`converts a string to an Error object`, () => { + const err = createErrorFromString(errorStr, ``) expect(typeof err).toEqual(`object`) expect(err.name).toEqual(`WebpackError`) expect(err.message).toEqual(`./src/pages/index.module.scss`) diff --git a/packages/gatsby-cli/src/reporter/errors.ts b/packages/gatsby-cli/src/reporter/errors.ts index 5f10a3a251d6d..095e271884354 100644 --- a/packages/gatsby-cli/src/reporter/errors.ts +++ b/packages/gatsby-cli/src/reporter/errors.ts @@ -103,10 +103,10 @@ export function getErrorFormatter(): PrettyError { * Convert a stringified webpack compilation error back into * an Error instance so it can be formatted properly */ -export async function createErrorFromString( +export function createErrorFromString( errorStr: string = ``, sourceMapFile: string -): Promise { +): ErrorWithCodeFrame { let [message, ...rest] = errorStr.split(/\r\n|[\n\r]/g) // pull the message from the first line then remove the `Error:` prefix // FIXME: when https://github.com/AriaMinaei/pretty-error/pull/49 is merged @@ -120,7 +120,7 @@ export async function createErrorFromString( error.name = `WebpackError` try { if (sourceMapFile) { - return await prepareStackTrace(error, sourceMapFile) + return prepareStackTrace(error, sourceMapFile) } } catch (err) { // don't shadow a real error because of a parsing issue diff --git a/packages/gatsby-cli/src/reporter/prepare-stack-trace.ts b/packages/gatsby-cli/src/reporter/prepare-stack-trace.ts index cc627e475a3ed..037fc909e6dcd 100644 --- a/packages/gatsby-cli/src/reporter/prepare-stack-trace.ts +++ b/packages/gatsby-cli/src/reporter/prepare-stack-trace.ts @@ -6,11 +6,12 @@ import { readFileSync, readdirSync } from "fs" import { codeFrameColumns } from "@babel/code-frame" import stackTrace from "stack-trace" import { - SourceMapConsumer, - BasicSourceMapConsumer, - IndexedSourceMapConsumer, - NullableMappedPosition, -} from "source-map" + TraceMap, + originalPositionFor, + OriginalMapping, + InvalidOriginalMapping, + sourceContentFor, +} from "@jridgewell/trace-mapping" import * as path from "path" export class ErrorWithCodeFrame extends Error { @@ -27,10 +28,10 @@ export class ErrorWithCodeFrame extends Error { } } -export async function prepareStackTrace( +export function prepareStackTrace( error: Error, sourceOfMainMap: string -): Promise { +): ErrorWithCodeFrame { const newError = new ErrorWithCodeFrame(error) // source point to single map, but with code splitting for build-html we need to handle more maps // we use fact that all .map files will be in same dir as main one here @@ -39,10 +40,8 @@ export async function prepareStackTrace( .filter(fileName => fileName.endsWith(`.js.map`)) .map(fileName => path.join(bundleDir, fileName)) - const maps = await Promise.all( - bundleDirMapFiles.map( - async source => await new SourceMapConsumer(readFileSync(source, `utf8`)) - ) + const maps = bundleDirMapFiles.map( + source => new TraceMap(readFileSync(source, `utf8`)) ) const stack = stackTrace @@ -66,12 +65,12 @@ export async function prepareStackTrace( } function getErrorSource( - maps: Array, + maps: Array, topFrame: stackTrace.StackFrame | IWrappedStackFrame ): string { let source for (const map of maps) { - source = map.sourceContentFor(topFrame.getFileName(), true) + source = sourceContentFor(map, topFrame.getFileName()) if (source) { break } @@ -103,7 +102,7 @@ interface IWrappedStackFrame { } function wrapCallSite( - maps: Array, + maps: Array, frame: stackTrace.StackFrame ): IWrappedStackFrame | stackTrace.StackFrame { const source = frame.getFileName() @@ -126,9 +125,9 @@ function getPosition({ maps, frame, }: { - maps: Array + maps: Array frame: stackTrace.StackFrame -}): NullableMappedPosition { +}): OriginalMapping | InvalidOriginalMapping { if (frame.getFileName().includes(`webpack:`)) { // if source-map-register is initiated, stack traces would already be converted return { @@ -145,7 +144,7 @@ function getPosition({ const line = frame.getLineNumber() const column = frame.getColumnNumber() for (const map of maps) { - const test = map.originalPositionFor({ line, column }) + const test = originalPositionFor(map, { line, column }) if (test.source) { return test } diff --git a/packages/gatsby-legacy-polyfills/package.json b/packages/gatsby-legacy-polyfills/package.json index 6c8a5cd6225bc..b5316e972de4d 100644 --- a/packages/gatsby-legacy-polyfills/package.json +++ b/packages/gatsby-legacy-polyfills/package.json @@ -31,6 +31,7 @@ "dist/" ], "devDependencies": { + "@jridgewell/trace-mapping": "^0.3.13", "chokidar-cli": "^3.0.0", "codegen.macro": "^4.1.0", "core-js": "3.9.0", @@ -42,7 +43,6 @@ "microbundle": "^0.14.2", "npm-run-all": "^4.1.5", "object-assign": "^4.1.1", - "source-map": "^0.7.3", "url-polyfill": "^1.1.12", "whatwg-fetch": "^3.6.2", "yet-another-abortcontroller-polyfill": "0.0.4" diff --git a/packages/gatsby-legacy-polyfills/src/__tests__/polyfills.js b/packages/gatsby-legacy-polyfills/src/__tests__/polyfills.js index b48ef4d1de4d3..ac5ca615940c4 100644 --- a/packages/gatsby-legacy-polyfills/src/__tests__/polyfills.js +++ b/packages/gatsby-legacy-polyfills/src/__tests__/polyfills.js @@ -1,5 +1,5 @@ const path = require(`path`) -const { SourceMapConsumer } = require(`source-map`) +const { TraceMap } = require(`@jridgewell/trace-mapping`) const execa = require(`execa`) const fs = require(`fs-extra`) @@ -30,7 +30,7 @@ describe(`polyfills`, () => { afterAll(() => fs.remove(path.join(packageRoot, tmpDir))) - it(`has the correct polyfills`, done => { + it(`has the correct polyfills`, () => { const polyfills = require(`../exclude`).LEGACY_POLYFILLS const polyfillMap = path.join(packageRoot, tmpDir, `polyfills.js.map`) expect(fs.existsSync(polyfillMap)).toBe(true) @@ -46,18 +46,14 @@ describe(`polyfills`, () => { }) const polyfillMapSource = fs.readFileSync(polyfillMap, `utf8`) - SourceMapConsumer.with(polyfillMapSource, null, consumer => { - const sources = consumer.sources.map(source => - source.replace(/.*\/node_modules\//, ``) - ) - - // check if all polyfills are in the bundle - expect(sources).toEqual( - expect.arrayContaining( - fileMap.map(file => expect.stringContaining(file)) - ) - ) - done() - }) + const tracer = new TraceMap(polyfillMapSource) + const sources = tracer.sources.map(source => + source.replace(/.*\/node_modules\//, ``) + ) + + // check if all polyfills are in the bundle + expect(sources).toEqual( + expect.arrayContaining(fileMap.map(file => expect.stringContaining(file))) + ) }) }) diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 40b4f7b539d07..acb7fd0edf3e6 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -28,6 +28,7 @@ "@graphql-codegen/typescript-operations": "^2.3.5", "@graphql-tools/code-file-loader": "^7.2.14", "@graphql-tools/load": "^7.5.10", + "@jridgewell/trace-mapping": "^0.3.13", "@nodelib/fs.walk": "^1.2.8", "@parcel/core": "2.6.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", @@ -152,7 +153,6 @@ "slugify": "^1.6.1", "socket.io": "3.1.2", "socket.io-client": "3.1.3", - "source-map": "^0.7.3", "source-map-support": "^0.5.20", "st": "^2.0.0", "stack-trace": "^0.0.10", diff --git a/packages/gatsby/src/commands/build-html.ts b/packages/gatsby/src/commands/build-html.ts index 86e06c755c95c..95d1d366e831a 100644 --- a/packages/gatsby/src/commands/build-html.ts +++ b/packages/gatsby/src/commands/build-html.ts @@ -229,7 +229,7 @@ const renderHTMLQueue = async ( pagePaths: [pagePath], }) seenErrors.add(error.stack) - const prettyError = await createErrorFromString( + const prettyError = createErrorFromString( error.stack, `${htmlComponentRendererPath}.map` ) @@ -304,7 +304,7 @@ const renderHTMLQueue = async ( } for (const unsafeBuiltinUsedStack of uniqueUnsafeBuiltinUsedStacks) { - const prettyError = await createErrorFromString( + const prettyError = createErrorFromString( unsafeBuiltinUsedStack, `${htmlComponentRendererPath}.map` ) @@ -359,7 +359,7 @@ export const doBuildPages = async ( try { await renderHTMLQueue(workerPool, activity, rendererPath, pagePaths, stage) } catch (error) { - const prettyError = await createErrorFromString( + const prettyError = createErrorFromString( error.stack, `${rendererPath}.map` ) diff --git a/packages/gatsby/src/utils/dev-ssr/render-dev-html-child.js b/packages/gatsby/src/utils/dev-ssr/render-dev-html-child.js index 33303ef045025..ea3f28695b013 100644 --- a/packages/gatsby/src/utils/dev-ssr/render-dev-html-child.js +++ b/packages/gatsby/src/utils/dev-ssr/render-dev-html-child.js @@ -1,3 +1,4 @@ +// TODO: Do not use source-map-support and migrate to a package that doesn't use source-map under the hood require(`source-map-support`).install() const sysPath = require(`path`) const fs = require(`fs-extra`) diff --git a/packages/gatsby/src/utils/stack-trace-utils.ts b/packages/gatsby/src/utils/stack-trace-utils.ts index d9123fb8b276d..056b3dfb77889 100644 --- a/packages/gatsby/src/utils/stack-trace-utils.ts +++ b/packages/gatsby/src/utils/stack-trace-utils.ts @@ -1,11 +1,12 @@ import stackTrace, { StackFrame } from "stack-trace" import { codeFrameColumns } from "@babel/code-frame" import { - NullableMappedPosition, - SourceMapConsumer, - RawSourceMap, - RawIndexMap, -} from "source-map" + TraceMap, + originalPositionFor, + OriginalMapping, + SourceMapInput, + sourceContentFor, +} from "@jridgewell/trace-mapping" const fs = require(`fs-extra`) const path = require(`path`) @@ -111,33 +112,31 @@ export const getNonGatsbyCodeFrameFormatted = ({ } interface IOriginalSourcePositionAndContent { - sourcePosition: NullableMappedPosition | null + sourcePosition: OriginalMapping | null sourceContent: string | null } -export async function findOriginalSourcePositionAndContent( - webpackSource: RawSourceMap | RawIndexMap | string, +export function findOriginalSourcePositionAndContent( + webpackSource: SourceMapInput | string, position: { line: number; column: number | null } -): Promise { - return await SourceMapConsumer.with(webpackSource, null, consumer => { - const sourcePosition = consumer.originalPositionFor({ - line: position.line, - column: position.column ?? 0, - }) - - if (!sourcePosition.source) { - return { - sourcePosition: null, - sourceContent: null, - } - } - - const sourceContent: string | null = - consumer.sourceContentFor(sourcePosition.source, true) ?? null +): IOriginalSourcePositionAndContent { + const tracer = new TraceMap(webpackSource) + const sourcePosition = originalPositionFor(tracer, { + line: position.line, + column: position.column ?? 0, + }) + if (!sourcePosition.source) { return { - sourcePosition, - sourceContent, + sourcePosition: null, + sourceContent: null, } - }) + } + + const sourceContent = sourceContentFor(tracer, sourcePosition.source) + + return { + sourcePosition, + sourceContent, + } } diff --git a/packages/gatsby/src/utils/start-server.ts b/packages/gatsby/src/utils/start-server.ts index 67e6635647cdd..863eb0a5beb07 100644 --- a/packages/gatsby/src/utils/start-server.ts +++ b/packages/gatsby/src/utils/start-server.ts @@ -406,7 +406,7 @@ export async function startServer( } ) - app.get(`/__original-stack-frame`, async (req, res) => { + app.get(`/__original-stack-frame`, (req, res) => { const compilation = res.locals?.webpack?.devMiddleware?.stats?.compilation const emptyResponse = { codeFrame: `No codeFrame could be generated`, @@ -454,10 +454,7 @@ export async function startServer( line: lineNumber, column: columnNumber, } - const result = await findOriginalSourcePositionAndContent( - sourceMap, - position - ) + const result = findOriginalSourcePositionAndContent(sourceMap, position) const sourcePosition = result?.sourcePosition const sourceLine = sourcePosition?.line diff --git a/yarn.lock b/yarn.lock index 35a39eafeb6f9..9bd149fa6a6c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3140,7 +3140,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": version "0.3.13" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== @@ -23041,14 +23041,14 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" -source-map@0.7.3, source-map@^0.7.3, source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" +source-map@^0.7.3, source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + source-map@~0.1.30: version "0.1.43" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"