Building the package
Overview
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.
Build steps
build:server
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.
build:client
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.
build:types
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.
build:src
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.
Path alias resolution
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 |
Packaging for npm
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.
Build and publish workflow
npm run build # Produces .server/, .public/ and .src/npm pack # prepack swaps .src -> src, packs, postpack restoresOr equivalently:
npm run buildnpm publishPackage contents
The 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 |