From c301f1d64d2784e4ec015f66838740b6cafb7ae2 Mon Sep 17 00:00:00 2001 From: Jon Jensen Date: Fri, 24 Jun 2022 05:28:37 -0600 Subject: [PATCH] fix(esbuild-plugin-pnp): respect resolveDir (#4569) On-load callbacks can provide a custom `resolveDir` for virtual plugins; if set, it should be used for resolving paths in that file. `importer` is only guaranteed to be a file system path if the namespace is `file`. For context, see: https://esbuild.github.io/plugins/#on-resolve-arguments --- .github/workflows/e2e-esbuild-workflow.yml | 23 ++++++++++++++++++++ .yarn/versions/662b766b.yml | 13 +++++++++++ packages/esbuild-plugin-pnp/sources/index.ts | 8 ++++--- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 .yarn/versions/662b766b.yml diff --git a/.github/workflows/e2e-esbuild-workflow.yml b/.github/workflows/e2e-esbuild-workflow.yml index 7b488f473235..f631f9a26d08 100644 --- a/.github/workflows/e2e-esbuild-workflow.yml +++ b/.github/workflows/e2e-esbuild-workflow.yml @@ -48,3 +48,26 @@ jobs: yarn ts-node --transpile-only build.js [[ "$(node dist/bundle.js)" = "Hello webpack" ]] + + # Make sure we play nicely with esbuild plugins that create virtual modules with resolveDirs + echo "require('esbuild').build({bundle: true, format: 'cjs', target: 'node14', entryPoints: ['./src/main.js'], outfile: './dist/bundle.js', plugins: [require('./virtualModulePlugin'), require('@yarnpkg/esbuild-plugin-pnp').pnpPlugin()]})" > build.js + cat <<- "EOF" | tee virtualModulePlugin.js + const { resolve, dirname } = require('path'); + module.exports = { + name: 'virtualModules', + setup(build) { + build.onResolve({ filter: /\?virtual$/ }, function({ path, importer }) { + const resolveDir = dirname(resolve(dirname(importer), path)); + return { path, pluginData: { resolveDir }, namespace: 'virtual-module' }; + }); + build.onLoad({ filter: /\?virtual$/ }, function({ path, pluginData }) { + const specifier = path.replace(/\?virtual/, ''); + return { resolveDir: pluginData.resolveDir, contents: `export * as virtual from ${JSON.stringify(specifier)}`, loader: 'js' }; + }); + } + } + EOF + echo "import {virtual} from './maths.js?virtual'; console.log(virtual.cube(6));" | tee src/main.js + + yarn ts-node --transpile-only build.js + [[ "$(node dist/bundle.js)" = "216" ]] \ No newline at end of file diff --git a/.yarn/versions/662b766b.yml b/.yarn/versions/662b766b.yml new file mode 100644 index 000000000000..34fb02e73811 --- /dev/null +++ b/.yarn/versions/662b766b.yml @@ -0,0 +1,13 @@ +releases: + "@yarnpkg/builder": patch + "@yarnpkg/esbuild-plugin-pnp": patch + +declined: + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-exec" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/cli" diff --git a/packages/esbuild-plugin-pnp/sources/index.ts b/packages/esbuild-plugin-pnp/sources/index.ts index 379b6495997c..64fff1588dcb 100644 --- a/packages/esbuild-plugin-pnp/sources/index.ts +++ b/packages/esbuild-plugin-pnp/sources/index.ts @@ -139,9 +139,11 @@ export function pnpPlugin({ conditions = conditionsRequire; // The entry point resolution uses an empty string - const effectiveImporter = args.importer - ? args.importer - : `${baseDir}/`; + const effectiveImporter = args.resolveDir + ? `${args.resolveDir}/` + : args.importer + ? args.importer + : `${baseDir}/`; const pnpApi = findPnpApi(effectiveImporter) as PnpApi | null; if (!pnpApi)