Skip to content

Commit

Permalink
feat: better log (#506)
Browse files Browse the repository at this point in the history
  • Loading branch information
ulivz authored May 26, 2018
1 parent d531073 commit d53807e
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 35 deletions.
13 changes: 7 additions & 6 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ 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
}

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)

Expand Down Expand Up @@ -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)
}
Expand All @@ -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'),
Expand All @@ -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 ---

Expand Down Expand Up @@ -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(/^\//, ''))
Expand Down
63 changes: 36 additions & 27 deletions lib/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
}

Expand Down Expand Up @@ -67,37 +68,24 @@ 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) {
config = applyUserWebpackConfig(userConfig, config, false /* isServer */)
}

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({
Expand Down Expand Up @@ -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
}
3 changes: 2 additions & 1 deletion lib/eject.js
Original file line number Diff line number Diff line change
@@ -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')
Expand All @@ -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`)
}
3 changes: 2 additions & 1 deletion lib/markdown/highlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'])
Expand Down Expand Up @@ -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]) {
Expand Down
48 changes: 48 additions & 0 deletions lib/util/logger.js
Original file line number Diff line number Diff line change
@@ -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
29 changes: 29 additions & 0 deletions lib/webpack/DevLogPlugin.js
Original file line number Diff line number Diff line change
@@ -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')
}

0 comments on commit d53807e

Please sign in to comment.