Open daolou opened 2 years ago
Maybe you meant about the legacy output modifier. If not, what would be the expected output?
I want is code split,like this:
dist
- tool1
- tool1.js
- tool1.mjs
- tool2
- tool2.js
- tool2.mjs
- tool3
- tool3.js
- tool3.mjs
- index.js
- index.mjs
An approach I take to achieve something similar is to set up entry
with a glob that would output an array of files, for example
import glob from 'tiny-glob'
import { defineConfig } from 'tsup'
export default defineConfig(async () => {
return [
{
entry: await glob('./src/**/!(*.d|*.spec).ts'),
Maybe to elaborate, this seems appropriate when building libraries of React component or libraries of independant utilities (lodash style), see: https://stackoverflow.com/questions/72149666/a-fool-proof-tsup-config-for-a-react-component-library In this case you want to generate one .js per component.
We seem to need:
bundle: false
to disable bundling and keep only the transpiling step.I still struggle to keep the directory structure. If entry is ["index.ts", "./smth/nested.ts"]
, the smth
folder will be created. But this is probably not what you want since you need no bundling for index, and bundling for "nested". If entry is ["./smth/nested.ts"]
it won't respect the directory structure.
Edit: here is the final result. Components are bundled with code splitting (in case 2 components use the same internal sub component for instance), index files are not bundled, only transpiled, and uses an explicit ".js" which is necessary for ESM modules to work. I am surprised that the ".js" extension is accepted by TypeScript, but it works. Named import works as expected, and tree shaking is now possible because each component leaves in an isolated ES module. This is not perfect but a good first step.
An approach I take to achieve something similar is to set up
entry
with a glob that would output an array of files, for exampleimport glob from 'tiny-glob' import { defineConfig } from 'tsup' export default defineConfig(async () => { return [ { entry: await glob('./src/**/!(*.d|*.spec).ts'),
It's entry seem support glob:
export default defineConfig([
{
entry: ['src/**/*.ts'],
splitting: true,
target: 'es5',
format: 'cjs',
dts: true,
treeshake: true,
bundle: false,
}
]);
Just to answer this precise question:
outDir: "./dist",
esbuildOptions(options, context) {
// the directory structure will be the same as the source
options.outbase = "./";
},
},
The "outbase" option of esbuild will force the bundled files to have the same directory structure as the source.
I've updated my Stack Overflow answer here: https://stackoverflow.com/a/73883783/5513532
At this point I am stuck with one last thing, I need to add ".js" to the imports of "index.ts" and can't find a way to do that during bundling. So I add the ".js" manually in the "index.ts" source (sounds weird, but it works), except that now it breaks storybook.
Just to answer this precise question:
outDir: "./dist", esbuildOptions(options, context) { // the directory structure will be the same as the source options.outbase = "./"; }, },
The "outbase" option of esbuild will force the bundled files to have the same directory structure as the source.
I've updated my Stack Overflow answer here: https://stackoverflow.com/a/73883783/5513532
At this point I am stuck with one last thing, I need to add ".js" to the imports of "index.ts" and can't find a way to do that during bundling. So I add the ".js" manually in the "index.ts" source (sounds weird, but it works), except that now it breaks storybook.
use bundle: false
and entry: ['./src/**/*.ts']
also work, but I have another problem: compilerOptions.paths
not resolved
BTW
if use options.outbase = "./";
, it maybe affect esbuild-plugins that use build.onResolve
;
One drawback to using globs in entry
is that new files aren't picked up, so you have to restart tsup whenever adding a new file that matches one of the globs in entry
.
Just to answer this precise question:
outDir: "./dist", esbuildOptions(options, context) { // the directory structure will be the same as the source options.outbase = "./"; }, },
The "outbase" option of esbuild will force the bundled files to have the same directory structure as the source. I've updated my Stack Overflow answer here: https://stackoverflow.com/a/73883783/5513532 At this point I am stuck with one last thing, I need to add ".js" to the imports of "index.ts" and can't find a way to do that during bundling. So I add the ".js" manually in the "index.ts" source (sounds weird, but it works), except that now it breaks storybook.
use
bundle: false
andentry: ['./src/**/*.ts']
also work, but I have another problem:compilerOptions.paths
not resolved
Have you got a change to find a solution to compilerOptions.paths
not being resolved, I have tried a couple of esbuild plugins to temporary fix but to no avail. For DTS part of the application it seems to resolve quite fine, but JavaScript part as you indicate is not resolved.
I guess this behavior is caused by esbuild not following any paths in the tsconfig when the bundling options is off.
I scoured the documentation and couldn't find the bundle: false
option. In my case, I just want to replace tsc
with tsup
cause tsc
is too slow. Maybe we should add a section about bundle
option to documentation?
For anybody stumbling accross the issue I ended up combining what I usually use for tsc.
Setting bundle to false as expected stops following paths on esbuild side of things. I suppose this would not be a concern of tsup. From the esbuild side I could not make it work using alias plugins and injecting tsconfig in.
So just used tsconfig-replace-paths cli to swap paths on onsuccess step. It is still fast and stable enough for me so that I prefer not to mark it as being a trade off.
Something like as below:
https://github.com/tailoredmedia/backend-nx-skeleton/blob/master/packages/nx-nest/tsup.config.ts
Are you guys also having the issue that it gives the error on the first line No input files, try "tsup <your-file>" instead
? Getting stuck on this piece of code: https://github.com/egoist/tsup/blob/main/src/index.ts#L77-L79 while I just have the config
{
bundle: false,
entry: ['src/**/*.{ts,tsx}', '!src/**/*.stories.{ts,tsx}', '!src/**/*.d.{ts,tsx}'],
}
tried all, none of them worked π’
I was trying to build a node library to use in both CJS and ESM environments and figured it out with
tsup ./src --format cjs,esm --no-splitting --dts --tsconfig tsconfig.build.json
to:
.d.ts
files for library consumersHope it helps someone :)
I was trying to build a Discord bot and changing entry from entry: ['src/index.ts']
to entry: ['src/**/*']
worked. I hope this helps.
Interestingly, using the glob pattern src/**/*
works fine with a structure like this:
./src
βββ index.ts
βββ types
βββ application.ts
βββ new-file.ts
Yields
./dist
βββ index.js
βββ types
βββ application.js
βββ new-file.js
But when the src
directory has no top-level files, a nesting level is omitted:
./src
βββ types
βββ application.ts
βββ new-file.ts
Yields
./dist
βββ application.js
βββ new-file.js
Perhaps I should create a new issue for this, though. It may even be an esbuild problem.
Such as above,
src/index.ts
isexports
all, then usetsup src/index.ts --format esm,cjs,iife
build,it will output:it not I want.
Upvote & Fund