esbuild-node-externals icon indicating copy to clipboard operation
esbuild-node-externals copied to clipboard

Support for ignoring node_modules in sibling packages in monorepo

Open IlyaSemenov opened this issue 2 years ago • 3 comments

Consider a pnpm monorepo:

packages/foo (depends on axios, bar)
packages/bar (depends on express)

I would like to have foo and bar compiled, but keep axios and express as external.

If I create the build script for foo:

const { build } = require('esbuild')
const { nodeExternalsPlugin } = require('esbuild-node-externals')

build({
  // ...
  plugins: [
    nodeExternalsPlugin({
      allowList: ['bar']
    })
  ]
})

then foo, bar and express are compiled, and only axios is considered external.

Ideally, I would like the plugin to handle the monorepo setup automatically (recognize that bar is not even a package inside node_modules without having to specify any option, not even allowList).

IlyaSemenov avatar Mar 31 '22 12:03 IlyaSemenov

To clarify: a sibling monorepo package is referred like this in package.json:

{
  "name": "foo",
  "dependencies": {
    "bar": "workspace:*"
  }
}

I suppose this should be enough to recognize it?

IlyaSemenov avatar Apr 13 '22 03:04 IlyaSemenov

Could be a good way to detect this 👍 Happy to accept a pr for this :)

pradel avatar Apr 13 '22 09:04 pradel

Something like the below in utils.ts (perhaps exposed as an option rather than always running) would probably do the trick:

return packageJsonKeys
  .map((key) => {
    if (!packageJson[key]) return [];

    // filter out yarn workspace references
    return Object.keys(packageJson[key]).filter((packageName) => !packageJson[key][packageName].startsWith('workspace:'))
  })
  .flat(1)
  .filter((packageName) => !options.allowList.includes(packageName));

marbemac avatar Apr 29 '22 20:04 marbemac

Added in 1.10.0

pradel avatar Nov 20 '23 12:11 pradel