Skip to content

Commit df57922

Browse files
committed
[wip] vite
1 parent 6a217f0 commit df57922

22 files changed

Lines changed: 1448 additions & 662 deletions

.changeset/vite-web-generator.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@node-core/doc-kit': minor
3+
---
4+
5+
Rebuild the `web` generator around Vite 8.1

eslint.config.mjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ export default defineConfig([
9797
languageOptions: {
9898
globals: {
9999
...globals.browser,
100-
// SERVER and CLIENT denote server-only and client-only
101-
// codepaths in our web generator
102-
CLIENT: 'readonly',
103-
SERVER: 'readonly',
104100
},
105101
ecmaVersion: 'latest',
106102
},

package-lock.json

Lines changed: 492 additions & 111 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
"@node-core/ui-components": "^1.7.2",
6868
"@orama/orama": "^3.1.18",
6969
"@orama/ui": "^1.5.4",
70-
"@rollup/plugin-virtual": "^3.0.2",
7170
"@swc/html-wasm": "^1.15.43",
7271
"acorn": "^8.17.0",
7372
"commander": "^15.0.0",
@@ -78,7 +77,6 @@
7877
"glob-parent": "^6.0.2",
7978
"hast-util-to-string": "^3.0.1",
8079
"hastscript": "^9.0.1",
81-
"lightningcss-wasm": "^1.32.0",
8280
"mdast-util-slice-markdown": "^2.0.1",
8381
"oxc-parser": "^0.139.0",
8482
"piscina": "^5.2.0",
@@ -94,7 +92,6 @@
9492
"remark-parse": "^11.0.0",
9593
"remark-rehype": "^11.1.2",
9694
"remark-stringify": "^11.0.0",
97-
"rolldown": "1.1.3",
9895
"semver": "^7.8.5",
9996
"shiki": "^4.3.0",
10097
"tinyglobby": "^0.2.17",
@@ -105,6 +102,7 @@
105102
"unist-util-remove": "^4.0.0",
106103
"unist-util-select": "^5.1.0",
107104
"unist-util-visit": "^5.1.0",
105+
"vite": "~8.1.5",
108106
"yaml": "^2.9.0"
109107
}
110108
}

src/generators/web/README.md

Lines changed: 53 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
# `web` Generator
22

3-
The `web` generator transforms JSX AST entries into complete web bundles, producing server-side rendered HTML pages, client-side JavaScript with code splitting, and bundled CSS styles.
3+
The `web` generator transforms JSX AST entries into complete web bundles. Vite
4+
builds server-rendered HTML and hashed client-side JavaScript, CSS, and imported
5+
assets. When `output` is configured, the client output also includes
6+
`.vite/manifest.json` and `importmap.json`.
47

58
## Configuring
69

710
The `web` generator accepts the following configuration options:
811

9-
| Name | Type | Default | Description |
10-
| ----------------- | --------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
11-
| `output` | `string` | - | The directory where HTML, JavaScript, and CSS files will be written |
12-
| `templatePath` | `string` | `'template.html'` | Path to the HTML template file |
13-
| `project` | `string` | `'Node.js'` | Project name used in page titles and the version selector |
14-
| `title` | `string` | `'{project} v{version} Documentation'` | Title template for HTML pages (supports `{project}`, `{version}`) |
15-
| `useAbsoluteURLs` | `boolean` | `false` | When `true`, all internal links use absolute URLs based on `baseURL` |
16-
| `editURL` | `string` | `'${GITHUB_EDIT_URL}/doc/api{path}.md'` | URL template for "edit this page" links |
17-
| `pageURL` | `string` | `'{baseURL}/latest-{version}/api{path}.html'` | URL template for documentation page links |
18-
| `remoteConfigUrl` | `string` | `'https://nodejs.org/site.json'` | URL fetched client-side at runtime for remote site config (currently used to power the announcement banner) |
19-
| `head` | `object` | See below | Configurable `<meta>`, `<link>`, and raw markup for the document head |
20-
| `lightningcss` | `object` | `{}` | Options spread into LightningCSS while bundling CSS (see below) |
21-
| `imports` | `object` | See below | Object mapping `#theme/` aliases to component paths for customization |
22-
| `virtualImports` | `object` | `{}` | Additional virtual module mappings merged into the build |
23-
| `components` | `object` | `{}` | Maps JSX tag names to component imports, enabling JSX-in-MDX (see below) |
24-
| `rolldown` | `object` | `{}` | Options merged into the Rolldown build — extra plugins, etc. (see below) |
12+
| Name | Type | Default | Description |
13+
| ----------------- | ------------ | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
14+
| `output` | `string` | - | The directory where HTML and Vite's hashed client output will be written |
15+
| `templatePath` | `string` | `'template.html'` | Path to the HTML template file |
16+
| `project` | `string` | `'Node.js'` | Project name used in page titles and the version selector |
17+
| `title` | `string` | `'{project} v{version} Documentation'` | Title template for HTML pages (supports `{project}`, `{version}`) |
18+
| `useAbsoluteURLs` | `boolean` | `false` | When `true`, all internal links use absolute URLs based on `baseURL` |
19+
| `editURL` | `string` | `'${GITHUB_EDIT_URL}/doc/api{path}.md'` | URL template for "edit this page" links |
20+
| `pageURL` | `string` | `'{baseURL}/latest-{version}/api{path}.html'` | URL template for documentation page links |
21+
| `remoteConfigUrl` | `string` | `'https://nodejs.org/site.json'` | URL fetched client-side at runtime for remote site config (currently used to power the announcement banner) |
22+
| `head` | `object` | See below | Configurable `<meta>`, `<link>`, and raw markup for the document head |
23+
| `imports` | `object` | See below | Object mapping `#theme/` aliases to component paths for customization |
24+
| `virtualImports` | `object` | `{}` | Additional virtual module mappings merged into both Vite builds |
25+
| `components` | `object` | `{}` | Maps JSX tag names to component imports, enabling JSX-in-MDX (see below) |
26+
| `vite` | `UserConfig` | `{}` | Vite configuration merged into the client and SSR builds (see below) |
2527

2628
### `head`
2729

