Skip to content

Commit 254802d

Browse files
authored
feat(build): generate llms.txt via doc-kit (#201)
* feat(build): generate llms.txt via doc-kit - add the llms-txt target with a webpack-specific template - link entries to raw markdown pages and copy the .md sources into out/ - drop empty entries produced by JSX-driven pages (home, blog index) * Apply suggestion from @bjohansebas
1 parent 896d24e commit 254802d

3 files changed

Lines changed: 39 additions & 1 deletion

File tree

‎scripts/html/doc-kit.config.mjs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ export default {
4343
generateIndexPage: false,
4444
generateAllPage: false,
4545
},
46+
'llms-txt': {
47+
templatePath: join(ROOT, 'scripts/html/llms-template.txt'),
48+
pageURL: `${BASE_URL.replace(/\/$/, '')}{path}.md`,
49+
output: VERSION ? `./out/docs/api/${MAJOR_VERSION}` : './out',
50+
},
4651
web: {
4752
project: 'webpack',
4853
useAbsoluteURLs: true,

‎scripts/html/index.mjs‎

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import { execFile } from 'node:child_process';
2-
import { readFile } from 'node:fs/promises';
2+
import { cp, readFile, writeFile } from 'node:fs/promises';
3+
import { statSync } from 'node:fs';
34
import { promisify } from 'node:util';
45

56
const execFileAsync = promisify(execFile);
67

8+
// TODO: Have doc-kit understand that some pages don't have meaningful information
9+
// The llms-txt generator lists every page with a depth-1 heading. JSX-driven
10+
// pages like the homepage produce entries with no title or description — drop
11+
// them, they carry no information for LLMs.
12+
const cleanLlmsTxt = async path => {
13+
const content = await readFile(path, 'utf8');
14+
const cleaned = content
15+
.split('\n')
16+
.filter(line => !line.startsWith('- []('))
17+
.join('\n');
18+
await writeFile(path, cleaned);
19+
};
20+
721
const runDocKit = version =>
822
execFileAsync(
923
'npx',
@@ -16,6 +30,8 @@ const runDocKit = version =>
1630
'web',
1731
'-t',
1832
'orama-db',
33+
'-t',
34+
'llms-txt',
1935
'--config-file',
2036
'./scripts/html/doc-kit.config.mjs',
2137
],
@@ -35,5 +51,14 @@ const versions = JSON.parse(await readFile('./versions.json'));
3551

3652
for (const version of versions) {
3753
await runDocKit(version);
54+
await cleanLlmsTxt(`./out/docs/api/v${version.match(/\d+/)[0]}.x/llms.txt`);
3855
}
3956
await runDocKit();
57+
await cleanLlmsTxt('./out/llms.txt');
58+
59+
// Publish the markdown sources next to the rendered pages so the llms.txt
60+
// links (`{path}.md`) resolve to LLM-friendly raw markdown.
61+
await cp('./pages', './out', {
62+
recursive: true,
63+
filter: source => statSync(source).isDirectory() || source.endsWith('.md'),
64+
});

‎scripts/html/llms-template.txt‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# webpack Documentation
2+
3+
> webpack is a static module bundler for modern JavaScript applications. It builds a dependency graph from one or more entry points and combines every module your project needs into one or more bundles, and it can transform, bundle, or package just about any resource or asset.
4+
5+
Below are the sections of the webpack documentation. Look out especially towards the links that point towards guidance/introduction to the structure of this documentation.
6+
7+
## Documentation
8+

0 commit comments

Comments
 (0)