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:
| Tool | Common role | Senior concern |
|---|---|---|
| TypeScript | type checking and optional emit | types do not exist at runtime |
| Babel | syntax transforms and plugin ecosystem | transforms can add helpers and change output size |
| SWC | fast transforms used by modern frameworks | speed does not remove the need to inspect output |
| esbuild | fast bundling/transforms in many tools | not 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:
| Artifact | Review question |
|---|---|
| route chunks | did the feature add code to the initial route unnecessarily? |
| shared/vendor chunk | did one dependency become a global tax? |
| CSS output | are critical styles available without late layout shifts? |
| source maps | are they available to observability tools without exposing sensitive code publicly? |
| environment bundles | did server-only values leak into client code? |
| asset filenames | are they immutable and deploy-safe? |
| generated HTML | does 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:
| Type | Example | Rule |
|---|---|---|
| build-time public | analytics public key | safe to expose, prefixed and documented |
| runtime server-only | database/API secret | never bundled to browser |
| runtime client-readable | feature flag bootstrap | no secrets, validated shape |
| deployment metadata | release SHA, environment name | included for observability |
| experiment config | cohort and variant | auditable 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:
| Gate | Catches |
|---|---|
| typecheck | contract and refactor mistakes |
| lint/architecture rules | forbidden imports, dangerous APIs, boundary violations |
| unit/component tests | deterministic behavior |
| contract tests | API shape drift |
| E2E smoke | critical journey breakage |
| bundle budget | route cost creep |
| accessibility checks | obvious semantic regressions |
| security/dependency scan | known 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
- Vite: Building for production - https://vite.dev/guide/build
- Vite: Performance - https://vite.dev/guide/performance
- webpack: Code splitting - https://webpack.js.org/guides/code-splitting/
- webpack: Production - https://webpack.js.org/guides/production/
- MDN: HTTP caching - https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching