dochub 1.0.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +198 -52
- package/index.js +85 -31
- package/package.json +27 -10
- package/src/build.js +90 -0
- package/src/init.js +49 -219
- package/src/markdown.js +23 -0
- package/src/serve.js +134 -66
- package/src/template.js +390 -0
- package/src/utils.js +111 -0
- package/templates/README.md +69 -43
- package/templates/folder/README.md +27 -3
- package/templates/guide.md +75 -3
- package/templates/server.js +0 -271
package/README.md
CHANGED
|
@@ -1,52 +1,198 @@
|
|
|
1
|
-
# DocHub
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
1
|
+
# DocHub
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<a href="https://www.npmjs.com/package/dochub"><img src="https://img.shields.io/npm/v/dochub?style=flat&label=npm" alt="npm version"></a>
|
|
5
|
+
<a href="https://www.npmjs.com/package/dochub"><img src="https://img.shields.io/npm/dt/dochub?style=flat&label=downloads" alt="npm downloads"></a>
|
|
6
|
+
<a href="https://packagephobia.com/result?p=dochub"><img src="https://packagephobia.com/badge?p=dochub" alt="install size"></a>
|
|
7
|
+
<a href="https://github.com/tyler-Github/dochub/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat" alt="license"></a>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
Write Markdown. Ship beautiful documentation.
|
|
11
|
+
|
|
12
|
+
DocHub is a zero-config documentation tool that turns a folder of Markdown files into a modern, searchable, themeable documentation site. Use it as a live-reload dev server during writing, then export a fully self-contained static site for deployment.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
| | |
|
|
19
|
+
|---|---|
|
|
20
|
+
| **Live preview** | Dev server with instant reload on file changes |
|
|
21
|
+
| **Static export** | Build a portable HTML site with clean URLs (`/guide`, `/api/auth`) |
|
|
22
|
+
| **Full-text search** | Client-side search across all pages with relevance scoring |
|
|
23
|
+
| **Dark mode** | Light/dark toggle with persistent preference |
|
|
24
|
+
| **Syntax highlighting** | 190+ languages via Highlight.js |
|
|
25
|
+
| **File-tree sidebar** | Auto-generated navigation from your folder structure |
|
|
26
|
+
| **Responsive** | Works on desktop, tablet, and mobile |
|
|
27
|
+
| **Self-contained** | Zero external CDN dependencies in the output |
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install -g dochub
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Scaffold a new project
|
|
39
|
+
dochub init my-docs
|
|
40
|
+
|
|
41
|
+
# Start writing — open http://localhost:3000
|
|
42
|
+
cd my-docs && dochub serve
|
|
43
|
+
|
|
44
|
+
# Build for production
|
|
45
|
+
dochub build
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Project structure
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
my-docs/
|
|
52
|
+
├── markdown/ # Your content — add .md files here
|
|
53
|
+
│ ├── README.md # Home page (/)
|
|
54
|
+
│ ├── guide.md # /guide
|
|
55
|
+
│ ├── api/
|
|
56
|
+
│ │ ├── README.md # /api
|
|
57
|
+
│ │ └── authentication # /api/authentication
|
|
58
|
+
│ └── deployment/
|
|
59
|
+
│ └── README.md # /deployment
|
|
60
|
+
└── dochub.config.js # Site configuration
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Every folder becomes a collapsible sidebar section. `README.md` inside a folder becomes the folder's index page at a clean URL (`/api` not `/api/readme`).
|
|
64
|
+
|
|
65
|
+
## Commands
|
|
66
|
+
|
|
67
|
+
### `dochub init [directory]`
|
|
68
|
+
|
|
69
|
+
Scaffolds a new documentation project with a `markdown/` folder containing starter pages and a `dochub.config.js`.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
dochub init my-project # Creates ./my-project
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `dochub serve [directory]`
|
|
76
|
+
|
|
77
|
+
Starts a development server with WebSocket live reload. Changes to any `.md` file instantly refresh the browser.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
dochub serve # Serve current directory
|
|
81
|
+
dochub serve my-project # Serve a specific project
|
|
82
|
+
dochub serve -p 4000 # Custom port
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `dochub build [directory]`
|
|
86
|
+
|
|
87
|
+
Generates a static HTML site with clean URLs. Each page becomes a directory with `index.html` — deployable to any static host (Netlify, Vercel, GitHub Pages, S3, etc.).
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
dochub build # Build to ./dist
|
|
91
|
+
dochub build -o docs # Build to ./docs
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Configuration
|
|
95
|
+
|
|
96
|
+
Edit `dochub.config.js` in your project root:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
module.exports = {
|
|
100
|
+
title: 'My API Docs',
|
|
101
|
+
description: 'Everything you need to build with our API',
|
|
102
|
+
};
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The title appears in the browser tab, page header, and search metadata.
|
|
106
|
+
|
|
107
|
+
## Writing documentation
|
|
108
|
+
|
|
109
|
+
DocHub uses standard Markdown. All files go in `markdown/` and URLs are derived from the file path:
|
|
110
|
+
|
|
111
|
+
| File | URL |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `markdown/README.md` | `/` |
|
|
114
|
+
| `markdown/guide.md` | `/guide` |
|
|
115
|
+
| `markdown/api/README.md` | `/api` |
|
|
116
|
+
| `markdown/api/authentication.md` | `/api/authentication` |
|
|
117
|
+
|
|
118
|
+
### Supported syntax
|
|
119
|
+
|
|
120
|
+
- Headers (h1–h6), bold, italic, strikethrough, inline code
|
|
121
|
+
- Fenced code blocks with syntax highlighting
|
|
122
|
+
- Ordered and unordered lists (nested too)
|
|
123
|
+
- Links, images, blockquotes, horizontal rules
|
|
124
|
+
- Tables with header alignment
|
|
125
|
+
|
|
126
|
+
## Deployment
|
|
127
|
+
|
|
128
|
+
The `build` command outputs a static `dist/` folder:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
dist/
|
|
132
|
+
├── index.html
|
|
133
|
+
├── guide/
|
|
134
|
+
│ └── index.html
|
|
135
|
+
├── api/
|
|
136
|
+
│ └── index.html
|
|
137
|
+
├── folder/
|
|
138
|
+
│ └── index.html
|
|
139
|
+
└── 404.html
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Deploy the entire `dist/` folder to any static file host:
|
|
143
|
+
|
|
144
|
+
<details>
|
|
145
|
+
<summary><b>Netlify</b></summary>
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
dochub build
|
|
149
|
+
# Drag dist/ onto Netlify Drop, or
|
|
150
|
+
npx netlify-cli deploy --dir=dist --prod
|
|
151
|
+
```
|
|
152
|
+
</details>
|
|
153
|
+
|
|
154
|
+
<details>
|
|
155
|
+
<summary><b>Vercel</b></summary>
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
dochub build
|
|
159
|
+
npx vercel dist --prod
|
|
160
|
+
```
|
|
161
|
+
</details>
|
|
162
|
+
|
|
163
|
+
<details>
|
|
164
|
+
<summary><b>GitHub Pages</b></summary>
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
dochub build
|
|
168
|
+
# Push dist/ contents to gh-pages branch, or
|
|
169
|
+
# use actions/upload-pages-artifact
|
|
170
|
+
```
|
|
171
|
+
</details>
|
|
172
|
+
|
|
173
|
+
<details>
|
|
174
|
+
<summary><b>Any static server</b></summary>
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
dochub build
|
|
178
|
+
npx serve dist
|
|
179
|
+
```
|
|
180
|
+
</details>
|
|
181
|
+
|
|
182
|
+
## Why DocHub?
|
|
183
|
+
|
|
184
|
+
There are many documentation tools. Here's where DocHub fits:
|
|
185
|
+
|
|
186
|
+
| | DocHub | Docusaurus | VitePress |
|
|
187
|
+
|---|---|---|---|
|
|
188
|
+
| Setup time | seconds | minutes | minutes |
|
|
189
|
+
| Language | Markdown | MDX + React | Markdown + Vue |
|
|
190
|
+
| Build output | ~20KB pages | ~200KB+ JS bundle | ~100KB+ JS bundle |
|
|
191
|
+
| Dependencies | 5 packages | 200+ packages | 100+ packages |
|
|
192
|
+
| Config | 5-line JS file | Full Docusaurus config | Full VitePress config |
|
|
193
|
+
|
|
194
|
+
DocHub is for teams that want to write Markdown and ship docs without learning a framework or managing hundreds of dependencies.
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
MIT
|
package/index.js
CHANGED
|
@@ -1,32 +1,86 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const yargs = require('yargs');
|
|
4
|
-
const initProject = require('./src/init');
|
|
5
|
-
const serveDocs = require('./src/serve');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.command(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
.
|
|
2
|
+
|
|
3
|
+
const yargs = require('yargs');
|
|
4
|
+
const initProject = require('./src/init');
|
|
5
|
+
const serveDocs = require('./src/serve');
|
|
6
|
+
const buildSite = require('./src/build');
|
|
7
|
+
|
|
8
|
+
const color = process.stdout.isTTY ? {
|
|
9
|
+
bold: (s) => `\x1b[1m${s}\x1b[22m`,
|
|
10
|
+
dim: (s) => `\x1b[2m${s}\x1b[22m`,
|
|
11
|
+
cyan: (s) => `\x1b[36m${s}\x1b[39m`,
|
|
12
|
+
green: (s) => `\x1b[32m${s}\x1b[39m`,
|
|
13
|
+
red: (s) => `\x1b[31m${s}\x1b[39m`,
|
|
14
|
+
reset: (s) => `\x1b[0m${s}`,
|
|
15
|
+
} : { bold: (s) => s, dim: (s) => s, cyan: (s) => s, green: (s) => s, red: (s) => s, reset: (s) => s };
|
|
16
|
+
|
|
17
|
+
yargs
|
|
18
|
+
.scriptName('dochub')
|
|
19
|
+
.usage(`${color.bold('dochub')} <command> ${color.dim('[options]')}`)
|
|
20
|
+
.command({
|
|
21
|
+
command: 'init [directory]',
|
|
22
|
+
describe: `${color.green('Scaffold')} a new documentation project`,
|
|
23
|
+
builder: (yargs) => {
|
|
24
|
+
yargs.positional('directory', {
|
|
25
|
+
describe: 'Project directory name',
|
|
26
|
+
type: 'string',
|
|
27
|
+
default: 'my-docs'
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
handler: initProject,
|
|
31
|
+
})
|
|
32
|
+
.command({
|
|
33
|
+
command: 'serve [directory]',
|
|
34
|
+
describe: `${color.cyan('Start')} dev server with live reload`,
|
|
35
|
+
builder: (yargs) => {
|
|
36
|
+
yargs.positional('directory', {
|
|
37
|
+
describe: 'Project directory',
|
|
38
|
+
type: 'string',
|
|
39
|
+
default: '.'
|
|
40
|
+
}).option('port', {
|
|
41
|
+
alias: 'p',
|
|
42
|
+
describe: 'Port to listen on',
|
|
43
|
+
type: 'number',
|
|
44
|
+
default: 3000
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
handler: serveDocs,
|
|
48
|
+
})
|
|
49
|
+
.command({
|
|
50
|
+
command: 'build [directory]',
|
|
51
|
+
describe: `${color.green('Build')} static HTML site`,
|
|
52
|
+
builder: (yargs) => {
|
|
53
|
+
yargs.positional('directory', {
|
|
54
|
+
describe: 'Project directory',
|
|
55
|
+
type: 'string',
|
|
56
|
+
default: '.'
|
|
57
|
+
}).option('out', {
|
|
58
|
+
alias: 'o',
|
|
59
|
+
describe: 'Output directory',
|
|
60
|
+
type: 'string',
|
|
61
|
+
default: 'dist'
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
handler: buildSite,
|
|
65
|
+
})
|
|
66
|
+
.demandCommand(1, '')
|
|
67
|
+
.example('dochub init my-docs', ' Scaffold a new project')
|
|
68
|
+
.example('dochub serve', ' Start dev server in current dir')
|
|
69
|
+
.example('dochub serve --port 8080', ' Start on a custom port')
|
|
70
|
+
.example('dochub build', ' Build static site to ./dist')
|
|
71
|
+
.example('dochub build -o docs', ' Build to a custom output dir')
|
|
72
|
+
.epilogue([
|
|
73
|
+
'',
|
|
74
|
+
` ${color.dim('Learn more:')} ${color.cyan('https://github.com/tyler-Github/dochub')}`,
|
|
75
|
+
''
|
|
76
|
+
].join('\n'))
|
|
77
|
+
.strict()
|
|
78
|
+
.wrap(90)
|
|
79
|
+
.fail((msg, err) => {
|
|
80
|
+
if (err) throw err;
|
|
81
|
+
if (msg) console.error(`\n ${color.red('!')} ${msg}\n`);
|
|
82
|
+
yargs.showHelp();
|
|
83
|
+
process.exit(1);
|
|
84
|
+
})
|
|
85
|
+
.help()
|
|
86
|
+
.argv;
|
package/package.json
CHANGED
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dochub",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "A modern documentation generator with live-reload dev server and static site builder",
|
|
4
5
|
"main": "index.js",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
-
},
|
|
8
6
|
"bin": {
|
|
9
7
|
"dochub": "./index.js"
|
|
10
8
|
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node index.js --help"
|
|
11
|
+
},
|
|
11
12
|
"author": "Tyler Reece",
|
|
12
|
-
"license": "
|
|
13
|
-
"description": "DocHub is a documentation generation CLI tool.",
|
|
13
|
+
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
15
|
+
"chokidar": "^5.0.0",
|
|
16
|
+
"highlight.js": "^11.11.1",
|
|
17
|
+
"marked": "^18.0.5",
|
|
18
|
+
"ws": "^8.21.0",
|
|
18
19
|
"yargs": "^17.7.2"
|
|
19
|
-
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"index.js",
|
|
23
|
+
"src/",
|
|
24
|
+
"templates/"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"documentation",
|
|
31
|
+
"docs",
|
|
32
|
+
"markdown",
|
|
33
|
+
"static-site-generator",
|
|
34
|
+
"documentation-generator",
|
|
35
|
+
"live-reload"
|
|
36
|
+
]
|
|
20
37
|
}
|
package/src/build.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { renderMarkdown } = require('./markdown');
|
|
4
|
+
const { generatePageHtml } = require('./template');
|
|
5
|
+
const { loadConfig, walkMarkdownFiles, getSearchData, generateSidebarHtml, extractTitle } = require('./utils');
|
|
6
|
+
|
|
7
|
+
function buildSite(argv) {
|
|
8
|
+
const directory = path.resolve(argv.directory || '.');
|
|
9
|
+
const outDir = path.resolve(argv.out || 'dist');
|
|
10
|
+
const markdownDir = path.join(directory, 'markdown');
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(markdownDir)) {
|
|
13
|
+
console.error(`No 'markdown' directory found in ${directory}.`);
|
|
14
|
+
console.error('Run `dochub init` first to scaffold a project.');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const config = loadConfig(directory);
|
|
19
|
+
|
|
20
|
+
if (fs.existsSync(outDir)) {
|
|
21
|
+
fs.rmSync(outDir, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const files = walkMarkdownFiles(markdownDir, markdownDir);
|
|
25
|
+
const allSearchData = getSearchData(directory);
|
|
26
|
+
|
|
27
|
+
let count = 0;
|
|
28
|
+
for (const file of files) {
|
|
29
|
+
const content = fs.readFileSync(file.path, 'utf8');
|
|
30
|
+
const contentHtml = renderMarkdown(content);
|
|
31
|
+
const searchData = allSearchData.map(s => ({
|
|
32
|
+
path: s.path,
|
|
33
|
+
title: s.title,
|
|
34
|
+
excerpt: s.excerpt,
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
const sidebarHtml = generateSidebarHtml(directory, file.url);
|
|
38
|
+
|
|
39
|
+
const html = generatePageHtml({
|
|
40
|
+
config,
|
|
41
|
+
sidebarHtml,
|
|
42
|
+
contentHtml,
|
|
43
|
+
searchData,
|
|
44
|
+
currentPath: file.url,
|
|
45
|
+
isDev: false,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
let outputPath;
|
|
49
|
+
if (file.url === '/' || file.url === '') {
|
|
50
|
+
outputPath = path.join(outDir, 'index.html');
|
|
51
|
+
} else {
|
|
52
|
+
outputPath = path.join(outDir, file.url.slice(1), 'index.html');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
56
|
+
fs.writeFileSync(outputPath, html, 'utf8');
|
|
57
|
+
count++;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const homeMarkdown = path.join(markdownDir, 'README.md');
|
|
61
|
+
if (!fs.existsSync(homeMarkdown)) {
|
|
62
|
+
const allSearchData = getSearchData(directory);
|
|
63
|
+
const sidebarHtml = generateSidebarHtml(directory, '/');
|
|
64
|
+
const html = generatePageHtml({
|
|
65
|
+
config,
|
|
66
|
+
sidebarHtml,
|
|
67
|
+
contentHtml: '<h1>Welcome</h1><p>Select a page from the sidebar.</p>',
|
|
68
|
+
searchData: allSearchData,
|
|
69
|
+
currentPath: '/',
|
|
70
|
+
isDev: false,
|
|
71
|
+
});
|
|
72
|
+
const indexPath = path.join(outDir, 'index.html');
|
|
73
|
+
fs.mkdirSync(path.dirname(indexPath), { recursive: true });
|
|
74
|
+
fs.writeFileSync(indexPath, html, 'utf8');
|
|
75
|
+
count++;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const notFoundHtml = `<!DOCTYPE html>
|
|
79
|
+
<html lang="en">
|
|
80
|
+
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>404 - ${config.title}</title>
|
|
81
|
+
<style>body{font-family:-apple-system,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#0b1120;color:#f1f5f9;text-align:center}.wrap{max-width:480px}h1{font-size:4rem;margin:0;color:#60a5fa}p{color:#94a3b8;margin:1rem 0 2rem}a{color:#60a5fa;text-decoration:none;border:1px solid #60a5fa;padding:.5rem 1.5rem;border-radius:8px}a:hover{background:#60a5fa;color:#0b1120}</style></head>
|
|
82
|
+
<body><div class="wrap"><h1>404</h1><p>The page you're looking for doesn't exist.</p><a href="/">Go Home</a></div></body></html>`;
|
|
83
|
+
fs.writeFileSync(path.join(outDir, '404.html'), notFoundHtml, 'utf8');
|
|
84
|
+
|
|
85
|
+
console.log(`\n \x1b[1mDocHub\x1b[0m build complete`);
|
|
86
|
+
console.log(` \x1b[36m>\x1b[0m Pages: ${count}`);
|
|
87
|
+
console.log(` \x1b[36m>\x1b[0m Output: \x1b[1m${outDir}\x1b[0m\n`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = buildSite;
|