aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vuepress/lib/dev.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/vuepress/lib/dev.js')
-rw-r--r--node_modules/vuepress/lib/dev.js149
1 files changed, 149 insertions, 0 deletions
diff --git a/node_modules/vuepress/lib/dev.js b/node_modules/vuepress/lib/dev.js
new file mode 100644
index 00000000..ba909d99
--- /dev/null
+++ b/node_modules/vuepress/lib/dev.js
@@ -0,0 +1,149 @@
+module.exports = async function dev (sourceDir, cliOptions = {}) {
+ const fs = require('fs')
+ const path = require('path')
+ const chalk = require('chalk')
+ const webpack = require('webpack')
+ const chokidar = require('chokidar')
+ const serve = require('webpack-serve')
+ const convert = require('koa-connect')
+ const mount = require('koa-mount')
+ const range = require('koa-range')
+ const serveStatic = require('koa-static')
+ const history = require('connect-history-api-fallback')
+
+ const prepare = require('./prepare')
+ const logger = require('./util/logger')
+ const HeadPlugin = require('./webpack/HeadPlugin')
+ const DevLogPlugin = require('./webpack/DevLogPlugin')
+ const createClientConfig = require('./webpack/createClientConfig')
+ const { applyUserWebpackConfig } = require('./util')
+ const { frontmatterEmitter } = require('./webpack/markdownLoader')
+
+ logger.wait('\nExtracting site metadata...')
+ const options = await prepare(sourceDir)
+
+ // setup watchers to update options and dynamically generated files
+ const update = () => {
+ prepare(sourceDir).catch(err => {
+ console.error(logger.error(chalk.red(err.stack), false))
+ })
+ }
+
+ // watch add/remove of files
+ const pagesWatcher = chokidar.watch([
+ '**/*.md',
+ '.vuepress/components/**/*.vue'
+ ], {
+ cwd: sourceDir,
+ ignored: '.vuepress/**/*.md',
+ ignoreInitial: true
+ })
+ pagesWatcher.on('add', update)
+ pagesWatcher.on('unlink', update)
+ pagesWatcher.on('addDir', update)
+ pagesWatcher.on('unlinkDir', update)
+
+ // watch config file
+ const configWatcher = chokidar.watch([
+ '.vuepress/config.js',
+ '.vuepress/config.yml',
+ '.vuepress/config.toml'
+ ], {
+ cwd: sourceDir,
+ ignoreInitial: true
+ })
+ configWatcher.on('change', update)
+
+ // also listen for frontmatter changes from markdown files
+ frontmatterEmitter.on('update', update)
+
+ // resolve webpack config
+ let config = createClientConfig(options, cliOptions)
+
+ config
+ .plugin('html')
+ // using a fork of html-webpack-plugin to avoid it requiring webpack
+ // internals from an incompatible version.
+ .use(require('vuepress-html-webpack-plugin'), [{
+ template: path.resolve(__dirname, 'app/index.dev.html')
+ }])
+
+ config
+ .plugin('site-data')
+ .use(HeadPlugin, [{
+ tags: options.siteConfig.head || []
+ }])
+
+ const port = await resolvePort(cliOptions.port || options.siteConfig.port)
+ const { host, displayHost } = await resolveHost(cliOptions.host || options.siteConfig.host)
+
+ config
+ .plugin('vuepress-log')
+ .use(DevLogPlugin, [{
+ port,
+ displayHost,
+ publicPath: options.publicPath
+ }])
+
+ config = config.toConfig()
+ const userConfig = options.siteConfig.configureWebpack
+ if (userConfig) {
+ config = applyUserWebpackConfig(userConfig, config, false /* isServer */)
+ }
+
+ const compiler = webpack(config)
+
+ const nonExistentDir = path.resolve(__dirname, 'non-existent')
+ await serve({
+ // avoid project cwd from being served. Otherwise if the user has index.html
+ // in cwd it would break the server
+ content: [nonExistentDir],
+ compiler,
+ host,
+ dev: { logLevel: 'warn' },
+ hot: {
+ port: port + 1,
+ logLevel: 'error'
+ },
+ logLevel: 'error',
+ port,
+ add: app => {
+ const userPublic = path.resolve(sourceDir, '.vuepress/public')
+
+ // enable range request
+ app.use(range)
+
+ // respect base when serving static files...
+ if (fs.existsSync(userPublic)) {
+ app.use(mount(options.publicPath, serveStatic(userPublic)))
+ }
+
+ app.use(convert(history({
+ rewrites: [
+ { from: /\.html$/, to: '/' }
+ ]
+ })))
+ }
+ })
+}
+
+function resolveHost (host) {
+ // webpack-serve hot updates doesn't work properly over 0.0.0.0 on Windows,
+ // but localhost does not allow visiting over network :/
+ const defaultHost = process.platform === 'win32' ? 'localhost' : '0.0.0.0'
+ host = host || defaultHost
+ const displayHost = host === defaultHost && process.platform !== 'win32'
+ ? 'localhost'
+ : host
+ return {
+ displayHost,
+ host
+ }
+}
+
+async function resolvePort (port) {
+ const portfinder = require('portfinder')
+ portfinder.basePort = parseInt(port) || 8080
+ port = await portfinder.getPortPromise()
+ return port
+}