Skip to main content

Build Process

Count App uses Angular’s application builder with Server-Side Rendering (SSR) support. The build process compiles your TypeScript code, bundles assets, and generates optimized output for both browser and server.

Production Build

Create a production-ready build:
npm run build
Or using the Angular CLI:
ng build
The default configuration is set to production, which includes optimizations, tree-shaking, and minification.

Build Configurations

Production Configuration

The production build includes:
"production": {
  "budgets": [
    {
      "type": "initial",
      "maximumWarning": "500kB",
      "maximumError": "1MB"
    },
    {
      "type": "anyComponentStyle",
      "maximumWarning": "4kB",
      "maximumError": "8kB"
    }
  ],
  "outputHashing": "all"
}
Features:
  • Output hashing: All files get content-based hashes for cache busting
  • Bundle budgets: Build fails if initial bundle exceeds 1MB
  • Style budgets: Component styles limited to 8kB maximum
  • Optimizations: Minification, tree-shaking, and dead code elimination enabled by default

Development Configuration

For faster builds during development:
npm run watch
This uses the development configuration:
"development": {
  "optimization": false,
  "extractLicenses": false,
  "sourceMap": true
}
Features:
  • No optimization for faster builds
  • Source maps enabled for debugging
  • License extraction disabled
  • Rebuilds automatically on file changes

Build Output Structure

After building, the dist/count-app/ directory contains:
dist/count-app/
├── browser/              # Client-side application files
│   ├── index.html       # Main HTML file
│   ├── main-[hash].js   # Application bundle
│   ├── polyfills-[hash].js
│   └── styles-[hash].css
└── server/              # Server-side rendering files
    └── server.mjs       # Express server for SSR

Browser Output

The browser/ directory contains:
  • Compiled and bundled JavaScript
  • Processed CSS with Tailwind utilities
  • Static assets from the public/ directory
  • Hashed filenames for cache management

Server Output

The server/ directory contains the SSR server built from src/server.ts.

SSR (Server-Side Rendering)

SSR Configuration

The build is configured for SSR in angular.json:
"server": "src/main.server.ts",
"outputMode": "server",
"ssr": {
  "entry": "src/server.ts"
}
Entry points:
  • Browser: src/main.ts
  • Server: src/main.server.ts
  • SSR Server: src/server.ts

Building for SSR

1

Run the build command

The standard build command creates both browser and server bundles:
npm run build
2

Serve the SSR build

After building, serve the application with Node.js:
npm run serve:ssr:count-app
This runs the Express server from dist/count-app/server/server.mjs.
The SSR server uses Express 5.1.0 to handle requests and render pages on the server.

Build Options

TypeScript Configuration

The build uses tsconfig.app.json for compilation:
tsconfig.app.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": ["node"]
  },
  "include": ["src/**/*.ts"],
  "exclude": ["src/**/*.spec.ts"]
}
  • Excludes test files from the build
  • Includes Node.js types for SSR support
  • Outputs to out-tsc/app/

Assets Configuration

Static assets are configured in angular.json:
"assets": [
  {
    "glob": "**/*",
    "input": "public"
  }
]
All files in the public/ directory are copied to the build output.

Styles Configuration

Global styles are specified in angular.json:
"styles": [
  "src/styles.css"
]
This includes your Tailwind CSS configuration and global styles.

Bundle Budgets

The build enforces size budgets to keep your app performant:
  • Warning: 500kB
  • Error: 1MB
The initial JavaScript bundle that loads when the app starts.
If your build exceeds these budgets:
Warning: bundle initial exceeded maximum budget.
Expected: 500kB
Actual: 512kB
Builds that exceed the error threshold will fail. Consider code splitting or lazy loading to reduce bundle size.

Optimization Strategies

Use Angular’s router to lazy load feature modules:
const routes: Routes = [
  {
    path: 'feature',
    loadComponent: () => import('./feature/feature.component')
      .then(m => m.FeatureComponent)
  }
];
Import only what you need from libraries:
// Good: Tree-shakeable
import { map } from 'rxjs/operators';

// Avoid: Imports entire library
import * as rxjs from 'rxjs';
Use Angular CLI’s built-in analysis:
ng build --stats-json
npx webpack-bundle-analyzer dist/count-app/browser/stats.json

Environment-Specific Builds

Build for specific environments:
ng build --configuration production

Serving the Production Build

npm run serve:ssr:count-app
This starts the Express server with server-side rendering.

Static Serving

You can also serve the browser output with any static file server:
npx serve dist/count-app/browser
Static serving won’t include SSR benefits like improved SEO and faster initial page load.

Deployment

The build output is ready for deployment to:
  • Node.js hosts: Deploy the entire dist/count-app/ directory and run the SSR server
  • Static hosts: Deploy only the dist/count-app/browser/ directory
  • Docker: Create a container with Node.js and the build output

Example Dockerfile

FROM node:20-alpine

WORKDIR /app

COPY dist/count-app ./dist/count-app
COPY package.json .

RUN npm install --production

EXPOSE 4000

CMD ["npm", "run", "serve:ssr:count-app"]

Troubleshooting

Your bundle size exceeds the limits. Options:
  1. Implement lazy loading for large features
  2. Remove unused dependencies
  3. Adjust budgets in angular.json (not recommended)
Ensure you built the project first:
npm run build
npm run serve:ssr:count-app
Check your assets configuration in angular.json. Files must be in the public/ directory.

Next Steps

Setup Guide

Return to the setup guide

Testing

Learn about testing your application

Build docs developers (and LLMs) love