Skip to main content

Tooling, Build, and Delivery

(Knowing what your pipeline produces and why it matters)

Senior rule:

Build tooling is production behavior, not background machinery.

Atlas can have excellent components and still ship a bad experience if the build emits oversized chunks, broken source maps, stale assets, or unsafe environment variables.

Conceptual Model

The build pipeline decides:

  • what code ships
  • how TypeScript, Babel, SWC, or other transforms change that code
  • how code is split
  • what browsers are supported
  • how assets are hashed and cached
  • whether source maps exist
  • which environment variables leak to the client
  • how failures are rolled back

Dynamic Imports

async function openExportDialog() {
const { ExportDialog } = await import("./ExportDialog");
return ExportDialog;
}

Dynamic imports create split points in both Vite and webpack-based setups. Use them for heavy, infrequent, or route-specific code.

Transforms: TypeScript, Babel, and SWC

Senior engineers distinguish type checking from code transformation:

ToolCommon roleSenior concern
TypeScripttype checking and optional emittypes do not exist at runtime
Babelsyntax transforms and plugin ecosystemtransforms can add helpers and change output size
SWCfast transforms used by modern frameworksspeed does not remove the need to inspect output
esbuildfast bundling/transforms in many toolsnot every plugin or transform behaves like Babel

When a browser target changes, the emitted JavaScript can change materially. Inspect production output after changing targets, transpilation plugins, or polyfill strategy.

Vite Build Awareness

// vite.config.ts
import { defineConfig } from "vite";

export default defineConfig({
build: {
sourcemap: true,
target: "es2022",
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes("node_modules/chart.js")) return "charts";
},
},
},
},
});

Senior questions:

  • what is the target browser baseline?
  • are source maps uploaded securely?
  • did manual chunking improve user experience or only make bundles look tidy?
  • what happens when a dynamic import fails after deployment?

Vite emits a vite:preloadError event for failed dynamic imports, commonly after a deploy removes old chunks.

window.addEventListener("vite:preloadError", () => {
window.location.reload();
});

Use reload carefully. Preserve unsaved work where needed.

webpack Production Awareness

export default {
mode: "production",
optimization: {
splitChunks: {
chunks: "all",
},
},
devtool: "source-map",
};

Production mode enables important optimizations, but seniors still inspect output:

  • duplicate dependencies
  • unexpected polyfills
  • large shared chunks
  • route chunks pulled into the initial path
  • source map exposure rules

CDN and Cache Headers

Static hashed assets can be cached aggressively.

Cache-Control: public, max-age=31536000, immutable

HTML usually should not be cached the same way.

Cache-Control: no-cache

Senior engineers understand which files can be immutable and which files coordinate current deployments.

Environment Variables

export function getClientConfig() {
return {
publicAnalyticsKey: process.env.NEXT_PUBLIC_ANALYTICS_KEY,
};
}

Anything exposed to the browser is public. Do not put secrets in client-prefixed variables.

CI/CD Guardrails

A senior frontend pipeline should include:

  • typecheck
  • lint
  • unit tests
  • selected integration tests
  • e2e smoke tests
  • bundle size check
  • accessibility checks for critical surfaces
  • source map upload
  • artifact retention
  • rollback path

Mini Case Study: Broken Chunks After Deploy

Atlas deployed while users had old HTML open. They clicked Export, which tried to load a chunk that no longer existed.

Fix:

  • retain old assets during deploy window
  • handle dynamic import failure
  • show reload prompt for non-dirty pages
  • protect dirty forms from forced reload
  • monitor chunk load failures by release

The issue was delivery architecture, not component logic.

Common Failure Modes

  • Treating bundle size as the only build metric.
  • Changing Babel/SWC/browser targets without inspecting emitted code.
  • Shipping source maps publicly without a policy.
  • Caching HTML like hashed assets.
  • Leaking secrets through client env vars.
  • Manual chunking without measuring route impact.
  • No rollback or chunk-retention strategy.

Review Checklist

  • Are chunks understandable by route and feature?
  • Are source maps generated and protected?
  • Are cache headers correct for HTML vs assets?
  • Are client environment variables safe?
  • Does CI catch size and test regressions?
  • Can users survive a deploy while the app is open?

Senior Deep Dive: Delivery As Architecture

Build tooling is not just developer experience. It determines what users download, what code executes, what secrets leak, how rollback works, and whether production errors can be diagnosed.

Build artifact review

Senior engineers inspect outputs:

ArtifactReview question
route chunksdid the feature add code to the initial route unnecessarily?
shared/vendor chunkdid one dependency become a global tax?
CSS outputare critical styles available without late layout shifts?
source mapsare they available to observability tools without exposing sensitive code publicly?
environment bundlesdid server-only values leak into client code?
asset filenamesare they immutable and deploy-safe?
generated HTMLdoes it reference assets that will survive rollback?

The weakness this corrects: treating a green build as proof of delivery quality. A green build can still ship broken chunks, leaked config, poor caching, and huge route cost.

Environment configuration model

Classify configuration:

TypeExampleRule
build-time publicanalytics public keysafe to expose, prefixed and documented
runtime server-onlydatabase/API secretnever bundled to browser
runtime client-readablefeature flag bootstrapno secrets, validated shape
deployment metadatarelease SHA, environment nameincluded for observability
experiment configcohort and variantauditable and reversible

Senior engineers do not rely on naming conventions alone. They verify what ends up in the client bundle.

Deploy compatibility

Modern frontend deploys are distributed systems. Users can hold old HTML while new assets are deployed, CDN caches can serve stale files, and service workers can keep old code alive.

A safe deploy plan answers:

  • Are old chunks retained long enough?
  • Can HTML reference a chunk that no longer exists?
  • Can rollback serve compatible assets?
  • Are service worker updates staged?
  • Are API changes backward-compatible with old clients?
  • Are feature flags evaluated consistently across server and client?
  • Is the release identifiable in logs and RUM?

Delivery maturity means the team can roll forward or back without turning cache into a guessing game.

CI gate design

Good CI gates are risk-based:

GateCatches
typecheckcontract and refactor mistakes
lint/architecture rulesforbidden imports, dangerous APIs, boundary violations
unit/component testsdeterministic behavior
contract testsAPI shape drift
E2E smokecritical journey breakage
bundle budgetroute cost creep
accessibility checksobvious semantic regressions
security/dependency scanknown package risk

Avoid gates that are slow, noisy, and unactionable. A gate should fail with a path to remediation.

Rollback readiness

Rollback is a feature. Define who can trigger rollback, whether rollback reverts flags/assets/server code/config, which metrics trigger rollback, how long old assets are retained, how migrations or API changes remain compatible, and how users in active sessions are affected. Senior engineers ask rollback questions before launch, not during an incident.

Exercises

Exercise 1 - Bundle Inspection

Inspect a production build and list the top five largest chunks and why they exist.

Exercise 2 - Cache Header Audit

Compare cache headers for HTML, JS, CSS, images, and API responses.

Exercise 3 - Deploy Failure Drill

Simulate a missing dynamic import chunk. Define the user recovery behavior.

Further Reading