methanol 0.0.1 → 0.0.3
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 +58 -0
- package/package.json +10 -1
- package/src/config.js +63 -18
- package/src/dev-server.js +80 -7
- package/src/main.js +51 -1
- package/src/mdx.js +176 -24
- package/src/pagefind.js +10 -2
- package/src/pages.js +149 -10
- package/src/register-loader.js +2 -7
- package/src/rehype-plugins/link-resolve.js +35 -8
- package/src/state.js +27 -3
- package/src/vite-plugins.js +2 -2
- package/themes/default/components/ThemeAccentSwitch.client.jsx +95 -0
- package/themes/default/components/ThemeAccentSwitch.static.jsx +23 -0
- package/themes/default/components/ThemeColorSwitch.client.jsx +1 -1
- package/themes/default/components/ThemeSearchBox.client.jsx +71 -34
- package/themes/default/components/ThemeSearchBox.static.jsx +0 -1
- package/themes/default/components/pre.client.jsx +1 -1
- package/themes/default/components/{pre.jsx → pre.static.jsx} +1 -1
- package/themes/default/index.js +4 -13
- package/themes/default/page.jsx +61 -7
- package/themes/default/pages/index.mdx +24 -2
- package/themes/default/public/favicon.png +0 -0
- package/themes/default/sources/prefetch.js +49 -0
- package/themes/default/{resources → sources}/style.css +600 -29
- package/.editorconfig +0 -19
- package/.prettierrc +0 -10
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Methanol
|
|
2
|
+
|
|
3
|
+
Opinionated MDX-first static site generator powered by rEFui + Vite.
|
|
4
|
+
|
|
5
|
+
For full documentation and examples, see the `methanol-docs` project.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# build
|
|
11
|
+
npx methanol build
|
|
12
|
+
|
|
13
|
+
# dev server
|
|
14
|
+
npx methanol dev
|
|
15
|
+
|
|
16
|
+
# preview the production build
|
|
17
|
+
npx methanol serve
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
From this repo, use `node bin/methanol.js [dev|build|serve]`.
|
|
21
|
+
|
|
22
|
+
## Project layout
|
|
23
|
+
|
|
24
|
+
Methanol expects a project like this:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
pages/ # .mdx pages (file-based routing)
|
|
28
|
+
components/ # JSX/TSX components used by MDX
|
|
29
|
+
public/ # static assets copied/served as-is
|
|
30
|
+
dist/ # build output
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
Create `methanol.config.{js,mjs,cjs,ts,jsx,tsx,mts,cts}` and export a function:
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
export default () => ({
|
|
39
|
+
// optional: search (Pagefind)
|
|
40
|
+
pagefind: {
|
|
41
|
+
enabled: true
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
// optional: code highlighting (Starry Night)
|
|
45
|
+
starryNight: false,
|
|
46
|
+
|
|
47
|
+
// optional: theme sources
|
|
48
|
+
theme: {
|
|
49
|
+
sources: {
|
|
50
|
+
'/.my-theme': './sources'
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## CLI notes
|
|
57
|
+
|
|
58
|
+
- `methanol preview` is an alias for `methanol serve`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "methanol",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Static site generator powered by rEFui and MDX",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -16,6 +16,15 @@
|
|
|
16
16
|
"bin": {
|
|
17
17
|
"methanol": "./bin/methanol.js"
|
|
18
18
|
},
|
|
19
|
+
"files": [
|
|
20
|
+
"bin/",
|
|
21
|
+
"src/",
|
|
22
|
+
"themes/",
|
|
23
|
+
"index.js",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"README.md",
|
|
26
|
+
"banner.txt"
|
|
27
|
+
],
|
|
19
28
|
"dependencies": {
|
|
20
29
|
"@mdx-js/mdx": "^3.1.1",
|
|
21
30
|
"@sindresorhus/fnv1a": "^3.1.0",
|
package/src/config.js
CHANGED
|
@@ -34,8 +34,10 @@ const CONFIG_FILENAMES = [
|
|
|
34
34
|
'methanol.config.mjs',
|
|
35
35
|
'methanol.config.cjs',
|
|
36
36
|
'methanol.config.ts',
|
|
37
|
+
'methanol.config.jsx',
|
|
37
38
|
'methanol.config.mts',
|
|
38
|
-
'methanol.config.cts'
|
|
39
|
+
'methanol.config.cts',
|
|
40
|
+
'methanol.config.tsx'
|
|
39
41
|
]
|
|
40
42
|
|
|
41
43
|
const resolveRootPath = (value) => {
|
|
@@ -78,7 +80,7 @@ const resolveThemePublicDir = (root, value) => {
|
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj || {}, key)
|
|
81
|
-
const
|
|
83
|
+
const normalizeSources = (value, root) => {
|
|
82
84
|
if (!value) return []
|
|
83
85
|
const entries = []
|
|
84
86
|
const addEntry = (find, replacement) => {
|
|
@@ -120,7 +122,7 @@ const resolvePagefindEnabled = (config) => {
|
|
|
120
122
|
const resolvePagefindOptions = (config) => {
|
|
121
123
|
const value = config?.pagefind
|
|
122
124
|
if (!value || typeof value !== 'object') return null
|
|
123
|
-
const { enabled, options, ...rest } = value
|
|
125
|
+
const { enabled, options, build, buildOptions, ...rest } = value
|
|
124
126
|
if (options && typeof options === 'object') {
|
|
125
127
|
return { ...options }
|
|
126
128
|
}
|
|
@@ -130,16 +132,42 @@ const resolvePagefindOptions = (config) => {
|
|
|
130
132
|
return null
|
|
131
133
|
}
|
|
132
134
|
|
|
133
|
-
const
|
|
135
|
+
const resolvePagefindBuild = (config) => {
|
|
134
136
|
const value = config?.pagefind
|
|
135
137
|
if (!value || typeof value !== 'object') return null
|
|
136
|
-
const
|
|
137
|
-
if (
|
|
138
|
-
return { ...
|
|
138
|
+
const build = value.build
|
|
139
|
+
if (build && typeof build === 'object') {
|
|
140
|
+
return { ...build }
|
|
139
141
|
}
|
|
140
142
|
return null
|
|
141
143
|
}
|
|
142
144
|
|
|
145
|
+
const resolveStarryNightConfig = (value) => {
|
|
146
|
+
if (value == null) return { enabled: false, options: null }
|
|
147
|
+
if (typeof value === 'boolean') {
|
|
148
|
+
return { enabled: value, options: null }
|
|
149
|
+
}
|
|
150
|
+
if (typeof value !== 'object') {
|
|
151
|
+
return { enabled: false, options: null }
|
|
152
|
+
}
|
|
153
|
+
const { enabled, options, ...rest } = value
|
|
154
|
+
if (enabled === false) return { enabled: false, options: null }
|
|
155
|
+
if (options && typeof options === 'object') {
|
|
156
|
+
return { enabled: true, options: { ...options } }
|
|
157
|
+
}
|
|
158
|
+
if (Object.keys(rest).length) {
|
|
159
|
+
return { enabled: true, options: { ...rest } }
|
|
160
|
+
}
|
|
161
|
+
return { enabled: true, options: null }
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const normalizeHooks = (value) => {
|
|
165
|
+
if (!value) return []
|
|
166
|
+
if (typeof value === 'function') return [value]
|
|
167
|
+
if (Array.isArray(value)) return value.filter((entry) => typeof entry === 'function')
|
|
168
|
+
return []
|
|
169
|
+
}
|
|
170
|
+
|
|
143
171
|
const loadConfigModule = async (filePath) => {
|
|
144
172
|
return import(`${pathToFileURL(filePath).href}?t=${Date.now()}`)
|
|
145
173
|
}
|
|
@@ -191,12 +219,12 @@ export const applyConfig = async (config, mode) => {
|
|
|
191
219
|
if (mode) {
|
|
192
220
|
state.CURRENT_MODE = mode
|
|
193
221
|
}
|
|
194
|
-
|
|
222
|
+
// config.paths / config.dirs are intentionally ignored (deprecated)
|
|
195
223
|
|
|
196
|
-
const pagesDirValue = cli.CLI_PAGES_DIR || config.pagesDir
|
|
197
|
-
const componentsDirValue = cli.CLI_COMPONENTS_DIR || config.componentsDir
|
|
198
|
-
const distDirValue = cli.CLI_OUTPUT_DIR || config.distDir
|
|
199
|
-
const publicDirValue = cli.CLI_ASSETS_DIR ?? config.publicDir
|
|
224
|
+
const pagesDirValue = cli.CLI_PAGES_DIR || config.pagesDir
|
|
225
|
+
const componentsDirValue = cli.CLI_COMPONENTS_DIR || config.componentsDir
|
|
226
|
+
const distDirValue = cli.CLI_OUTPUT_DIR || config.distDir
|
|
227
|
+
const publicDirValue = cli.CLI_ASSETS_DIR ?? config.publicDir
|
|
200
228
|
|
|
201
229
|
const resolvePagesFallback = () => {
|
|
202
230
|
const pagesPath = resolveFromRoot(root, 'pages', 'pages')
|
|
@@ -210,18 +238,18 @@ export const applyConfig = async (config, mode) => {
|
|
|
210
238
|
: resolvePagesFallback()
|
|
211
239
|
state.COMPONENTS_DIR = resolveFromRoot(root, componentsDirValue, 'components')
|
|
212
240
|
state.STATIC_DIR = resolveOptionalPath(root, publicDirValue, 'public')
|
|
213
|
-
state.BUILD_DIR = resolveFromRoot(root, config.buildDir
|
|
241
|
+
state.BUILD_DIR = resolveFromRoot(root, config.buildDir, 'build')
|
|
214
242
|
state.DIST_DIR = resolveFromRoot(root, distDirValue, 'dist')
|
|
215
243
|
|
|
216
|
-
const userSpecifiedPagesDir = cli.CLI_PAGES_DIR != null || hasOwn(config, 'pagesDir')
|
|
244
|
+
const userSpecifiedPagesDir = cli.CLI_PAGES_DIR != null || hasOwn(config, 'pagesDir')
|
|
217
245
|
if (userSpecifiedPagesDir && !existsSync(state.PAGES_DIR)) {
|
|
218
246
|
throw new Error(`Pages directory not found: ${state.PAGES_DIR}`)
|
|
219
247
|
}
|
|
220
|
-
const userSpecifiedComponentsDir = cli.CLI_COMPONENTS_DIR != null || hasOwn(config, 'componentsDir')
|
|
248
|
+
const userSpecifiedComponentsDir = cli.CLI_COMPONENTS_DIR != null || hasOwn(config, 'componentsDir')
|
|
221
249
|
if (userSpecifiedComponentsDir && !existsSync(state.COMPONENTS_DIR)) {
|
|
222
250
|
throw new Error(`Components directory not found: ${state.COMPONENTS_DIR}`)
|
|
223
251
|
}
|
|
224
|
-
const userSpecifiedPublicDir = cli.CLI_ASSETS_DIR != null || hasOwn(config, 'publicDir')
|
|
252
|
+
const userSpecifiedPublicDir = cli.CLI_ASSETS_DIR != null || hasOwn(config, 'publicDir')
|
|
225
253
|
if (userSpecifiedPublicDir && state.STATIC_DIR !== false && !existsSync(state.STATIC_DIR)) {
|
|
226
254
|
state.STATIC_DIR = resolveFromRoot(root, publicDirValue, 'public')
|
|
227
255
|
}
|
|
@@ -270,14 +298,31 @@ export const applyConfig = async (config, mode) => {
|
|
|
270
298
|
) {
|
|
271
299
|
state.STATIC_DIR = state.THEME_PUBLIC_DIR
|
|
272
300
|
}
|
|
273
|
-
state.
|
|
301
|
+
state.SOURCES = normalizeSources(state.USER_THEME.sources, themeRoot)
|
|
274
302
|
state.USER_VITE_CONFIG = config.vite || null
|
|
275
303
|
state.USER_MDX_CONFIG = config.mdx || null
|
|
276
304
|
state.RESOLVED_MDX_CONFIG = undefined
|
|
277
305
|
state.RESOLVED_VITE_CONFIG = undefined
|
|
278
306
|
state.PAGEFIND_ENABLED = resolvePagefindEnabled(config)
|
|
279
307
|
state.PAGEFIND_OPTIONS = resolvePagefindOptions(config)
|
|
280
|
-
state.
|
|
308
|
+
state.PAGEFIND_BUILD = resolvePagefindBuild(config)
|
|
309
|
+
state.USER_PRE_BUILD_HOOKS = normalizeHooks(config.preBuild)
|
|
310
|
+
state.USER_POST_BUILD_HOOKS = normalizeHooks(config.postBuild)
|
|
311
|
+
state.USER_PRE_BUNDLE_HOOKS = normalizeHooks(config.preBundle)
|
|
312
|
+
state.USER_POST_BUNDLE_HOOKS = normalizeHooks(config.postBundle)
|
|
313
|
+
state.THEME_PRE_BUILD_HOOKS = normalizeHooks(state.USER_THEME?.preBuild)
|
|
314
|
+
state.THEME_POST_BUILD_HOOKS = normalizeHooks(state.USER_THEME?.postBuild)
|
|
315
|
+
state.THEME_PRE_BUNDLE_HOOKS = normalizeHooks(state.USER_THEME?.preBundle)
|
|
316
|
+
state.THEME_POST_BUNDLE_HOOKS = normalizeHooks(state.USER_THEME?.postBundle)
|
|
317
|
+
const starryNight = resolveStarryNightConfig(config.starryNight)
|
|
318
|
+
const cliCodeHighlighting = cli.CLI_CODE_HIGHLIGHTING
|
|
319
|
+
if (cliCodeHighlighting != null) {
|
|
320
|
+
state.STARRY_NIGHT_ENABLED = cliCodeHighlighting === true
|
|
321
|
+
state.STARRY_NIGHT_OPTIONS = cliCodeHighlighting === true ? starryNight.options : null
|
|
322
|
+
} else {
|
|
323
|
+
state.STARRY_NIGHT_ENABLED = starryNight.enabled
|
|
324
|
+
state.STARRY_NIGHT_OPTIONS = starryNight.enabled ? starryNight.options : null
|
|
325
|
+
}
|
|
281
326
|
|
|
282
327
|
if (cli.CLI_INTERMEDIATE_DIR) {
|
|
283
328
|
state.INTERMEDIATE_DIR = resolveFromRoot(root, cli.CLI_INTERMEDIATE_DIR, 'build')
|
package/src/dev-server.js
CHANGED
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import { existsSync } from 'fs'
|
|
22
|
-
import {
|
|
22
|
+
import { readFile } from 'fs/promises'
|
|
23
|
+
import { resolve, dirname, extname, join, basename, relative } from 'path'
|
|
23
24
|
import { fileURLToPath } from 'url'
|
|
24
25
|
import chokidar from 'chokidar'
|
|
25
26
|
import { createServer, mergeConfig } from 'vite'
|
|
@@ -151,6 +152,48 @@ export const runViteDev = async () => {
|
|
|
151
152
|
return mdxPath
|
|
152
153
|
}
|
|
153
154
|
|
|
155
|
+
const resolveHtmlCandidates = (pathname) => {
|
|
156
|
+
const candidates = []
|
|
157
|
+
if (pathname === '/' || pathname === '') {
|
|
158
|
+
candidates.push('/index.html')
|
|
159
|
+
} else if (pathname.endsWith('.html')) {
|
|
160
|
+
candidates.push(pathname)
|
|
161
|
+
} else {
|
|
162
|
+
candidates.push(`${pathname}.html`)
|
|
163
|
+
candidates.push(`${pathname}/index.html`)
|
|
164
|
+
}
|
|
165
|
+
return candidates.map((candidate) =>
|
|
166
|
+
resolve(state.PAGES_DIR, candidate.replace(/^\//, ''))
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const shouldServeHtml = (relativePath, requestedPath, hasMdx) => {
|
|
171
|
+
if (hasMdx) return false
|
|
172
|
+
const baseName = basename(relativePath, '.html')
|
|
173
|
+
if (baseName.startsWith('_') || baseName.startsWith('.')) return false
|
|
174
|
+
const excludedDirs = pagesContext?.excludedDirs
|
|
175
|
+
if (excludedDirs?.size) {
|
|
176
|
+
const dir = relativePath.split('/').slice(0, -1).join('/')
|
|
177
|
+
for (const excludedDir of excludedDirs) {
|
|
178
|
+
if (!excludedDir) return false
|
|
179
|
+
if (dir === excludedDir || dir.startsWith(`${excludedDir}/`)) {
|
|
180
|
+
return false
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const excludedRoutes = pagesContext?.excludedRoutes
|
|
185
|
+
if (excludedRoutes?.has(requestedPath)) return false
|
|
186
|
+
const excludedDirPaths = pagesContext?.excludedDirPaths
|
|
187
|
+
if (excludedDirPaths?.size) {
|
|
188
|
+
for (const dirPath of excludedDirPaths) {
|
|
189
|
+
if (requestedPath === dirPath || requestedPath.startsWith(`${dirPath}/`)) {
|
|
190
|
+
return false
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return true
|
|
195
|
+
}
|
|
196
|
+
|
|
154
197
|
const htmlMiddleware = async (req, res, next) => {
|
|
155
198
|
if (!req.url || req.method !== 'GET') {
|
|
156
199
|
return next()
|
|
@@ -206,9 +249,38 @@ export const runViteDev = async () => {
|
|
|
206
249
|
? (pagesContext?.pagesByRouteIndex?.get(requestedPath) ?? pagesContext?.pagesByRoute?.get(requestedPath) ?? null)
|
|
207
250
|
: (pagesContext?.pagesByRoute?.get(requestedPath) ?? null)
|
|
208
251
|
let filePath = pageMeta?.filePath || resolvePageFile(requestedPath)
|
|
252
|
+
const hasMdx = Boolean(pageMeta) || existsSync(filePath)
|
|
209
253
|
let status = 200
|
|
210
254
|
let renderRoutePath = requestedPath
|
|
211
255
|
|
|
256
|
+
if (!hasMdx) {
|
|
257
|
+
const candidates = resolveHtmlCandidates(pathname)
|
|
258
|
+
for (const candidate of candidates) {
|
|
259
|
+
if (!existsSync(candidate)) continue
|
|
260
|
+
const relativePath = relative(state.PAGES_DIR, candidate).replace(/\\/g, '/')
|
|
261
|
+
if (relativePath.startsWith('..')) {
|
|
262
|
+
continue
|
|
263
|
+
}
|
|
264
|
+
if (!shouldServeHtml(relativePath, requestedPath, hasMdx)) {
|
|
265
|
+
continue
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
const html = await readFile(candidate, 'utf-8')
|
|
269
|
+
const candidateUrl = `/${relativePath}`
|
|
270
|
+
const transformed = await server.transformIndexHtml(candidateUrl, html)
|
|
271
|
+
res.statusCode = 200
|
|
272
|
+
res.setHeader('Content-Type', 'text/html')
|
|
273
|
+
res.end(transformed)
|
|
274
|
+
return
|
|
275
|
+
} catch (err) {
|
|
276
|
+
console.error(err)
|
|
277
|
+
res.statusCode = 500
|
|
278
|
+
res.end('Internal Server Error')
|
|
279
|
+
return
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
212
284
|
if (isExcludedPath()) {
|
|
213
285
|
if (notFoundPage) {
|
|
214
286
|
filePath = notFoundPage.filePath
|
|
@@ -414,12 +486,13 @@ export const runViteDev = async () => {
|
|
|
414
486
|
prevEntry.toc = null
|
|
415
487
|
pagesContext.refreshPagesTree?.()
|
|
416
488
|
pagesContext.refreshLanguages?.()
|
|
417
|
-
if (prevEntry.
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
489
|
+
if (prevEntry.content && prevEntry.content.trim().length) {
|
|
490
|
+
await compilePageMdx(prevEntry, pagesContext, {
|
|
491
|
+
lazyPagesTree: true,
|
|
492
|
+
refreshPagesTree: false
|
|
493
|
+
})
|
|
494
|
+
// Avoid caching a potentially stale render; recompile on request.
|
|
495
|
+
prevEntry.mdxComponent = null
|
|
423
496
|
}
|
|
424
497
|
return true
|
|
425
498
|
}
|
package/src/main.js
CHANGED
|
@@ -24,6 +24,7 @@ import { buildHtmlEntries, runViteBuild } from './build-system.js'
|
|
|
24
24
|
import { runPagefind } from './pagefind.js'
|
|
25
25
|
import { runVitePreview } from './preview-server.js'
|
|
26
26
|
import { cli, state } from './state.js'
|
|
27
|
+
import { HTMLRenderer } from './renderer.js'
|
|
27
28
|
import { readFile } from 'fs/promises'
|
|
28
29
|
|
|
29
30
|
const printBanner = async () => {
|
|
@@ -61,7 +62,39 @@ const main = async () => {
|
|
|
61
62
|
const mode = isDev ? 'development' : 'production'
|
|
62
63
|
const config = await loadUserConfig(mode, cli.CLI_CONFIG_PATH)
|
|
63
64
|
await applyConfig(config, mode)
|
|
65
|
+
const hookContext = {
|
|
66
|
+
mode,
|
|
67
|
+
root: state.ROOT_DIR,
|
|
68
|
+
command: normalizedCommand,
|
|
69
|
+
isDev,
|
|
70
|
+
isBuild,
|
|
71
|
+
isPreview,
|
|
72
|
+
HTMLRenderer,
|
|
73
|
+
site: {
|
|
74
|
+
name: state.SITE_NAME,
|
|
75
|
+
root: state.ROOT_DIR,
|
|
76
|
+
pagesDir: state.PAGES_DIR,
|
|
77
|
+
componentsDir: state.COMPONENTS_DIR,
|
|
78
|
+
publicDir: state.STATIC_DIR,
|
|
79
|
+
distDir: state.DIST_DIR,
|
|
80
|
+
mode: state.CURRENT_MODE,
|
|
81
|
+
pagefind: {
|
|
82
|
+
enabled: state.PAGEFIND_ENABLED,
|
|
83
|
+
options: state.PAGEFIND_OPTIONS || null,
|
|
84
|
+
build: state.PAGEFIND_BUILD || null
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
data: {}
|
|
88
|
+
}
|
|
89
|
+
const runHooks = async (hooks = [], extra = null) => {
|
|
90
|
+
const context = extra ? { ...hookContext, ...extra } : hookContext
|
|
91
|
+
for (const hook of hooks) {
|
|
92
|
+
await hook(context)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
64
95
|
if (isDev) {
|
|
96
|
+
await runHooks(state.USER_PRE_BUILD_HOOKS)
|
|
97
|
+
await runHooks(state.THEME_PRE_BUILD_HOOKS)
|
|
65
98
|
await runViteDev()
|
|
66
99
|
return
|
|
67
100
|
}
|
|
@@ -70,11 +103,28 @@ const main = async () => {
|
|
|
70
103
|
return
|
|
71
104
|
}
|
|
72
105
|
if (isBuild) {
|
|
73
|
-
|
|
106
|
+
await runHooks(state.USER_PRE_BUILD_HOOKS)
|
|
107
|
+
await runHooks(state.THEME_PRE_BUILD_HOOKS)
|
|
108
|
+
const { entry, htmlCache, pagesContext } = await buildHtmlEntries()
|
|
109
|
+
const buildContext = pagesContext
|
|
110
|
+
? {
|
|
111
|
+
pagesContext,
|
|
112
|
+
pages: pagesContext.pages,
|
|
113
|
+
pagesTree: pagesContext.pagesTree,
|
|
114
|
+
pagesByRoute: pagesContext.pagesByRoute,
|
|
115
|
+
site: pagesContext.site
|
|
116
|
+
}
|
|
117
|
+
: null
|
|
118
|
+
await runHooks(state.USER_PRE_BUNDLE_HOOKS, buildContext)
|
|
119
|
+
await runHooks(state.THEME_PRE_BUNDLE_HOOKS, buildContext)
|
|
74
120
|
await runViteBuild(entry, htmlCache)
|
|
121
|
+
await runHooks(state.THEME_POST_BUNDLE_HOOKS, buildContext)
|
|
122
|
+
await runHooks(state.USER_POST_BUNDLE_HOOKS, buildContext)
|
|
75
123
|
if (state.PAGEFIND_ENABLED) {
|
|
76
124
|
await runPagefind()
|
|
77
125
|
}
|
|
126
|
+
await runHooks(state.THEME_POST_BUILD_HOOKS, buildContext)
|
|
127
|
+
await runHooks(state.USER_POST_BUILD_HOOKS, buildContext)
|
|
78
128
|
return
|
|
79
129
|
}
|
|
80
130
|
cli.showHelp()
|