| layout | default |
|---|---|
| title | Building the package |
| render_with_liquid | false |
| nav_order | 5 |
The build pipeline compiles TypeScript and JavaScript source files into a publishable npm package. It produces server-side JavaScript, client-side bundles, TypeScript declaration files and a copy of the source files with resolved import paths.
To run the full build:
npm run buildThis executes four steps in sequence: build:server, build:client, build:types and build:src.
Compiles the server-side source code using Babel. TypeScript and JavaScript files in src/ are transpiled to JavaScript and output to .server/. Test files (**/*.test.ts) are excluded. Source maps are generated alongside each output file.
Babel is configured with babel-plugin-module-resolver which resolves the ~ path alias (see Path alias resolution) to relative paths in the compiled .js output.
Bundles client-side JavaScript and stylesheets using webpack. The output is written to .public/ (minified assets) and .server/client/ (shared scripts and styles). The NODE_ENV defaults to production.
Generates TypeScript declaration files (.d.ts) from the source and outputs them to .server/. This step runs two tools in sequence:
tsccompiles declarations usingtsconfig.build.json. Because TypeScript preserves path aliases in its output, the generated.d.tsfiles initially contain unresolved~imports.tsc-aliaspost-processes the.d.tsfiles usingtsconfig.alias.jsonto replace the~path aliases with relative paths.
tsconfig.alias.json exists separately from tsconfig.build.json because the path mappings need to be adjusted for tsc-alias to work correctly. The build config has rootDir: ./src which strips the src/ prefix from output paths. This means tsc-alias needs the mapping ~/src/* -> ./* (rather than ~/* -> ./*) so it can locate the target files within the .server/ output directory.
Runs scripts/resolve-tilde-imports.js which copies the src/ directory to .src/ and resolves all ~/src/... import paths to relative paths in the copy. The original src/ directory is left untouched.
This is necessary because the source files are shipped in the npm package (for source map support) and consumers cannot resolve the ~ path alias.
During development, the codebase uses a ~ path alias as a shorthand for the project root. For example:
import { config } from '~/src/config/index.js'This alias is defined in tsconfig.json:
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"~/*": ["./*"]
}
}
}The ~ alias improves the developer experience by avoiding deeply nested relative paths like ../../../../config/index.js. However, package consumers do not have this alias configured, so all ~ references must be resolved to relative paths before the package is published.
Three separate mechanisms handle this resolution across the different output types:
| Output | Tool | Config |
|---|---|---|
.server/**/*.js |
babel-plugin-module-resolver |
babel.config.cjs |
.server/**/*.d.ts |
tsc-alias |
tsconfig.alias.json |
.src/**/*.ts |
scripts/resolve-tilde-imports.js |
N/A |
The package.json files field controls which directories are included in the published package:
{
"files": [".server", ".public", "src"]
}Note that src is listed here (not .src). The prepack and postpack lifecycle scripts handle the swap:
prepackruns beforenpm packornpm publish. It moves the originalsrc/to.src.bak/and moves the resolved.src/intosrc/. This means npm packs the resolved copy under thesrcdirectory name.postpackruns after packing completes. It restores the originalsrc/and moves the resolved copy back to.src/.
This swap approach avoids destructive operations on the working src/ directory. At no point are the original source files modified.
npm run build # Produces .server/, .public/ and .src/
npm pack # prepack swaps .src -> src, packs, postpack restoresOr equivalently:
npm run build
npm publishThe published package contains:
| Directory | Contents |
|---|---|
.server/ |
Compiled JavaScript (.js), declaration files (.d.ts) and source maps (.js.map) |
.public/ |
Minified client-side assets |
src/ |
TypeScript and JavaScript source files with resolved import paths |