Skip to content

Commit

Permalink
chore(gatsby): Migrate from source-map to `@jridgewell/trace-mappin…
Browse files Browse the repository at this point in the history
…g` (#35621)

* initial

* sourceContentFor

* update upstream package
  • Loading branch information
LekoArts committed Jun 1, 2022
1 parent ba182c6 commit fc5df03
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 80 deletions.
2 changes: 1 addition & 1 deletion packages/gatsby-cli/package.json
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-cli/src/reporter/__tests__/errors.ts
Expand Up @@ -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`)
Expand Down
6 changes: 3 additions & 3 deletions packages/gatsby-cli/src/reporter/errors.ts
Expand Up @@ -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> {
): 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
Expand All @@ -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
Expand Down
33 changes: 16 additions & 17 deletions packages/gatsby-cli/src/reporter/prepare-stack-trace.ts
Expand Up @@ -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 {
Expand All @@ -27,10 +28,10 @@ export class ErrorWithCodeFrame extends Error {
}
}

export async function prepareStackTrace(
export function prepareStackTrace(
error: Error,
sourceOfMainMap: string
): Promise<ErrorWithCodeFrame> {
): 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
Expand All @@ -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
Expand All @@ -66,12 +65,12 @@ export async function prepareStackTrace(
}

function getErrorSource(
maps: Array<BasicSourceMapConsumer | IndexedSourceMapConsumer>,
maps: Array<TraceMap>,
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
}
Expand Down Expand Up @@ -103,7 +102,7 @@ interface IWrappedStackFrame {
}

function wrapCallSite(
maps: Array<BasicSourceMapConsumer | IndexedSourceMapConsumer>,
maps: Array<TraceMap>,
frame: stackTrace.StackFrame
): IWrappedStackFrame | stackTrace.StackFrame {
const source = frame.getFileName()
Expand All @@ -126,9 +125,9 @@ function getPosition({
maps,
frame,
}: {
maps: Array<BasicSourceMapConsumer | IndexedSourceMapConsumer>
maps: Array<TraceMap>
frame: stackTrace.StackFrame
}): NullableMappedPosition {
}): OriginalMapping | InvalidOriginalMapping {
if (frame.getFileName().includes(`webpack:`)) {
// if source-map-register is initiated, stack traces would already be converted
return {
Expand All @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby-legacy-polyfills/package.json
Expand Up @@ -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",
Expand All @@ -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"
Expand Down
26 changes: 11 additions & 15 deletions 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`)

Expand Down Expand Up @@ -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)
Expand All @@ -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)))
)
})
})
2 changes: 1 addition & 1 deletion packages/gatsby/package.json
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
6 changes: 3 additions & 3 deletions packages/gatsby/src/commands/build-html.ts
Expand Up @@ -229,7 +229,7 @@ const renderHTMLQueue = async (
pagePaths: [pagePath],
})
seenErrors.add(error.stack)
const prettyError = await createErrorFromString(
const prettyError = createErrorFromString(
error.stack,
`${htmlComponentRendererPath}.map`
)
Expand Down Expand Up @@ -304,7 +304,7 @@ const renderHTMLQueue = async (
}

for (const unsafeBuiltinUsedStack of uniqueUnsafeBuiltinUsedStacks) {
const prettyError = await createErrorFromString(
const prettyError = createErrorFromString(
unsafeBuiltinUsedStack,
`${htmlComponentRendererPath}.map`
)
Expand Down Expand Up @@ -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`
)
Expand Down
1 change: 1 addition & 0 deletions 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`)
Expand Down
53 changes: 26 additions & 27 deletions 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`)
Expand Down Expand Up @@ -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<IOriginalSourcePositionAndContent> {
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,
}
}
7 changes: 2 additions & 5 deletions packages/gatsby/src/utils/start-server.ts
Expand Up @@ -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`,
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Expand Up @@ -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==
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit fc5df03

Please sign in to comment.