# 0007. Webpack Encore with per-page entries

- **Status:** Accepted
- **Date:** 2025-06-28

## Context

Yii's asset bundle system registers CSS and JS per widget, which either produces many small requests or one
bundle carrying everything. Neither is good for a content site where the homepage, the storage list and the
account area share almost no behaviour.

## Decision

Build assets with **Symfony Webpack Encore**, one entry per controller + action pair, named
`<controllerId><ActionId>` (`articlesIndex`, `storagesDisplay`). Plus `common`, always loaded, and `admin`,
the whole back office in one entry.

The name is **derived, never configured** — `View::getEntryList()` computes it as
`$controller->id . Inflector::id2camel( $controller->action->id )` and looks it up in
`web/build/entrypoints.json`.

CSS is **inlined** into the response; JS is linked.

## Alternatives

- **Yii asset bundles.** Would keep asset declaration next to the widgets, but gives no tree-shaking, no
  Babel and no Sass pipeline without extra tooling.
- **One bundle for everything.** Simplest, and the wrong trade for a public site measured on load time.
- **Per-widget entries.** Too many requests; widgets compose per page anyway.

## Consequences

- **A page loads only what it needs**, which is the point.
- **The entry name is a convention with no error path.** A new page action without a matching entry silently
  loads only `common`. Nothing warns.
- **Node is required to build, and the server has no Node.** `web/build/` is committed, production-built,
  before every push. A dev build reaching production is a live-breaking mistake — hence the separate
  `Build assets (production)` commit and the rule that `web/build/` never enters a phase commit.
- `cleanupOutputBeforeBuild()` means a dev build and a production build cannot coexist in the output
  directory. Whatever ran last is what is there.
- Inlined CSS means it is paid for on every page load rather than cached — deliberate for first-paint, and a
  reason to keep entry stylesheets narrow.
- `./yii dev/create-entry` exists precisely because the naming convention is easy to get wrong by hand.
