esbuild-runner icon indicating copy to clipboard operation
esbuild-runner copied to clipboard

Duplicate import in monorepo

Open IlyaSemenov opened this issue 2 years ago • 1 comments

In a monorepo, importing from different files of a sibling workspace package leads to duplicate code in generated bundle.

Consider this monorepo:

  • packages/a/1.ts imports ./shared
  • packages/a/2.ts imports ./shared
  • packages/a/shared.ts — this import gets duplicated in esbuild-runner bundle
  • packages/b/index.ts — imports @test/a/1 and @test/a/2

then run:

cd packages/b
pnpm esr index.ts

The code in shared.ts will execute twice.

Complete minimal reproduction: https://github.com/IlyaSemenov/esbuild-runner-monorepo-duplicate-import

Suggested workaround

I believe here: https://github.com/folke/esbuild-runner/blob/6e5d00b931e75fbee343b96980108299bee7e5e2/src/esbuild.ts#L35-L38

we can filter externals with something like:

.filter(e => !(pkg.dependencies?.[e] || pkg.devDependencies?.[e]).startsWith("workspace:"))

IlyaSemenov avatar Apr 07 '22 11:04 IlyaSemenov

For the time being, I'm using a patch for patch-package.

Put this under patches/esbuild-runner+2.2.1.patch:

# generated by patch-package 6.4.8 on 2022-04-13 10:39:14
#
# command:
#   npx patch-package esbuild-runner
#
# declared package:
#   esbuild-runner: 2.2.1
#
diff --git a/node_modules/esbuild-runner/lib/esbuild.js b/node_modules/esbuild-runner/lib/esbuild.js
index a35df93..0dc08ed 100644
--- a/node_modules/esbuild-runner/lib/esbuild.js
+++ b/node_modules/esbuild-runner/lib/esbuild.js
@@ -20,6 +20,7 @@ var externals = [];
 if (fs_1.default.existsSync(pkgPath)) {
     var pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, { encoding: "utf-8" }));
     externals = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], Object.keys((_a = pkg.dependencies) !== null && _a !== void 0 ? _a : {}), true), Object.keys((_b = pkg.devDependencies) !== null && _b !== void 0 ? _b : {}), true);
+    externals = externals.filter(e => !(pkg.dependencies?.[e] || pkg.devDependencies?.[e]).startsWith('workspace:'))
 }
 exports.loaders = {
     ".js": "js",

IlyaSemenov avatar Apr 13 '22 03:04 IlyaSemenov