Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 0 additions & 77 deletions .github/workflows/sync.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules
out
*.generated.*
/webpack
/pages
/.cache
/pages/api
5 changes: 2 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
node_modules
out
*.generated.*
/webpack
pages
.husky
/.cache
/pages/api
versions.json
1 change: 0 additions & 1 deletion HEAD_COMMIT

This file was deleted.

53 changes: 31 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,55 @@ Automated TypeScript API documentation generator for [webpack](https://github.co
3. **@node-core/doc-kit** converts Markdown to HTML
4. GitHub Actions deploys the result to GitHub Pages

### Webpack Version Tracking
### Webpack Versions

The `HEAD_COMMIT` file pins the exact webpack/webpack commit used for doc generation. A scheduled GitHub Action runs every 24 hours to:
Generation expects a `versions.json` file at the project root with the webpack release tags to generate, for example:

1. Fetch the latest webpack `main` branch HEAD
2. Update `HEAD_COMMIT`
3. Regenerate documentation
4. Push the changes to this repository
```json
["v5.1.0"]
```

This ensures documentation stays in sync with upstream webpack without manual intervention.
Each tag is fetched from the webpack npm package and generated into `pages/api/v[Major].x`. Creating or updating `versions.json` is handled outside this project.

## Project Structure

```
├── generate-md.mjs # TypeDoc entry point
├── scripts/
│ ├── prepare/ # Fetches every webpack release listed in versions.json
│ ├── markdown/ # TypeDoc → Markdown for a single webpack source path
│ ├── html/ # doc-kit HTML generation
│ └── vercel/ # Vercel install/build entry points
├── plugins/
│ ├── processor.mjs # Namespace merging + type-map generation
│ ├── processor/ # Namespace merging + type-map generation
│ └── theme/ # Custom doc-kit theme
├── HEAD_COMMIT # Pinned webpack commit SHA
├── versions.json # Webpack release tags to generate
├── .github/workflows/
│ ├── ci.yml # Lint + doc generation check
│ ├── deploy.yml # Build HTML + deploy to GitHub Pages
│ └── sync.yml # Daily webpack sync
│ └── ci.yml # Lint + format check
└── package.json
```

The pipeline is split into three stages: `prepare` fetches each webpack tag into `.cache/webpack/<version>/`, `markdown` is invoked once per source directory to emit Markdown under `pages/api/v<major>.x`, and `html` runs doc-kit over the result.

## Scripts

| Script | Description |
| ----------------------- | ------------------------------------ |
| `npm run clone-webpack` | Clone webpack repo at pinned commit |
| `npm run generate-docs` | Generate Markdown from webpack types |
| `npm run build-html` | Convert Markdown to HTML |
| `npm run build` | Generate docs + build HTML |
| `npm run lint` | Run ESLint |
| `npm run format:check` | Check Prettier formatting |
| Script | Description |
| ---------------------- | ----------------------------------------------------------------- |
| `npm run prep` | Fetch every webpack tag in `versions.json` into `.cache/webpack/` |
| `npm run build:md` | Generate Markdown for every prepared webpack source |
| `npm run build:html` | Convert Markdown to HTML |
| `npm run build` | Full pipeline: prepare → Markdown → HTML |
| `npm run lint` | Run ESLint |
| `npm run format:check` | Check Prettier formatting |

To generate Markdown for a single webpack source, invoke the processor directly:

```sh
node scripts/markdown/index.mjs .cache/webpack/v5.107.1
```

## Contributing

When making changes to documentation generation (plugins, `generate-md.mjs`, `tsconfig.json`), ensure the docs can still be generated successfully. CI will verify this on every pull request.
When making changes to documentation generation (plugins, `scripts/markdown/index.mjs`, `tsconfig.json`), ensure the docs can still be generated successfully. CI will verify this on every pull request.

## License

Expand Down
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export default [
},
},
{
ignores: ['node_modules/', 'out/', 'webpack/'],
ignores: ['node_modules/', 'out/', '.cache/', 'webpack/', 'pages/api'],
},
];
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"scripts": {
"clone-webpack": "bash scripts/clone.sh",
"generate-docs": "node scripts/markdown.mjs",
"build-html": "doc-kit generate -t web --config-file ./doc-kit.config.mjs",
"build": "npm run generate-docs && npm run build-html",
"prep": "node scripts/prepare/index.mjs",
"build:md": "node scripts/markdown/index.mjs",
"build:html": "node scripts/html/index.mjs",
"build": "npm run prep && npm run build:md && npm run build:html",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"format": "prettier --write .",
Expand All @@ -12,7 +12,6 @@
},
"dependencies": {
"@node-core/doc-kit": "^1.3.6",
"semver": "^7.8.1",
"typedoc": "^0.28.19",
"typedoc-plugin-markdown": "^4.11.0",
"webpack": "^5.107.1"
Expand Down
3 changes: 3 additions & 0 deletions pages/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
layout: home
---
3 changes: 3 additions & 0 deletions pages/site.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"sidebar": []
}
5 changes: 2 additions & 3 deletions plugins/processor/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import { createTypeMap } from './typeMap.mjs';
* @param {import('typedoc-plugin-markdown').MarkdownApplication} app
*/
export function load(app) {
// Keep router ownership in the processor plugin because routing depends on
// source metadata and the synthetic type pages created during conversion.
app.renderer.defineRouter('doc-kit', DocKitRouter);
app.options.addDeclaration({ name: 'base' });

app.converter.on(Converter.EVENT_RESOLVE_BEGIN, context => {
// doc-kit has property metadata, not TypeDoc accessor metadata.
Expand Down Expand Up @@ -54,7 +53,7 @@ export function load(app) {
join(app.options.getValue('out'), 'site.json'),
JSON.stringify(
{
sidebar: sidebar(app.renderer.router),
sidebar: sidebar(app.renderer.router, app.options.getValue('base')),
},
null,
2
Expand Down
9 changes: 5 additions & 4 deletions plugins/processor/site.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ const getFirstAtxHeading = text => text.match(/^#\s+(.+)$/m)?.[1]?.trim();

const getFirstPathSegment = url => url.replace(/^\//, '').split('/')[0];

const toSidebarLink = url => {
const toSidebarLink = (url, basePath) => {
const path = url.replace(/\.md$/, '').replace(/\/index$/, '');
return path ? `/${path}` : '/';
const prefix = basePath ? `/${basePath.replace(/^\/|\/$/g, '')}` : '';
return path ? `${prefix}/${path}` : prefix || '/';
};

const defaultLabelFor = (target, url) => {
Expand All @@ -29,7 +30,7 @@ const isSidebarTarget = (router, target) => {
return url.endsWith('.md') && !url.includes('#');
};

export const sidebar = router => {
export const sidebar = (router, basePath) => {
const categories = new Map();
const seen = new Set();

Expand Down Expand Up @@ -58,7 +59,7 @@ export const sidebar = router => {
};

group.items.push({
link: toSidebarLink(url),
link: toSidebarLink(url, basePath),
label,
});

Expand Down
6 changes: 0 additions & 6 deletions scripts/build.sh

This file was deleted.

10 changes: 0 additions & 10 deletions scripts/clone.sh

This file was deleted.

26 changes: 13 additions & 13 deletions doc-kit.config.mjs → scripts/html/doc-kit.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { major } from 'semver';
import webpack from './webpack/package.json' with { type: 'json' };

const ROOT = dirname(fileURLToPath(import.meta.url));
const DOCS_DIR = `pages/v${major(webpack.version)}.x`;
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..');

const VERSION = process.env.VERSION;
const inputDir = join(
ROOT,
VERSION ? `./pages/api/${VERSION.split('.')[0]}.x` : './pages'
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self review why didn't I use semver? I should fix this

);

/**
* Configuration for @node-core/doc-kit when generating webpack API docs.
Expand All @@ -13,21 +16,18 @@ const DOCS_DIR = `pages/v${major(webpack.version)}.x`;
*/
export default {
global: {
// Point GitHub links to the webpack repository instead of nodejs/node
repository: 'webpack/webpack',

// Input & Output
input: [`./${DOCS_DIR}/**/*.md`],
output: 'out',

// Base URL,
version: VERSION,
input: [`${inputDir}/**/*.md`],
ignore: VERSION ? [] : ['./pages/api/**/*.md'],
output: VERSION ? `./out/api/${VERSION.split('.')[0]}.x` : './out',
baseURL: process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: 'http://localhost:3000',
},
threads: 1,
metadata: {
typeMap: `./${DOCS_DIR}/type-map.json`,
typeMap: VERSION ? join(inputDir, 'type-map.json') : undefined,
},
'jsx-ast': {
generateIndexPage: false,
Expand All @@ -39,7 +39,7 @@ export default {
remoteConfigUrl: null,
imports: {
'#theme/Sidebar': join(ROOT, 'components/SideBar.jsx'),
'#theme/site': join(ROOT, DOCS_DIR, 'site.json'),
'#theme/site': join(inputDir, 'site.json'),
'#theme/Layout': join(ROOT, 'components/Layout.jsx'),
},
},
Expand Down
36 changes: 36 additions & 0 deletions scripts/html/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { execFile } from 'node:child_process';
import { readFile } from 'node:fs/promises';
import { promisify } from 'node:util';

const execFileAsync = promisify(execFile);

const runDocKit = version =>
execFileAsync(
'npx',
[
'-p',
'@node-core/doc-kit',
'doc-kit',
'generate',
'-t',
'web',
'--config-file',
'./scripts/html/doc-kit.config.mjs',
],
{
env: {
...process.env,
VERSION: version,
},
}
);

// For each version in versions.json, run doc-kit to generate the API docs
// Plus, once more without a version to generate the latest API docs

const versions = JSON.parse(await readFile('./versions.json'));

for (const version of versions) {
await runDocKit(version);
}
await runDocKit();
Loading