0

Consider this very contrived npm package:

import clone from "lodash.clonedeep";
import calculate from "./utils/calculate"; // ".ts" omitted

function x(obj:any):number {
  return calculate(clone(obj).a, clone(obj).b);
}
export { x }

Imagine we want an esm build of this.

  • If we set esbuild to "bundle", both external clone and internal calculate imports will end up in the generated file. (That's cool, I want that for iife build).
  • If we set esbuild not to "bundle", neither external clone nor internal calculate will end up in the generated file. (That's not cool, I want calculate bundled still).

In Rollup, "bundling" in this sense pertains only for external imports; internal-ones are all placed into one file by default.

Do you know how to set esbuild to include only internal file imports? To get:

import clone from "lodash.clonedeep";

function calculate(a, b) {
  return a * b;
}
function x(obj){
  return calculate(clone(obj).a, clone(obj).b);
}
export { x }

I'm simply trying to make some esm/cjs npm package builds.

Other questions in SO are different: this one is concatenating multiple files into one. Here we're just trying to replicate Rollup's behaviour, to include local imports but not external, like in a normal npm package. Thank you.

revelt
  • 2,312
  • 1
  • 25
  • 37

1 Answers1

3

The answer is, same like in Rollup — enable "bundle", but skip bundling external dependencies by setting external. This way, local imports won't be bundled because they are not in package.json.

const path = require("path");
const pkg = require(path.resolve("./package.json"));

const external = [
  ...Object.keys(pkg.dependencies || {}),
  ...Object.keys(pkg.peerDependencies || {}),
];

// ESM
require('esbuild').buildSync({
  entryPoints: ['src/main.ts'],
  format: 'esm',
  bundle: true,
  minify: false,
  sourcemap: false,
  target: ['esnext'],
  outfile: 'dist/yourProgram.esm.js',
  external,
});
revelt
  • 2,312
  • 1
  • 25
  • 37