mirror of
https://github.com/wahyd4/vuepress.git
synced 2026-08-09 05:16:23 +10:00
feat: better log (#506)
This commit is contained in:
+7
-6
@@ -8,13 +8,14 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
|
||||
const readline = require('readline')
|
||||
const escape = require('escape-html')
|
||||
|
||||
const logger = require('./util/logger')
|
||||
const prepare = require('./prepare')
|
||||
const createClientConfig = require('./webpack/createClientConfig')
|
||||
const createServerConfig = require('./webpack/createServerConfig')
|
||||
const { createBundleRenderer } = require('vue-server-renderer')
|
||||
const { normalizeHeadTag, applyUserWebpackConfig } = require('./util')
|
||||
|
||||
process.stdout.write('Extracting site metadata...')
|
||||
logger.wait('\nExtracting site metadata...')
|
||||
const options = await prepare(sourceDir)
|
||||
if (cliOptions.outDir) {
|
||||
options.outDir = cliOptions.outDir
|
||||
@@ -22,7 +23,7 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
|
||||
|
||||
const { outDir } = options
|
||||
if (path.resolve() === outDir) {
|
||||
return console.error(chalk.red('Unexpected option: outDir cannot be set to the current working directory.\n'))
|
||||
return console.error(logger.error(chalk.red('Unexpected option: outDir cannot be set to the current working directory.\n'), false))
|
||||
}
|
||||
await fs.remove(outDir)
|
||||
|
||||
@@ -64,7 +65,7 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
|
||||
.join('\n ')
|
||||
|
||||
// render pages
|
||||
console.log('Rendering static HTML...')
|
||||
logger.wait('Rendering static HTML...')
|
||||
for (const page of options.siteData.pages) {
|
||||
await renderPage(page)
|
||||
}
|
||||
@@ -78,7 +79,7 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
|
||||
readline.cursorTo(process.stdout, 0)
|
||||
|
||||
if (options.siteConfig.serviceWorker) {
|
||||
console.log('Generating service worker...')
|
||||
logger.wait('\nGenerating service worker...')
|
||||
const wbb = require('workbox-build')
|
||||
wbb.generateSW({
|
||||
swDest: path.resolve(outDir, 'service-worker.js'),
|
||||
@@ -89,7 +90,7 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
|
||||
|
||||
// DONE.
|
||||
const relativeDir = path.relative(process.cwd(), outDir)
|
||||
console.log(`\n${chalk.green('Success!')} Generated static files in ${chalk.cyan(relativeDir)}.`)
|
||||
logger.success(`\n${chalk.green('Success!')} Generated static files in ${chalk.cyan(relativeDir)}.\n`)
|
||||
|
||||
// --- helpers ---
|
||||
|
||||
@@ -150,7 +151,7 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
|
||||
try {
|
||||
html = await renderer.renderToString(context)
|
||||
} catch (e) {
|
||||
console.error(chalk.red(`Error rendering ${pagePath}:`))
|
||||
console.error(logger.error(chalk.red(`Error rendering ${pagePath}:`), false))
|
||||
throw e
|
||||
}
|
||||
const filename = decodeURIComponent(pagePath.replace(/\/$/, '/index.html').replace(/^\//, ''))
|
||||
|
||||
+36
-27
@@ -9,21 +9,22 @@ module.exports = async function dev (sourceDir, cliOptions = {}) {
|
||||
const mount = require('koa-mount')
|
||||
const serveStatic = require('koa-static')
|
||||
const history = require('connect-history-api-fallback')
|
||||
const portfinder = require('portfinder')
|
||||
|
||||
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')
|
||||
|
||||
process.stdout.write('Extracting site metadata...')
|
||||
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(chalk.red(err.stack))
|
||||
console.error(logger.error(chalk.red(err.stack), false))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -67,6 +68,17 @@ module.exports = async function dev (sourceDir, cliOptions = {}) {
|
||||
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) {
|
||||
@@ -74,30 +86,6 @@ module.exports = async function dev (sourceDir, cliOptions = {}) {
|
||||
}
|
||||
|
||||
const compiler = webpack(config)
|
||||
// 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'
|
||||
const host = cliOptions.host || options.siteConfig.host || defaultHost
|
||||
const displayHost = host === defaultHost && process.platform !== 'win32'
|
||||
? 'localhost'
|
||||
: host
|
||||
portfinder.basePort = cliOptions.port || options.siteConfig.port || 8080
|
||||
const port = await portfinder.getPortPromise()
|
||||
|
||||
let isFirst = true
|
||||
compiler.hooks.done.tap('vuepress', () => {
|
||||
if (isFirst) {
|
||||
isFirst = false
|
||||
console.log(
|
||||
`\n VuePress dev server listening at ${
|
||||
chalk.cyan(`http://${displayHost}:${port}${options.publicPath}`)
|
||||
}\n`
|
||||
)
|
||||
} else {
|
||||
const time = new Date().toTimeString().match(/^[\d:]+/)[0]
|
||||
console.log(` ${chalk.gray(`[${time}]`)} ${chalk.green('✔')} successfully compiled.`)
|
||||
}
|
||||
})
|
||||
|
||||
const nonExistentDir = path.resolve(__dirname, 'non-existent')
|
||||
await serve({
|
||||
@@ -128,3 +116,24 @@ module.exports = async function dev (sourceDir, cliOptions = {}) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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 = port || 8080
|
||||
port = await portfinder.getPortPromise()
|
||||
return port
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const logger = require('./util/logger')
|
||||
|
||||
module.exports = async (dir) => {
|
||||
const source = path.resolve(__dirname, 'default-theme')
|
||||
@@ -11,5 +12,5 @@ module.exports = async (dir) => {
|
||||
const content = await fs.readFile(styleConfig, 'utf-8')
|
||||
const transformed = content.split('\n').slice(0, -2).join('\n')
|
||||
await fs.writeFile(styleConfig, transformed)
|
||||
console.log(`Copied default theme into ${chalk.cyan(target)}.`)
|
||||
logger.success(`\nCopied default theme into ${chalk.cyan(target)}.\n`)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ const chalk = require('chalk')
|
||||
const prism = require('prismjs')
|
||||
const loadLanguages = require('prismjs/components/index')
|
||||
const escapeHtml = require('escape-html')
|
||||
const logger = require('../util/logger')
|
||||
|
||||
// required to make embedded highlighting work...
|
||||
loadLanguages(['markup', 'css', 'javascript'])
|
||||
@@ -32,7 +33,7 @@ module.exports = (str, lang) => {
|
||||
try {
|
||||
loadLanguages([lang])
|
||||
} catch (e) {
|
||||
console.log(chalk.yellow(`[vuepress] Syntax highlight for language "${lang}" is not supported.`))
|
||||
logger.warn(chalk.yellow(`[vuepress] Syntax highlight for language "${lang}" is not supported.`))
|
||||
}
|
||||
}
|
||||
if (prism.languages[lang]) {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
const chalk = require('chalk')
|
||||
|
||||
const logger = {}
|
||||
|
||||
const logTypes = {
|
||||
success: {
|
||||
color: 'green',
|
||||
label: 'DONE'
|
||||
},
|
||||
error: {
|
||||
color: 'red',
|
||||
label: 'FAIL'
|
||||
},
|
||||
warn: {
|
||||
color: 'yellow',
|
||||
label: 'WARN'
|
||||
},
|
||||
tip: {
|
||||
color: 'cyan',
|
||||
label: 'TIP'
|
||||
},
|
||||
wait: {
|
||||
color: 'blue',
|
||||
label: 'WAIT'
|
||||
}
|
||||
}
|
||||
|
||||
const getLoggerFn = (color, label) => (msg, log = true) => {
|
||||
let newLine = false
|
||||
if (msg.startsWith('\n')) {
|
||||
if (log) msg = msg.slice(1)
|
||||
newLine = true
|
||||
}
|
||||
msg = chalk.reset.inverse.bold[color](` ${label} `) + ' ' + msg
|
||||
if (log) {
|
||||
console.log(newLine ? '\n' + msg : msg)
|
||||
} else {
|
||||
return msg
|
||||
}
|
||||
}
|
||||
|
||||
for (const type in logTypes) {
|
||||
const { color, label } = logTypes[type]
|
||||
logger[type] = getLoggerFn(color, label)
|
||||
}
|
||||
|
||||
module.exports = logger
|
||||
module.exports.getLoggerFn = getLoggerFn
|
||||
@@ -0,0 +1,29 @@
|
||||
const chalk = require('chalk')
|
||||
const logger = require('../util/logger')
|
||||
|
||||
module.exports = class DevLogPlugin {
|
||||
constructor (options) {
|
||||
this.options = options
|
||||
}
|
||||
|
||||
apply (compiler) {
|
||||
let isFirst = true
|
||||
compiler.hooks.done.tap('vuepress-log', stats => {
|
||||
clearScreen()
|
||||
|
||||
const { displayHost, port, publicPath } = this.options
|
||||
const time = new Date().toTimeString().match(/^[\d:]+/)[0]
|
||||
|
||||
logger.success(`\n${chalk.gray(`[${time}]`)} Build ${chalk.italic(stats.hash.slice(0, 6))} finished in ${stats.endTime - stats.startTime} ms!`)
|
||||
if (isFirst) {
|
||||
isFirst = false
|
||||
console.log(`\n${chalk.gray('>')} VuePress dev server listening at ${chalk.cyan(`http://${displayHost}:${port}${publicPath}`)}`)
|
||||
}
|
||||
})
|
||||
compiler.hooks.invalid.tap('vuepress-log', clearScreen)
|
||||
}
|
||||
}
|
||||
|
||||
function clearScreen () {
|
||||
process.stdout.write('\x1Bc')
|
||||
}
|
||||
Reference in New Issue
Block a user