misc(cli): improve loader

This commit is contained in:
Pooya Parsa 2018-03-22 23:59:05 +04:30
parent 4c5c7b3bb4
commit 417e0bff40
6 changed files with 108 additions and 86 deletions

View File

@ -52,7 +52,13 @@ export default class Builder {
if (this.options.dev) {
this.nuxt.hook('close', () => this.unwatch())
}
// else {
// Initialize shared FS and Cache
if (this.options.dev) {
this.mfs = new MFS()
}
// if(!this.options.dev) {
// TODO: enable again when unsafe concern resolved.(common/options.js:42)
// this.nuxt.hook('build:done', () => this.generateConfig())
// }
@ -133,8 +139,6 @@ export default class Builder {
// Generate routes and interpret the template files
await this.generateRoutesAndFiles()
this.spinner.info('Starting webpack...')
// Start webpack build
await this.webpackBuild()
@ -445,66 +449,70 @@ export default class Builder {
}
})
// Initialize shared FS and Cache
const sharedFS = this.options.dev && new MFS()
// Initialize compilers
this.compilers = compilersOptions.map(compilersOption => {
const compiler = webpack(compilersOption)
// In dev, write files in memory FS
if (sharedFS) {
compiler.outputFileSystem = sharedFS
if (this.options.dev) {
compiler.outputFileSystem = this.mfs
}
return compiler
})
// Start Builds
await parallel(
this.compilers,
compiler =>
new Promise(async (resolve, reject) => {
const name = compiler.options.name
await this.nuxt.callHook('build:compile', { name, compiler })
await parallel(this.compilers, compiler => {
return this.webpackCompile(compiler)
})
}
// Resolve only when compiler emit done event
compiler.hooks.done.tap('load-resources', async stats => {
await this.nuxt.callHook('build:compiled', {
name,
compiler,
stats
})
// Reload renderer if available
this.nuxt.renderer.loadResources(sharedFS || fs)
// Resolve on next tick
process.nextTick(resolve)
})
// --- Dev Build ---
if (this.options.dev) {
// Client Build, watch is started by dev-middleware
if (compiler.options.name === 'client') {
return this.webpackDev(compiler)
}
// Server, build and watch for changes
this.compilersWatching.push(
compiler.watch(this.options.watchers.webpack, err => {
/* istanbul ignore if */
if (err) return reject(err)
})
)
return
}
// --- Production Build ---
compiler.run((err, stats) => {
/* istanbul ignore if */
if (err) {
console.error(err) // eslint-disable-line no-console
return reject(err)
}
resolve()
})
webpackCompile(compiler) {
return new Promise(async (resolve, reject) => {
const name = compiler.options.name
await this.nuxt.callHook('build:compile', { name, compiler })
// Load renderer resources after build
compiler.hooks.done.tap('load-resources', async stats => {
await this.nuxt.callHook('build:compiled', {
name,
compiler,
stats
})
)
// Reload renderer if available
this.nuxt.renderer.loadResources(this.mfs || fs)
// Resolve on next tick
process.nextTick(resolve)
})
if (this.options.dev) {
// --- Dev Build ---
// Client Build, watch is started by dev-middleware
if (compiler.options.name === 'client') {
return this.webpackDev(compiler)
}
// Server, build and watch for changes
this.compilersWatching.push(
compiler.watch(this.options.watchers.webpack, err => {
/* istanbul ignore if */
if (err) return reject(err)
})
)
} else {
// --- Production Build ---
compiler.run((err, stats) => {
/* istanbul ignore if */
if (err) {
console.error(err) // eslint-disable-line no-console
return reject(err)
}
resolve()
})
}
})
}
webpackDev(compiler) {

View File

@ -177,7 +177,7 @@ export default class WebpackBaseConfig {
plugins.push(new ProgressPlugin({
spinner: this.spinner,
name: this.isServer ? 'server' : 'client',
color: this.isServer ? 'green' : 'darkgreen'
color: this.isServer ? 'orange' : 'green'
}))
}
}

View File

@ -1,10 +1,12 @@
import webpack from 'webpack'
import chalk from 'chalk'
import _ from 'lodash'
import logUpdate from 'log-update'
const sharedState = {}
const BLOCK_CHAR = '█'
const BAR_LENGTH = 25
export default class ProgressPlugin extends webpack.ProgressPlugin {
constructor(options) {
@ -12,6 +14,8 @@ export default class ProgressPlugin extends webpack.ProgressPlugin {
this.handler = (percent, msg, ...details) => this.updateProgress(percent, msg, details)
this.handler = _.throttle(this.handler, 25, { leading: true, trailing: true })
this.options = options
if (!sharedState[options.name]) {
@ -19,8 +23,12 @@ export default class ProgressPlugin extends webpack.ProgressPlugin {
color: options.color
}
}
}
this.spinner = options.spinner
apply(compiler) {
super.apply(compiler)
compiler.hooks.done.tap('progress', () => logUpdate.clear())
}
get state() {
@ -31,52 +39,46 @@ export default class ProgressPlugin extends webpack.ProgressPlugin {
const progress = Math.floor(percent * 100)
this.state.progress = progress
this.state.msg = msg
this.state.msg = (msg && msg.length) ? msg : 'wait'
// Process all states
let inProgress = false
const additional = []
const lines = []
const bars = Object.keys(sharedState).map(name => {
_.sortBy(Object.keys(sharedState), s => s.name).forEach(name => {
const state = sharedState[name]
if (state.progress < 100) {
inProgress = true
}
const blockChar = chalk.keyword(state.color)(BLOCK_CHAR)
const _color = chalk.keyword(state.color)
additional.push(`${blockChar} ${name} (${state.progress}%) `)
const _icon = _color('⠸')
const _name = _color(_.startCase(name))
const _bar = this._renderBar(state.progress, state.color)
const _msg = chalk.grey(_.startCase(state.msg))
const _progress = chalk.grey('(' + state.progress + '%)')
return {
name,
color: state.color,
progress: state.progress,
blockChar: chalk.keyword(state.color)(BLOCK_CHAR)
}
lines.push([_icon, _name, _bar, _msg, _progress].join(' '))
})
if (!inProgress) {
this.spinner.succeed('Compiled ' + this.options.name)
return
logUpdate.clear()
} else {
logUpdate('\n' + lines.join('\n') + '\n')
}
}
// Generate progressbars
_renderBar(progress, color) {
const w = progress * (BAR_LENGTH / 100)
const bg = chalk.white(BLOCK_CHAR)
// const fg = chalk.keyword(color)(BLOCK_CHAR)
const width = 25
const progressbars = _.range(width).fill(chalk.white(BLOCK_CHAR))
const base = color === 'green' ? 100 : 50
const fg = i => chalk.hsl(i * 3 + base, 100, 50)(BLOCK_CHAR)
_.sortBy(bars, 'progress').reverse().forEach(bar => {
const w = bar.progress * (width / 100)
for (let i = 0; i < w; i++) {
progressbars[i] = bar.blockChar
}
})
// Update spinner
this.spinner.start()
this.spinner.text = _.startCase(msg) + ' ' + progressbars.join('') + ' ' + additional.join(' ')
return _.range(BAR_LENGTH).map(i => i < w ? fg(i) : bg).join('')
}
}

View File

@ -29,11 +29,7 @@ export const fatalError = function () {
export const createSpinner = function ({ minimal = false }) {
// Use ORA by default
if (!minimal) {
return new ORA({
color: 'green',
spinner: 'clock',
interval: 50
})
return new ORA()
}
// Creare a minimal fallback for test and CI environments

View File

@ -82,6 +82,7 @@
"is-ci": "^1.1.0",
"launch-editor-middleware": "^2.2.1",
"lodash": "^4.17.5",
"log-update": "^2.3.0",
"lru-cache": "^4.1.2",
"memory-fs": "^0.4.1",
"mini-css-extract-plugin": "^0.2.0",

View File

@ -1482,7 +1482,7 @@ cli-cursor@^1.0.2:
dependencies:
restore-cursor "^1.0.1"
cli-cursor@^2.1.0:
cli-cursor@^2.0.0, cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
@ -4448,6 +4448,14 @@ log-update@^1.0.2:
ansi-escapes "^1.0.0"
cli-cursor "^1.0.2"
log-update@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708"
dependencies:
ansi-escapes "^3.0.0"
cli-cursor "^2.0.0"
wrap-ansi "^3.0.1"
loglevelnext@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.3.tgz#0f69277e73bbbf2cd61b94d82313216bf87ac66e"
@ -7561,6 +7569,13 @@ wrap-ansi@^2.0.0:
string-width "^1.0.1"
strip-ansi "^3.0.1"
wrap-ansi@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba"
dependencies:
string-width "^2.1.1"
strip-ansi "^4.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"