From 3d4e42c3456d8bd578e7acca06967299a182154d Mon Sep 17 00:00:00 2001 From: Jonas Amundsen Date: Tue, 24 Sep 2024 23:38:11 +0200 Subject: [PATCH] Avoid using `path-browserify` This is essentially unmaintained and broken [1]. [1] https://github.com/browserify/path-browserify/issues/32 --- docs/source-maps.md | 8 +++- features/experimental_source_map.feature | 3 +- features/reporters/usage.feature | 3 +- lib/browser-runtime.ts | 4 +- lib/helpers/source-map.ts | 2 + lib/registry.ts | 31 ++------------ lib/subpath-entrypoints/browserify.ts | 7 +-- lib/subpath-entrypoints/esbuild.ts | 54 +++++++++++++++++++----- lib/subpath-entrypoints/rollup.ts | 2 +- lib/subpath-entrypoints/webpack.ts | 2 +- lib/template.ts | 3 -- package.json | 1 - 12 files changed, 61 insertions(+), 59 deletions(-) diff --git a/docs/source-maps.md b/docs/source-maps.md index d3b7e2c7..7fb10bbb 100644 --- a/docs/source-maps.md +++ b/docs/source-maps.md @@ -6,6 +6,11 @@ How to enable source maps for each bundler is shown below. ## esbuild +Source maps can be enabled using an optional argument to `createEsbuildPlugin()`, like seen below. +The process of ensuring that source maps are not only enabled, but also "pretty", is somewhat +cumbersome in lieu of [evanw/esbuild#2218](https://github.com/evanw/esbuild/issues/2218). Hence, +this is disabled by default until it has been sufficiently tested. + ```js const { defineConfig } = require("cypress"); const createBundler = require("@bahmutov/cypress-esbuild-preprocessor"); @@ -23,8 +28,7 @@ async function setupNodeEvents(on, config) { on( "file:preprocessor", createBundler({ - plugins: [createEsbuildPlugin(config)], - sourcemap: "inline" + plugins: [createEsbuildPlugin(config, { prettySourceMap: true })] }) ); diff --git a/features/experimental_source_map.feature b/features/experimental_source_map.feature index e6f73c1d..18a43f95 100644 --- a/features/experimental_source_map.feature +++ b/features/experimental_source_map.feature @@ -26,8 +26,7 @@ Feature: experimental source map on( "file:preprocessor", createBundler({ - plugins: [createEsbuildPlugin(config)], - sourcemap: "inline" + plugins: [createEsbuildPlugin(config, { prettySourceMap: true })] }) ); diff --git a/features/reporters/usage.feature b/features/reporters/usage.feature index 0b129e0a..4f9f01b3 100644 --- a/features/reporters/usage.feature +++ b/features/reporters/usage.feature @@ -22,8 +22,7 @@ Feature: usage report on( "file:preprocessor", createBundler({ - plugins: [createEsbuildPlugin(config)], - sourcemap: "inline" + plugins: [createEsbuildPlugin(config, { prettySourceMap: true })] }) ); diff --git a/lib/browser-runtime.ts b/lib/browser-runtime.ts index 7380792a..73b175ff 100644 --- a/lib/browser-runtime.ts +++ b/lib/browser-runtime.ts @@ -1172,8 +1172,6 @@ export default function createTests( stepDefinitionPatterns: string[]; stepDefinitionPaths: string[]; }, - projectRoot: string, - sourcesRelativeTo: string, dryRun: boolean, ) { const prng = random(seed.toString()); @@ -1183,7 +1181,7 @@ export default function createTests( random: Array.from({ length: 16 }, () => Math.floor(prng() * 256)), }); - registry.finalize(newId, projectRoot, sourcesRelativeTo); + registry.finalize(newId); const testFilter = createTestFilter(gherkinDocument, Cypress.env()); diff --git a/lib/helpers/source-map.ts b/lib/helpers/source-map.ts index 39337971..eeb3e006 100644 --- a/lib/helpers/source-map.ts +++ b/lib/helpers/source-map.ts @@ -94,5 +94,7 @@ export function maybeRetrievePositionFromSourceMap(): Position | undefined { column: relevantFrame.getColumnNumber()!, }); + position.source = position.source.replace(/^webpack:\/\/\//, ""); + return position; } diff --git a/lib/registry.ts b/lib/registry.ts index 18e495ee..c32e3ee9 100644 --- a/lib/registry.ts +++ b/lib/registry.ts @@ -10,8 +10,6 @@ import parse from "@cucumber/tag-expressions"; import { IdGenerator } from "@cucumber/messages"; -import path from "path-browserify"; - import { assertAndReturn } from "./helpers/assertions"; import DataTable from "./data_table"; @@ -119,27 +117,7 @@ export class Registry { this.parameterTypeRegistry = new ParameterTypeRegistry(); } - public finalize( - newId: IdGenerator.NewId, - projectRoot: string, - sourcesRelativeTo: string, - ) { - const finalizePosition = (position?: Position) => { - if (position != null) { - console.log("Original source", position.source); - - position.source = path.relative( - projectRoot, - path.join( - sourcesRelativeTo, - // Why does Webpack do this? I have no idea. - position.source.replace(/^webpack:\/\//, ""), - ), - ); - } - return position; - }; - + public finalize(newId: IdGenerator.NewId) { for (const { description, implementation, position } of this .preliminaryStepDefinitions) { if (typeof description === "string") { @@ -150,7 +128,7 @@ export class Registry { this.parameterTypeRegistry, ), implementation, - position: finalizePosition(position), + position, }); } else { this.stepDefinitions.push({ @@ -160,15 +138,14 @@ export class Registry { this.parameterTypeRegistry, ), implementation, - position: finalizePosition(position), + position, }); } } - for (const { position, ...preliminaryHook } of this.preliminaryHooks) { + for (const preliminaryHook of this.preliminaryHooks) { this.caseHooks.push({ id: newId(), - position: finalizePosition(position), ...preliminaryHook, }); } diff --git a/lib/subpath-entrypoints/browserify.ts b/lib/subpath-entrypoints/browserify.ts index f3c06c8e..56240a9c 100644 --- a/lib/subpath-entrypoints/browserify.ts +++ b/lib/subpath-entrypoints/browserify.ts @@ -25,12 +25,7 @@ export default function transform( try { done( null, - await compile( - configuration, - buffer.toString("utf8"), - filepath, - configuration.projectRoot, - ), + await compile(configuration, buffer.toString("utf8"), filepath), ); debug(`compiled ${filepath}`); diff --git a/lib/subpath-entrypoints/esbuild.ts b/lib/subpath-entrypoints/esbuild.ts index 7103c846..02c77df0 100644 --- a/lib/subpath-entrypoints/esbuild.ts +++ b/lib/subpath-entrypoints/esbuild.ts @@ -10,25 +10,57 @@ import { assertAndReturn } from "../helpers/assertions"; export function createEsbuildPlugin( configuration: Cypress.PluginConfigOptions, + options: { prettySourceMap: boolean } = { prettySourceMap: false }, ): esbuild.Plugin { return { name: "feature", setup(build) { + if (options.prettySourceMap) { + build.initialOptions.sourcemap = "external"; + build.initialOptions.sourcesContent = false; + + build.onEnd(async () => { + const outfile = assertAndReturn( + build.initialOptions.outfile, + "Expected an outfile", + ); + + const sourceMapLocation = outfile + ".map"; + + const sourceMap = JSON.parse( + (await fs.readFile(sourceMapLocation)).toString(), + ); + + /** + * In leu of https://github.com/evanw/esbuild/issues/2218. + */ + sourceMap.sources = sourceMap.sources.map((source: string) => { + return path.relative( + configuration.projectRoot, + path.normalize(path.join(path.dirname(outfile), source)), + ); + }); + + await fs.rm(sourceMapLocation); + + const encoded = Buffer.from(JSON.stringify(sourceMap)).toString( + "base64", + ); + + console.log(encoded.length); + + await fs.appendFile( + outfile, + `//# sourceMappingURL=data:application/json;base64,${encoded}\n`, + ); + }); + } + build.onLoad({ filter: /\.feature$/ }, async (args) => { const content = await fs.readFile(args.path, "utf8"); return { - contents: await compile( - configuration, - content, - args.path, - path.dirname( - assertAndReturn( - build.initialOptions.outfile, - "Expected to find 'outfile'", - ), - ), - ), + contents: await compile(configuration, content, args.path), loader: "js", }; }); diff --git a/lib/subpath-entrypoints/rollup.ts b/lib/subpath-entrypoints/rollup.ts index 91e4c720..c6cd6253 100644 --- a/lib/subpath-entrypoints/rollup.ts +++ b/lib/subpath-entrypoints/rollup.ts @@ -10,7 +10,7 @@ export function createRollupPlugin( async transform(src: string, id: string) { if (/\.feature$/.test(id)) { return { - code: await compile(config, src, id, config.projectRoot), + code: await compile(config, src, id), map: null, }; } diff --git a/lib/subpath-entrypoints/webpack.ts b/lib/subpath-entrypoints/webpack.ts index 5a520b65..09dc5b36 100644 --- a/lib/subpath-entrypoints/webpack.ts +++ b/lib/subpath-entrypoints/webpack.ts @@ -7,7 +7,7 @@ const loader: LoaderDefinition = function (data) { const config: Cypress.PluginConfigOptions = this.query as any; - compile(config, data, this.resourcePath, config.projectRoot).then( + compile(config, data, this.resourcePath).then( (result) => callback(null, result), (error) => callback(error), ); diff --git a/lib/template.ts b/lib/template.ts index f322d31a..f837f997 100644 --- a/lib/template.ts +++ b/lib/template.ts @@ -35,7 +35,6 @@ export async function compile( configuration: Cypress.PluginConfigOptions, data: string, uri: string, - sourcesRelativeTo: string, ) { configuration = rebuildOriginalConfigObject(configuration); @@ -145,8 +144,6 @@ export async function compile( ), stepDefinitionPaths: stepDefinitionPaths.map(ensureRelativeToProjectRoot), }, - configuration.projectRoot, - sourcesRelativeTo, preprocessor.dryRun, ]; diff --git a/package.json b/package.json index f6710e02..65f081e4 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,6 @@ "glob": "^10.4.5", "is-path-inside": "^3.0.3", "mocha": "^10.7.0", - "path-browserify": "^1.0.1", "seedrandom": "^3.0.5", "source-map": "^0.6.1", "split": "^1.0.1",