How to Create a Single File Bundle of a Large Typescript Project in 2023
I’ve been struggling with how to package a large ‘monorepo’ typescript project with several sub-projects inside an npm workspace.
Ideally I want a single file (two if you count the typedef file) to act as the distributable.
This is a very simple ask, yet though many packaging tools semi-claim to do something like this, I’ve only found one that works reliably.
Use esbuild to compile entire TypeScript monorepo to a single large JavaScript file.
Create a file called build.js
const { build } = require("esbuild");
const { dependencies, peerDependencies } = require('./package.json');
const sharedConfig = {
entryPoints: ["src/index.ts"],
bundle: true,
minify: false,
// only needed if you have dependencies
// external: Object.keys(dependencies).concat(Object.keys(peerDependencies)),
};
build({
...sharedConfig,
platform: 'browser',
format: 'esm',
outfile: "dist/index.js",
});
And run it like:
$ node ./build.js
Use dts-bundle-generator to build as single TypeScript defintion (.d.ts) file.
NOTE: this is a slow process on a large project, can take a few minutes.
$ npx dts-bundle-generator -o dist/index.d.ts src/index.ts
What this accomplishes
- A single javascript file with NO weird workspace-sub-project import dependencies (that tools like
npm pack
deal poorly with) - A single typescript definition file with NO weird workspace-sub-project import dependencies.
Originally published at https://github.com/matthewjosephtaylor.