egoist / tsup

The simplest and fastest way to bundle your TypeScript libraries.
https://tsup.egoist.dev
MIT License
9.01k stars 217 forks source link

bundle: false only includes entrypoint modules in output #1000

Open sentience opened 1 year ago

sentience commented 1 year ago

Minimal reproduction: https://github.com/sentience/tsup-bundle-false-issue

export default defineConfig({
  bundle: false,
  format: ["esm"],
  dts: true,
  splitting: true,
  entry: {
    index: "src/index.ts",
  },
})

The bundle option is only documented as "Disable bundling" in the API docs, but what I (perhaps incorrectly) expected it to do was to output all modules referenced by my entry module(s), but not bundle them into the entry modules.

So if I had:

src/index.ts

export { foo } from './foo.js'

src/foo.ts

export function foo() {
  console.log("This is a function that should make it into the output of this package.")
}

I would expect tsup to output two JavaScript files:

dist/index.mjs

import { foo } from "./foo.js"
export {
  foo
}

dist/foo.mjs

export function foo() {
  console.log("This is a function that should make it into the output of this package.")
}

Instead, tsup only outputs the first of those two files. The implementation of foo is left out of the build output entirely.

Is this really what bundle: false is supposed to do? If so, I don't understand what the use case for this option is.

My use case is to publish an ESM package with no bundling in order to maximise its tree-shakeability, assuming the consuming project will use a bundler to tree-shake dependencies and produce browser-ready bundles.

Upvote & Fund

Fund with Polar

smeijer commented 1 year ago

I think this needs to be used with multiple entries:

export default defineConfig({
  entry: ['src/**/*.{ts,tsx}'],    // < all files in src/
  bundle: false,
  clean: true,
  dts: true,
  format: ['cjs', 'esm'],
});
sentience commented 1 year ago

@smeijer I would call that a work-around. If bundle: false produces broken output unless you declare every one of your source files as an entrypoint, that seems like a bug to me. (Or at least missing documentation.)

marbemac commented 11 months ago

I would call that a work-around. If bundle: false produces broken output unless you declare every one of your source files as an entrypoint, that seems like a bug to me

Agree! What I expected when I ran into this was that the resulting output would include my specified entry files along with any other files in their module graphs (so things like test files, etc, are automatically not included in the output). Creating a glob pattern to match all files except those in certain directories like __tests__ etc is tricky (maybe not possible?).

While it doesn't solve the confusion around bundle: false, could at least achieve the compile everything but test/fixture/etc type of files use case if entry accepted a (entryPath: string) => boolean style function for more flexible filtering logic.