docs(website): correct the library build, and record slice 0
Slice 0 built the module bundle skeleton against the contract and found that §3.6 does not work as written. It shows Rollup's `external` alongside the resolve aliases, and the two do not compose: Rollup asks `external` BEFORE Vite's alias resolver runs, so a specifier in both is marked external and never aliased. The chunk then emits bare `import "react"`, which no browser can resolve without an import map, and CSP forbids the inline script an import map has to be. It built cleanly and emitted exactly that. §3.6 is corrected: alias only, `external` empty, with the alias table shown in full because the anchoring is what stops `react` also capturing `react/jsx-runtime`. What `external` was guarding -- a missed alias welding a second React into the chunk -- moves to a resolution-time build plugin, and two properties of that plugin are now contract because both were wrong first: it hooks `transform` rather than `load` (first-wins, so it never ran), and its forbidden-package list is stated rather than derived from the alias list (deriving it means deleting an alias also deletes the guard). Also records slice 0's outcome in §2.7.1, including the finding that generalises past this repo: the boundary check failed on its own documentation, because the comments describing what it catches are written in the syntax it catches. Slice 8's §5.2 grep has the same problem waiting for it. And the loader skips a SYMLINKED module directory silently, which is the first thing to check when a module fails to appear locally. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -801,6 +801,41 @@ rather than core adding an eighth member: the kit is closed on purpose, and a fu
|
||||
props and no layout cannot drift the way a component can. The same is not true of `PublicLayout`,
|
||||
which is why that one is in the kit.
|
||||
|
||||
#### Slice 0 — the bundle skeleton (Module-uo#2, 2026-08-11)
|
||||
|
||||
`module.json`, an entry point taking `(ctx, api)`, the Vite library build, four shims, and both
|
||||
boundary checks. It **registers nothing**, and core is untouched — what it proves is the delivery
|
||||
path itself, before a single UO file moves into it. 29 server tests and 9 client tests, both new.
|
||||
|
||||
Verified against a real core rather than asserted: the module loads, mounts its zero routes, reaches
|
||||
`started` and is published by `/api/v1/public/modules`; its chunk serves from the entry's directory
|
||||
with `Cache-Control: no-cache` while its server source, `module.json` and `package.json` all 404;
|
||||
and in Chrome, under the enforced `script-src 'self'`, the chunk reports every shared dependency
|
||||
**identity-equal** to core's, with zero CSP reports.
|
||||
|
||||
**Three findings, each of which had produced a green build that was wrong.** The first amends the
|
||||
contract and is written up at [API §3.6](MODULE_API.md#36-vite-library-mode-build): `external` and
|
||||
the aliases do not compose, so `external` is now empty and a resolution-time build guard replaces
|
||||
it. The second is that guard's own two failures — hooking `load` (first-wins, so it never ran) and
|
||||
deriving its forbidden list from the alias list (so deleting an alias deleted the guard). Both were
|
||||
found by breaking an alias on purpose and checking the build actually went red, which is the only
|
||||
way a guard's absence is visible.
|
||||
|
||||
The third is about the boundary check itself and generalises past this repo. **`checkImports.js`
|
||||
failed on its own documentation** — the comment naming `require("../../etc/passwd")` as an example
|
||||
of what to catch, and the entry point's comment explaining why a module must never
|
||||
`require('express')`. A check that cannot survive being described is one people stop writing
|
||||
comments around, so it strips comments and template literals with a character walk rather than a
|
||||
regexp (a URL in a string contains a comment opener; a comment contains quotes) and carries its own
|
||||
test suite. The same applies to slice 8's §5.2 grep, which will be read by a codebase that discusses
|
||||
modules constantly.
|
||||
|
||||
**One thing to know before running a module locally: the loader skips a *symlinked* module directory
|
||||
silently.** `readdirSync(…, { withFileTypes: true }).filter(e => e.isDirectory())` reports a Windows
|
||||
junction as a symlink, so a module linked rather than copied into `modules/` is simply not there,
|
||||
with nothing logged. Not a defect for a real install — `modules/` is a bind mount of real
|
||||
directories (§2.5) — but it is the first thing to check when a module fails to appear.
|
||||
|
||||
**Phase 4 — Delivery.** The admin-panel Modules screen (install, enable, disable, retry, purge,
|
||||
`startup_failed` with its recorded reason) and the Docker-environment path from §2.5. Deliberately
|
||||
last, so loader, packaging, schema and chunk-loading problems are not all being debugged at once.
|
||||
|
||||
Reference in New Issue
Block a user