esdev build
esdev build server.ts # → dist/server.js esdev build src/app.ts --out=dist/app.js --minify esdev build styles/app.css --minify # → dist/app.css
One entry, one file, ES modules out. runtime:* imports are left for the runtime to serve, and CommonJS dependencies are converted on the way in.
For a stylesheet entry, the output is CSS rather than JavaScript: its default is dist/<entry>.css. It follows local @imports before it writes. See Browser builds for CSS entry, asset, CSS Module, and library usage.
The CommonJS answer
esrun runs ES modules only, while a large share of npm still ships CommonJS. The bundler converts CJS to ESM on the developer's machine so the deployed artifact remains the text that was reviewed:
esdev build server.js # a CJS dependency goes in esrun dist/server.js # ordinary ESM comes out
esdev test and esdev <file> convert a CommonJS package as they load it, so a test needs no build step. See Imports.
A shorter deploy line
An unbundled program needs --allow-imports, because the loader walks node_modules at runtime. A bundle has no imports left to resolve:
esrun --allow-imports --allow-listen=8080 app.js # unbundled esrun --allow-listen=8080 dist/app.js # bundled
The build is a security step, not only a packaging one.
Options
| Flag | |
|---|---|
--out=<file> | Where to write it (default dist/<entry>.js, or dist/<entry>.css for a stylesheet) |
--minify | Minify the output |
--conditions=<list> | Extra exports conditions, comma-separated; these add to import, default, worker |
--define=<name>=<value> | Replace a name at build time; process.env.NODE_ENV defaults to "production" |
--alias=<name>=<to> | Rewrite a specifier before it resolves; repeatable |
--sourcemap[=<kind>] | A .map beside the output, or =inline, or =hidden |
--target=<name> | Build one target of the project's esdev.json |
--config=<path> | Read this project file instead of ./esdev.json |
--lib, --format, --no-types, --dts-bundle, --css-urls | A library build (Library builds) |
esdev build with no entry builds the targets esdev.json describes, each flag applied to every one of them (Flags on a project build). Naming an entry builds that one, with the project's jsx, resolve.alias and plugins.
What the application build guarantees
runtime:* stays external | It is served by the runtime and has no file behind it. |
| ESM output | The runtime has no other module system. |
process.env.NODE_ENV is defined | Packages branch on it before doing anything, and there is no ambient process global. |
The worker condition is asserted | Packages can select their Web-API build. |
--conditions adds rather than replaces, so asking for one more cannot silently cost the worker condition. A dynamic import() emits a content-hashed chunk beside the entry.
A module named with new URL("./path.js", import.meta.url) is built as a content-hashed chunk of its own, and the URL is rewritten to point at it. That is how a Worker finds its entry in the output, and how a durable worker's shards find the module that defines their classes:
new Worker(new URL("./resize.worker.ts", import.meta.url)); configure({ shards: "auto", module: new URL("./workers.js", import.meta.url) });
Only a literal path to a JavaScript or TypeScript module, with import.meta.url as the base, is built this way. A literal path to any other file is copied into the output, and a computed path is left as written.
The bundler's warnings are printed as the build runs. The one to act on is an import it could not resolve: the bundle keeps it as an import and the build succeeds, but the program fails where it is deployed, so the warning names the file and the line.
Source maps
esdev build src/server.ts --out=dist/server.js --sourcemap
Source maps are off unless asked. The available forms are:
| Option | Result |
|---|---|
--sourcemap | A .map beside the output, pointed at by the bundle |
--sourcemap=inline | A data URL in the file itself |
--sourcemap=hidden | Written, with nothing pointing at it — useful for an error reporter |
"sourcemap": true | The same setting per target in esdev.json; "inline", "hidden" and false are also supported |
A map's sources are relative to the map, so a deployment can be copied anywhere with its sources and still resolve them. The map names nothing about the machine that built it.
esrun remaps printed stack traces through the map, while error.stack inside the program remains the engine's original value.
Watching a build, and ?raw / ?url suffixes on an import.
Choose a focused guide
Project builds —
esdev.json, multiple targets, aliases, environment values, plugins and safe output replacement.Browser builds — HTML entries, imported assets, stylesheets and CSS Modules.
Library builds —
--lib, declarations and CommonJS output.