Skip to content

Commit 41f9dc6

Browse files
committed
feat(cli): allow setting default app config
1 parent acfca7f commit 41f9dc6

File tree

9 files changed

+174
-142
lines changed

9 files changed

+174
-142
lines changed

packages/@vuepress/cli/src/cli.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { cac } from 'cac'
2+
import type { AppConfig } from '@vuepress/core'
23
import { chalk } from '@vuepress/utils'
3-
import { build, dev, info } from './commands'
4+
import { createBuild, createDev, info } from './commands'
45
import { allowTs } from './utils'
56

67
/**
@@ -18,7 +19,7 @@ const wrapCommand = (cmd: (...args: any[]) => Promise<void>): typeof cmd => {
1819
/**
1920
* Vuepress cli
2021
*/
21-
export const cli = (): void => {
22+
export const cli = (defaultAppConfig: Partial<AppConfig> = {}): void => {
2223
// allow ts files globally
2324
allowTs()
2425

@@ -46,7 +47,7 @@ export const cli = (): void => {
4647
.option('--open', 'Open browser when ready')
4748
.option('--debug', 'Enable debug mode')
4849
.option('--no-watch', 'Disable watching page and config files')
49-
.action(wrapCommand(dev))
50+
.action(wrapCommand(createDev(defaultAppConfig)))
5051

5152
// register `build` command
5253
program
@@ -61,7 +62,7 @@ export const cli = (): void => {
6162
.option('--clean-temp', 'Clean the temporary files before build')
6263
.option('--clean-cache', 'Clean the cache files before build')
6364
.option('--debug', 'Enable debug mode')
64-
.action(wrapCommand(build))
65+
.action(wrapCommand(createBuild(defaultAppConfig)))
6566

6667
// register `info` command
6768
program

packages/@vuepress/cli/src/commands/build/build.ts renamed to packages/@vuepress/cli/src/commands/build/createBuild.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createApp } from '@vuepress/core'
2+
import type { AppConfig } from '@vuepress/core'
23
import { debug, fs, logger } from '@vuepress/utils'
34
import {
45
loadUserConfig,
@@ -11,9 +12,16 @@ import type { BuildCommandOptions } from './types'
1112

1213
const log = debug('vuepress:cli/build')
1314

14-
export const build = async (
15+
export type BuildCommand = (
16+
sourceDir?: string,
17+
commandOptions?: BuildCommandOptions
18+
) => Promise<void>
19+
20+
export const createBuild = (
21+
defaultAppConfig: Partial<AppConfig>
22+
): BuildCommand => async (
1523
sourceDir = '.',
16-
commandOptions: BuildCommandOptions = {}
24+
commandOptions = {}
1725
): Promise<void> => {
1826
log(`commandOptions:`, commandOptions)
1927

@@ -22,22 +30,25 @@ export const build = async (
2230
}
2331

2432
// resolve base app config
25-
const appConfig = resolveBuildAppConfig(sourceDir, commandOptions)
33+
const cliAppConfig = resolveBuildAppConfig(sourceDir, commandOptions)
2634

2735
// resolve user config file
2836
const userConfigPath = commandOptions.config
2937
? resolveUserConfigPath(commandOptions.config)
30-
: resolveUserConfigConventionalPath(appConfig.source)
38+
: resolveUserConfigConventionalPath(cliAppConfig.source)
3139

3240
log(`userConfigPath:`, userConfigPath)
3341

3442
const userConfig = await loadUserConfig(userConfigPath)
3543

3644
// create vuepress app
3745
const app = createApp({
46+
// allow setting default app config via `cli()`
47+
// for example, set different default bundler in `vuepress` and `vuepress-vite` package
48+
...defaultAppConfig,
3849
// use cli options to override config file
3950
...userConfig,
40-
...appConfig,
51+
...cliAppConfig,
4152
})
4253

4354
// use user-config plugin
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export * from './build'
1+
export * from './createBuild'
22
export * from './resolveBuildAppConfig'
33
export * from './types'
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import * as chokidar from 'chokidar'
2+
import type { FSWatcher } from 'chokidar'
3+
import { createApp } from '@vuepress/core'
4+
import type { AppConfig } from '@vuepress/core'
5+
import { chalk, debug, fs, logger } from '@vuepress/utils'
6+
import {
7+
loadUserConfig,
8+
resolveUserConfigConventionalPath,
9+
resolveUserConfigPath,
10+
transformUserConfigToPlugin,
11+
} from '../../config'
12+
import { handlePageAdd } from './handlePageAdd'
13+
import { handlePageChange } from './handlePageChange'
14+
import { handlePageUnlink } from './handlePageUnlink'
15+
import { resolveDevAppConfig } from './resolveDevAppConfig'
16+
import type { DevCommandOptions } from './types'
17+
18+
const log = debug('vuepress:cli/dev')
19+
20+
export type DevCommand = (
21+
sourceDir?: string,
22+
commandOptions?: DevCommandOptions
23+
) => Promise<void>
24+
25+
export const createDev = (defaultAppConfig: Partial<AppConfig>): DevCommand => {
26+
const dev: DevCommand = async (
27+
sourceDir = '.',
28+
commandOptions = {}
29+
): Promise<void> => {
30+
log(`commandOptions:`, commandOptions)
31+
32+
if (process.env.NODE_ENV === undefined) {
33+
process.env.NODE_ENV = 'development'
34+
}
35+
36+
// resolve app config from cli options
37+
const cliAppConfig = resolveDevAppConfig(sourceDir, commandOptions)
38+
39+
// resolve user config file
40+
const userConfigPath = commandOptions.config
41+
? resolveUserConfigPath(commandOptions.config)
42+
: resolveUserConfigConventionalPath(cliAppConfig.source)
43+
44+
log(`userConfigPath:`, userConfigPath)
45+
46+
const userConfig = await loadUserConfig(userConfigPath)
47+
48+
// create vuepress app
49+
const app = createApp({
50+
// allow setting default app config via `cli()`
51+
// for example, set different default bundler in `vuepress` and `vuepress-vite` package
52+
...defaultAppConfig,
53+
// use cli options to override config file
54+
...userConfig,
55+
...cliAppConfig,
56+
})
57+
58+
// use user-config plugin
59+
app.use(transformUserConfigToPlugin(app, userConfig))
60+
61+
// clean temp and cache
62+
if (commandOptions.cleanTemp === true) {
63+
logger.info('Cleaning temp...')
64+
await fs.remove(app.dir.temp())
65+
}
66+
if (commandOptions.cleanCache === true) {
67+
logger.info('Cleaning cache...')
68+
await fs.remove(app.dir.cache())
69+
}
70+
71+
// initialize and prepare
72+
logger.info('Initializing VuePress and preparing data...')
73+
await app.init()
74+
await app.prepare()
75+
76+
// start dev server
77+
const close = await app.dev()
78+
79+
// do not watch files if `watch` is set to `false`
80+
if (commandOptions.watch === false) {
81+
return
82+
}
83+
84+
// all watchers
85+
const watchers: FSWatcher[] = []
86+
87+
// restart dev command
88+
const restart = async (): Promise<void> => {
89+
await Promise.all([
90+
// close all watchers
91+
...watchers.map((item) => item.close()),
92+
// close current dev server
93+
close(),
94+
])
95+
// restart dev command
96+
await dev(sourceDir, {
97+
...commandOptions,
98+
// do not clean cache and temp on restart
99+
cleanCache: false,
100+
cleanTemp: false,
101+
})
102+
logger.tip(`dev server has restarted, please refresh your browser`)
103+
}
104+
105+
// watch page files
106+
const pagesWatcher = chokidar.watch(app.options.pagePatterns, {
107+
cwd: app.dir.source(),
108+
ignoreInitial: true,
109+
})
110+
pagesWatcher.on('add', (filePathRelative) => {
111+
logger.info(`page ${chalk.magenta(filePathRelative)} is created`)
112+
handlePageAdd(app, app.dir.source(filePathRelative))
113+
})
114+
pagesWatcher.on('change', (filePathRelative) => {
115+
logger.info(`page ${chalk.magenta(filePathRelative)} is modified`)
116+
handlePageChange(app, app.dir.source(filePathRelative))
117+
})
118+
pagesWatcher.on('unlink', (filePathRelative) => {
119+
logger.info(`page ${chalk.magenta(filePathRelative)} is removed`)
120+
handlePageUnlink(app, app.dir.source(filePathRelative))
121+
})
122+
watchers.push(pagesWatcher)
123+
124+
// watch user config file
125+
if (userConfigPath) {
126+
const configWatcher = chokidar.watch(userConfigPath, {
127+
cwd: process.cwd(),
128+
ignoreInitial: true,
129+
})
130+
configWatcher.on('change', (configFile) => {
131+
logger.info(`config ${chalk.magenta(configFile)} is modified`)
132+
restart()
133+
})
134+
watchers.push(configWatcher)
135+
}
136+
137+
await app.pluginApi.hooks.onWatched.process(app, watchers, restart)
138+
}
139+
140+
return dev
141+
}

packages/@vuepress/cli/src/commands/dev/dev.ts

Lines changed: 0 additions & 128 deletions
This file was deleted.

packages/@vuepress/cli/src/commands/dev/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export * from './dev'
1+
export * from './createDev'
22
export * from './handlePageAdd'
33
export * from './handlePageChange'
44
export * from './handlePageUnlink'
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
#!/usr/bin/env node
22

3-
require('@vuepress/cli/bin/vuepress')
3+
const { cli } = require('@vuepress/cli')
4+
5+
// set default bundler
6+
cli({ bundler: '@vuepress/bundler-vite' })

packages/vuepress-vite/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"main": "lib/index.js",
2222
"types": "lib/index.d.ts",
2323
"bin": {
24-
"vuepress": "bin/vuepress.js"
24+
"vuepress": "bin/vuepress.js",
25+
"vuepress-vite": "bin/vuepress.js"
2526
},
2627
"files": [
2728
"bin",

packages/vuepress/bin/vuepress.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
#!/usr/bin/env node
22

3-
require('@vuepress/cli/bin/vuepress')
3+
const { cli } = require('@vuepress/cli')
4+
5+
// set default bundler
6+
cli({ bundler: '@vuepress/bundler-webpack' })

0 commit comments

Comments
 (0)