You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feature #12 [Integrity] Emit Subresource Integrity hashes in entrypoints.json (Kocal)
This PR was merged into the main branch.
Discussion
----------
[Integrity] Emit Subresource Integrity hashes in entrypoints.json
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Issues | Fix #... <!-- prefix each issue number with "Fix #", no need to open an issue if none exists, explain below instead -->
| License | MIT
Add an opt-in `integrity: { enabled, algorithms? }` option (default `['sha384']`)
that writes an `integrity` map (asset URL -> SRI hash) into entrypoints.json, for
Reprise's Symfony bundle (src/RepriseBundle.php, still a stub) to render as
integrity="..." on the script/link tags. This change is JS-only.
Hashes are computed from the files on disk after each bundler finishes emitting: the
Rspack `done` hook and a Vite `writeBundle` hook both read the emitted files back and
hash them. In-memory hashing does not work for Vite because it finalizes chunks (e.g.
replacing `__VITE_PRELOAD__`) only when writing to disk, so the shipped bytes differ
from the bundle. Every referenced file per entry (js/css/preload/dynamic) is covered.
Build only -- the dev server serves changing in-memory assets, so no hashes there.
Commits
-------
9f16080 [Integrity] Emit Subresource Integrity hashes in entrypoints.json
Copy file name to clipboardExpand all lines: AGENTS.md
+4-3Lines changed: 4 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -48,7 +48,7 @@ unplugin still earns its place for Vite and (upcoming) the Stimulus virtual modu
48
48
49
49
## The Symfony integration contract (the core of this project)
50
50
51
-
Encore's real value to Symfony is two JSON files written into `outputPath`, consumed by WebpackEncoreBundle's Twig helpers (`encore_entry_script_tags()`, `encore_entry_link_tags()`, `asset()`). Generating these in Encore-compatible format is the primary work:
51
+
Encore's real value to Symfony is two JSON files written into `outputPath`, consumed by Reprise's **own** Symfony bundle (`RepriseBundle`, the PHP side under `src/` — still a stub) via its Twig helpers that render the `<script>`/`<link>`/`asset()` tags. Reprise does **not** use `symfony/webpack-encore-bundle`. Generating these two files in Encore-compatible format is the primary work:
52
52
53
53
-**`entrypoints.json`** — maps each entry name to its asset URLs grouped by type, in load order (runtime chunks before app chunks). Optional `integrity` section for SRI hashes.
54
54
```json
@@ -61,7 +61,7 @@ Encore's real value to Symfony is two JSON files written into `outputPath`, cons
61
61
The plugin must behave differently depending on the bundler mode:
62
62
63
63
- **Build mode** (`vite build`, `rsbuild build`): assets are written to `outputPath` with content hashes; `entrypoints.json`/`manifest.json` point at those files under `publicPath`.
64
-
- **Serve/dev mode** (`vite`, `rsbuild dev`): the bundler's own dev server holds modules in memory and serves them over HTTP with native ESM + HMR. Here `entrypoints.json` must instead point at the dev server origin (e.g. `http://127.0.0.1:5173/build/app.js`) and inject the HMR client (`@vite/client`; React additionally needs the refresh preamble), so WebpackEncoreBundle's Twig tags load from the running dev server rather than from disk.
64
+
- **Serve/dev mode** (`vite`, `rsbuild dev`): the bundler's own dev server holds modules in memory and serves them over HTTP with native ESM + HMR. Here `entrypoints.json` must instead point at the dev server origin (e.g. `http://127.0.0.1:5173/build/app.js`) and inject the HMR client (`@vite/client`; React additionally needs the refresh preamble), so RepriseBundle's Twig tags load from the running dev server rather than from disk.
65
65
66
66
The dev server itself is native to Vite/Rsbuild — this plugin does not run one. Its only dev-server responsibility is detecting the mode (unplugin `meta`, or Vite's `configResolved` `command === 'serve'` vs `'build'`; Rsbuild/Rspack expose the same distinction) and emitting the dev-flavored `entrypoints.json` plus client injection. Encore's counterpart is `configureDevServerOptions()` (webpack-dev-server) in the reference `index.ts`, but that whole layer is replaced by the native dev server.
67
67
@@ -95,5 +95,6 @@ Read-only clones under `.references/` (git-ignored) show how mature unplugins ar
95
95
- ESM only, strict TypeScript, ES2017 target. Use the `node:` prefix for Node builtins.
96
96
- New public options go in `assets/src/types.ts` with JSDoc; keep bundler adapters trivial.
97
97
- Documentation: any user-facing feature ships with a short section in `doc/index.rst`, and that section shows **both** a Vite and an Rsbuild example (the two supported bundlers) — never document one without the other. Flip the matching `*(planned)*` marker in the feature lists (`doc/index.rst` and `README.md`) when the feature lands. Match the existing sections' natural voice; draft/polish the prose with the `natural-writing-editor` agent.
98
-
- Commit messages: Symfony style `[<Scope>] <Short description>` — PascalCase scope, imperative mood, capitalized first word, no trailing period; combine scopes as `[A][B]` when a change spans several. E.g. `[Stimulus] Emit forward-slash local controller paths`, `[Docs] Frame Stimulus usage as the Encore experience`, `[CI] Cancel superseded runs with a concurrency group`. This is the convention used across Symfony UX and WebpackEncoreBundle — **not** Conventional Commits (no `feat:`/`fix:`/`chore:` prefixes).
98
+
- Tests: a functional/integration test for one bundler (Vite or Rsbuild) always ships with its equivalent for the other — never cover one bundler without the other, including the negative/off cases.
99
+
- Commit messages: Symfony style `[<Scope>] <Short description>` — PascalCase scope, imperative mood, capitalized first word, no trailing period. A feature commit uses the feature's **own name** as the scope (e.g. `[Integrity]`, `[Manifest]`) and does **not** tack on `[Tests]` or `[Docs]` for the tests and docs it naturally includes; `[Tests]`/`[Docs]` are only for changes that are _exclusively_ tests or documentation. Combine scopes as `[A][B]` only when a change genuinely spans several distinct components. E.g. `[Stimulus] Emit forward-slash local controller paths`, `[Docs] Frame Stimulus usage as the Encore experience`, `[CI] Cancel superseded runs with a concurrency group`. This is the convention used across Symfony UX and WebpackEncoreBundle — **not** Conventional Commits (no `feat:`/`fix:`/`chore:` prefixes).
99
100
- Releases: the published npm package lives in `assets/` (`@symfony/reprise`); its `prepublishOnly` runs the `tsdown` build before publish.
Copy file name to clipboardExpand all lines: README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,11 +31,11 @@ Symfony Reprise covers only the Symfony-side glue the bundlers leave out:
31
31
- 🔥 **Dev server & HMR**: points Twig at the running Vite/Rsbuild server
32
32
- 🧩 **Symfony UX / Stimulus**: registers `controllers.json` and local controllers, eager or lazy
33
33
- 🌐 **CDN support**: serve built assets from an absolute `publicPath`
34
-
- 🛡️ **Subresource Integrity**: SRI hashes in `entrypoints.json`_(planned)_
34
+
- 🛡️ **Subresource Integrity**: SRI hashes in `entrypoints.json`
35
35
- 📦 **Shared runtime chunk**: one runtime shared across entries _(planned)_
36
36
37
37
Vite and Rsbuild already handle **Sass/Less/PostCSS**, **TypeScript**, **JSX/Vue/Svelte**, **code splitting**, **content hashing**, **source maps**, **minification** and **HMR** on their own, so Symfony Reprise does not reimplement any of that.
38
38
39
-
It generates the Encore-compatible `entrypoints.json` and `manifest.json` that [WebpackEncoreBundle](https://github.com/symfony/webpack-encore-bundle)'s Twig helpers (`encore_entry_script_tags()`, `encore_entry_link_tags()`) read, wires up the native dev server, and turns your Stimulus controllers into a running application.
39
+
It generates the Encore-compatible `entrypoints.json` and `manifest.json` that Reprise's own Symfony bundle (`RepriseBundle`, still a stub) reads to render the `<script>` and `<link>` tags, wires up the native dev server, and turns your Stimulus controllers into a running application.
0 commit comments