From 7548c208209df3860cd9e2d5f6c41d4a3be5fffc Mon Sep 17 00:00:00 2001 From: wtclaude Date: Tue, 11 Aug 2026 01:33:38 -0500 Subject: [PATCH] docs(website): correct the library build, and record slice 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- website/MODULE_API.md | 58 +++++++++++++++++++++++++++++++--------- website/MODULE_SYSTEM.md | 35 ++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/website/MODULE_API.md b/website/MODULE_API.md index aed2c49..de6c820 100644 --- a/website/MODULE_API.md +++ b/website/MODULE_API.md @@ -663,27 +663,33 @@ owns the paths it calls, which is correct: it owns the routes at the other end. ### 3.6 Vite library-mode build -The module's `vite.config.js`, and the four externals are the whole contract: +The module's `vite.config.js`, and the shared-dependency aliases are the whole contract: ```js export default defineConfig({ - plugins: [react()], + plugins: [react(), assertSharedNotBundled()], + resolve: { + // ARRAY form with ANCHORED regexes. The object form does PREFIX matching, so + // a `react` key silently also rewrites `react/jsx-runtime`. + alias: [ + { find: /^react$/, replacement: shim('react') }, + { find: /^react\/jsx-runtime$/, replacement: shim('jsx-runtime') }, + { find: /^react\/jsx-dev-runtime$/, replacement: shim('jsx-runtime') }, + { find: /^react-dom$/, replacement: shim('react-dom') }, + { find: /^react-dom\/client$/, replacement: shim('react-dom') }, + { find: /^react-router-dom$/, replacement: shim('react-router-dom') }, + ], + }, build: { lib: { entry: 'src/entry.jsx', formats: ['es'], fileName: () => 'entry.js' }, outDir: 'dist', modulePreload: { polyfill: false }, // same reason as core: no inline bootstrap under CSP - rollupOptions: { - external: ['react', 'react-dom', 'react-dom/client', 'react-router-dom'], - output: { paths: { /* rewritten to window.__rg by the shim below */ } }, - }, + rollupOptions: { external: [] }, // deliberately empty — see below }, }) ``` -Rollup's `external` alone emits bare `import 'react'` specifiers, which the browser cannot resolve -without an import map — and CSP forbids the inline `