@@ -67,93 +69,51 @@ export default {
6769
> via `head`: `og:title` (mirrors the per-page title), `og:type`, and the font
6870
> preconnects/stylesheet the bundled UI components rely on.
6971
70-
### Custom LightningCSS options
72+
### Custom Vite options
7173

72-
The `lightningcss` object is spread directly into [LightningCSS][lightningcss]
73-
while CSS is bundled, so any of its options`visitor` (custom plugins),
74-
`customAtRules`, `targets`, `drafts`, and so on — are supported. The generator
75-
manages `filename`, `code`, `cssModules`, and `resolver`, so those are ignored.
74+
The `vite` object is merged into both production builds. This supports Vite
75+
plugins, aliases, `define`, asset options, and native Lightning CSS settings.
76+
Use `import.meta.env.SSR` inside application code or plugin transforms when
77+
behavior must differ between the SSR and browser builds.
7678

7779
```js
7880
// doc-kit.config.mjs
79-
export default {
80-
web: {
81-
lightningcss: {
82-
customAtRules: {
83-
mixin: { prelude: '<custom-ident>', body: 'style-block' },
84-
},
85-
visitor: {
86-
Color(color) {
87-
// e.g. transform every color through a design-token map
88-
return color;
89-
},
90-
},
91-
},
92-
},
93-
};
94-
```
95-
96-
To apply more than one visitor, compose them with LightningCSS's
97-
`composeVisitors` helper and pass the result as `visitor`.
98-
99-
[lightningcss]: https://lightningcss.dev/transforms.html
100-
101-
### Custom Rolldown options
102-
103-
The `rolldown` object is merged into the [Rolldown][rolldown] `build` call used
104-
for **both** the client and server bundles, so you can register extra plugins,
105-
inject compile-time constants, add module aliases, or set any other Rolldown
106-
option. The same config is applied to both builds — branch inside a plugin (or
107-
read the `SERVER`/`CLIENT` defines) if you need per-target behavior.
108-
109-
The merge follows these rules:
110-
111-
- **`plugins`** are registered after the built-in virtual-module plugin (so
112-
they see the in-memory entry modules) and before the CSS loader.
113-
- **`transform.define`** and **`resolve.alias`** are merged key-by-key, so you
114-
can add entries without dropping the generator's. The built-in `SERVER`/
115-
`CLIENT` defines and the `react`/`react-dom``preact/compat` aliases
116-
(plus anything from `imports`) always win.
117-
- **All other options** (e.g. `output.minify`, `treeshake`, `external`,
118-
`platform`, `logLevel`) override the generator's defaults.
119-
- **`input`** and the built-in plugins are managed by the generator and cannot
120-
be overridden.
121-
122-
> Functions (plugins, hooks, alias resolvers, etc.) are allowed here because the
123-
> `web` generator runs entirely on the main thread. Unlike the chunked
124-
> generators, its config is never serialized to a worker, so values that can't
125-
> be structured-cloned are safe. Keep this in mind if `web` ever gains parallel
126-
> processing: function-valued options would then need a serializable form.
127-
128-
```js
129-
// doc-kit.config.mjs
130-
import myRolldownPlugin from './my-rolldown-plugin.mjs';
81+
import myVitePlugin from './my-vite-plugin.mjs';
13182

13283
export default {
13384
web: {
134-
rolldown: {
135-
// Register additional plugins (run after the built-in ones).
136-
plugins: [myRolldownPlugin()],
137-
138-
// Inject extra compile-time constants (merged with SERVER/CLIENT).
139-
transform: {
140-
define: {
141-
'process.env.ANALYTICS_ID': JSON.stringify('UA-XXXXX'),
142-
},
85+
vite: {
86+
plugins: [myVitePlugin()],
87+
define: {
88+
'process.env.ANALYTICS_ID': JSON.stringify('UA-XXXXX'),
14389
},
144-
145-
// Extend module resolution with custom aliases.
14690
resolve: {
14791
alias: {
14892
'@components': './src/components',
14993
},
15094
},
95+
css: {
96+
lightningcss: {
97+
targets: {
98+
chrome: 100 << 16,
99+
},
100+
},
101+
},
151102
},
152103
},
153104
};
154105
```
155106

156-
[rolldown]: https://rolldown.rs/
107+
The generator owns the fields required to coordinate its builds: config-file
108+
loading, app type and base, virtual inputs, Preact aliases and automatic JSX
109+
runtime, CSS splitting, output/write mode, client manifests and chunk import
110+
maps, SSR format and temporary output, and SSR dependency bundling. Values
111+
supplied for those fields are replaced after configuration is merged. User
112+
plugins are registered after the generator's virtual-module plugin; other Vite
113+
options are preserved.
114+
115+
Function-valued plugins and hooks are supported because the `web` generator
116+
runs on the main thread and does not serialize this configuration to a worker.
157117

158118
### Default `imports`
159119

@@ -300,9 +260,9 @@ The HTML template file (set via `templatePath`) uses JavaScript template literal
300260
| ------------------ | -------- | ----------------------------------------------------------------- |
301261
| `title` | `string` | Fully resolved page title (e.g. `'File system \| Node.js v22.x'`) |
302262
| `dehydrated` | `string` | Server-rendered HTML for the page content |
303-
| `importMap` | `string` | JSON import map for client-side module resolution |
304-
| `entrypoint` | `string` | Client-side entry point filename with cache-bust query |
263+
| `entrypoint` | `string` | Virtual Vite module for this page's client hydration |
305264
| `speculationRules` | `string` | Speculation rules JSON for prefetching |
265+
| `themeScript` | `string` | Inline script that applies the saved theme before paint |
306266
| `root` | `string` | Relative or absolute path to the site root |
307267
| `metadata` | `object` | Full page metadata (frontmatter, path, heading, etc.) |
308268
| `config` | `object` | The resolved web generator configuration |
@@ -312,8 +272,9 @@ Since the template supports arbitrary JS expressions, you can use conditionals a
312272

313273
```html
314274
<title>${title}</title>
315-
<link rel="stylesheet" href="${root}styles.css" />
316-
<script type="importmap">
317-
${importMap}
318-
</script>
275+
<script type="module" src="${entrypoint}"></script>
319276
```
277+
278+
Vite processes each populated template as an HTML entry. It replaces the
279+
virtual `entrypoint` with the hashed client script and injects that page's
280+
stylesheets, module preloads, and chunk import map in their required order.

0 commit comments

Comments
 (0)