Refactor with async/await instead of yield

This commit is contained in:
Pooya Parsa 2017-05-16 01:21:27 +04:30
parent 34ac2f8b1c
commit c2befae5db
3 changed files with 55 additions and 67 deletions

View File

@ -1,7 +1,6 @@
'use strict' 'use strict'
import _ from 'lodash' import _ from 'lodash'
import co from 'co'
import chokidar from 'chokidar' import chokidar from 'chokidar'
import fs from 'fs-extra' import fs from 'fs-extra'
import hash from 'hash-sum' import hash from 'hash-sum'
@ -115,7 +114,7 @@ export function options () {
} }
} }
export function * build () { export async function build () {
// Check if pages dir exists and warn if not // Check if pages dir exists and warn if not
if (!fs.existsSync(join(this.srcDir, 'pages'))) { if (!fs.existsSync(join(this.srcDir, 'pages'))) {
if (fs.existsSync(join(this.srcDir, '..', 'pages'))) { if (fs.existsSync(join(this.srcDir, '..', 'pages'))) {
@ -128,19 +127,19 @@ export function * build () {
debug(`App root: ${this.srcDir}`) debug(`App root: ${this.srcDir}`)
debug('Generating .nuxt/ files...') debug('Generating .nuxt/ files...')
// Create .nuxt/, .nuxt/components and .nuxt/dist folders // Create .nuxt/, .nuxt/components and .nuxt/dist folders
yield remove(r(this.dir, '.nuxt')) await remove(r(this.dir, '.nuxt'))
yield mkdirp(r(this.dir, '.nuxt/components')) await mkdirp(r(this.dir, '.nuxt/components'))
if (!this.dev) { if (!this.dev) {
yield mkdirp(r(this.dir, '.nuxt/dist')) await mkdirp(r(this.dir, '.nuxt/dist'))
} }
// Generate routes and interpret the template files // Generate routes and interpret the template files
yield generateRoutesAndFiles.call(this) await generateRoutesAndFiles.call(this)
// Generate .nuxt/dist/ files // Generate .nuxt/dist/ files
yield buildFiles.call(this) await buildFiles.call(this)
return this return this
} }
function * buildFiles () { async function buildFiles () {
if (this.dev) { if (this.dev) {
debug('Adding webpack middleware...') debug('Adding webpack middleware...')
createWebpackMiddleware.call(this) createWebpackMiddleware.call(this)
@ -148,8 +147,8 @@ function * buildFiles () {
watchPages.call(this) watchPages.call(this)
} else { } else {
debug('Building files...') debug('Building files...')
yield webpackRunClient.call(this) await webpackRunClient.call(this)
yield webpackRunServer.call(this) await webpackRunServer.call(this)
addAppTemplate.call(this) addAppTemplate.call(this)
} }
} }
@ -163,17 +162,17 @@ function addAppTemplate () {
} }
} }
function * generateRoutesAndFiles () { async function generateRoutesAndFiles () {
debug('Generating routes...') debug('Generating routes...')
// Layouts // Layouts
let layouts = {} let layouts = {}
const layoutsFiles = yield glob('layouts/*.vue', { cwd: this.srcDir }) const layoutsFiles = await glob('layouts/*.vue', { cwd: this.srcDir })
layoutsFiles.forEach((file) => { layoutsFiles.forEach((file) => {
let name = file.split('/').slice(-1)[0].replace('.vue', '') let name = file.split('/').slice(-1)[0].replace('.vue', '')
if (name === 'error') return if (name === 'error') return
layouts[name] = r(this.srcDir, file) layouts[name] = r(this.srcDir, file)
}) })
const files = yield glob('pages/**/*.vue', { cwd: this.srcDir }) const files = await glob('pages/**/*.vue', { cwd: this.srcDir })
// Interpret and move template files to .nuxt/ // Interpret and move template files to .nuxt/
let templatesFiles = [ let templatesFiles = [
'App.vue', 'App.vue',
@ -234,7 +233,7 @@ function * generateRoutesAndFiles () {
} }
// If no default layout, create its folder and add the default folder // If no default layout, create its folder and add the default folder
if (!layouts.default) { if (!layouts.default) {
yield mkdirp(r(this.dir, '.nuxt/layouts')) await mkdirp(r(this.dir, '.nuxt/layouts'))
templatesFiles.push('layouts/default.vue') templatesFiles.push('layouts/default.vue')
layouts.default = r(__dirname, 'app', 'layouts', 'default.vue') layouts.default = r(__dirname, 'app', 'layouts', 'default.vue')
} }
@ -269,7 +268,7 @@ function * generateRoutesAndFiles () {
}) })
}) })
}) })
yield moveTemplates await moveTemplates
} }
function createRoutes (files, srcDir) { function createRoutes (files, srcDir) {
@ -518,8 +517,8 @@ function watchPages () {
ignoreInitial: true ignoreInitial: true
}) })
/* istanbul ignore next */ /* istanbul ignore next */
const refreshFiles = _.debounce(() => { const refreshFiles = _.debounce(async () => {
co(generateRoutesAndFiles.bind(this)) await generateRoutesAndFiles.bind(this)
}, 200) }, 200)
// Watch for internals // Watch for internals
this.pagesFilesWatcher = chokidar.watch(patterns, options) this.pagesFilesWatcher = chokidar.watch(patterns, options)

View File

@ -1,7 +1,6 @@
'use strict' 'use strict'
import _ from 'lodash' import _ from 'lodash'
import co from 'co'
import compression from 'compression' import compression from 'compression'
import fs from 'fs-extra' import fs from 'fs-extra'
import pify from 'pify' import pify from 'pify'
@ -16,7 +15,7 @@ import * as utils from './utils'
class Nuxt { class Nuxt {
constructor (options = {}) { constructor (options = {}) {
var defaults = { const defaults = {
dev: true, dev: true,
env: {}, env: {},
head: { head: {
@ -97,7 +96,7 @@ class Nuxt {
this.Server = Server this.Server = Server
// Add this.build // Add this.build
build.options.call(this) // Add build options build.options.call(this) // Add build options
this.build = () => co(build.build.bind(this)) this.build = build.build.bind(this)
// Error template // Error template
this.errorTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'error.html'), 'utf8'), { this.errorTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'error.html'), 'utf8'), {
interpolate: /{{([\s\S]+?)}}/g interpolate: /{{([\s\S]+?)}}/g
@ -146,10 +145,7 @@ class Nuxt {
if (this.customFilesWatcher) { if (this.customFilesWatcher) {
this.customFilesWatcher.close() this.customFilesWatcher.close()
} }
return co(function * () { Promise.all(promises).then(() => {
yield promises
})
.then(function () {
if (typeof callback === 'function') callback() if (typeof callback === 'function') callback()
}) })
} }

View File

@ -1,7 +1,6 @@
'use strict' 'use strict'
import ansiHTML from 'ansi-html' import ansiHTML from 'ansi-html'
import co from 'co'
import serialize from 'serialize-javascript' import serialize from 'serialize-javascript'
import { getContext, setAnsiColors, encodeHtml } from './utils' import { getContext, setAnsiColors, encodeHtml } from './utils'
const debug = require('debug')('nuxt:render') const debug = require('debug')('nuxt:render')
@ -9,7 +8,7 @@ const debug = require('debug')('nuxt:render')
debug.color = 4 debug.color = 4
setAnsiColors(ansiHTML) setAnsiColors(ansiHTML)
export function render (req, res) { export async function render (req, res) {
if (!this.renderer && !this.dev) { if (!this.renderer && !this.dev) {
console.error('> No build files found, please run `nuxt build` before launching `nuxt start`') // eslint-disable-line no-console console.error('> No build files found, please run `nuxt build` before launching `nuxt start`') // eslint-disable-line no-console
process.exit(1) process.exit(1)
@ -18,21 +17,22 @@ export function render (req, res) {
if (!this.renderer || !this.appTemplate) { if (!this.renderer || !this.appTemplate) {
return new Promise((resolve) => { return new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
debug('Waiting for renderer to be ready')
resolve(this.render(req, res)) resolve(this.render(req, res))
}, 1000) }, 1000)
}) })
} }
const self = this const self = this
const context = getContext(req, res) const context = getContext(req, res)
return co(function * () { res.statusCode = 200
res.statusCode = 200 try {
if (self.dev) { if (self.dev) {
// Call webpack middleware only in development // Call webpack middleware only in development
yield self.webpackDevMiddleware(req, res) await self.webpackDevMiddleware(req, res)
yield self.webpackHotMiddleware(req, res) await self.webpackHotMiddleware(req, res)
} }
if (!self.dev && self.options.performance.gzip) { if (!self.dev && self.options.performance.gzip) {
yield self.gzipMiddleware(req, res) await self.gzipMiddleware(req, res)
} }
// If base in req.url, remove it for the middleware and vue-router // If base in req.url, remove it for the middleware and vue-router
if (self.options.router.base !== '/' && req.url.indexOf(self.options.router.base) === 0) { if (self.options.router.base !== '/' && req.url.indexOf(self.options.router.base) === 0) {
@ -40,25 +40,21 @@ export function render (req, res) {
req.url = req.url.replace(self.options.router.base, '/') req.url = req.url.replace(self.options.router.base, '/')
} }
// Serve static/ files // Serve static/ files
yield self.serveStatic(req, res) await self.serveStatic(req, res)
// Serve .nuxt/dist/ files (only for production) // Serve .nuxt/dist/ files (only for production)
if (!self.dev && req.url.indexOf(self.options.build.publicPath) === 0) { if (!self.dev && req.url.indexOf(self.options.build.publicPath) === 0) {
const url = req.url const url = req.url
req.url = req.url.replace(self.options.build.publicPath, '/') req.url = req.url.replace(self.options.build.publicPath, '/')
yield self.serveStaticNuxt(req, res) await self.serveStaticNuxt(req, res)
/* istanbul ignore next */ /* istanbul ignore next */
req.url = url req.url = url
} }
})
.then(() => {
/* istanbul ignore if */ /* istanbul ignore if */
if (this.dev && req.url.indexOf(self.options.build.publicPath) === 0 && req.url.includes('.hot-update.json')) { if (this.dev && req.url.indexOf(self.options.build.publicPath) === 0 && req.url.includes('.hot-update.json')) {
res.statusCode = 404 res.statusCode = 404
return { html: '' } return {html: ''}
} }
return this.renderRoute(req.url, context) const {html, error, redirected} = await this.renderRoute(req.url, context)
})
.then(({ html, error, redirected }) => {
if (redirected) { if (redirected) {
return html return html
} }
@ -69,8 +65,7 @@ export function render (req, res) {
res.setHeader('Content-Length', Buffer.byteLength(html)) res.setHeader('Content-Length', Buffer.byteLength(html))
res.end(html, 'utf8') res.end(html, 'utf8')
return html return html
}) } catch (err) {
.catch((err) => {
/* istanbul ignore if */ /* istanbul ignore if */
if (context.redirected) { if (context.redirected) {
console.error(err) // eslint-disable-line no-console console.error(err) // eslint-disable-line no-console
@ -85,41 +80,39 @@ export function render (req, res) {
res.setHeader('Content-Length', Buffer.byteLength(html)) res.setHeader('Content-Length', Buffer.byteLength(html))
res.end(html, 'utf8') res.end(html, 'utf8')
return err return err
}) }
} }
export function renderRoute (url, context = {}) { export async function renderRoute (url, context = {}) {
debug(`Rendering url ${url}`) debug(`Rendering url ${url}`)
// Add url and isSever to the context // Add url and isSever to the context
context.url = url context.url = url
context.isServer = true context.isServer = true
// Call renderToString from the bundleRenderer and generate the HTML (will update the context as well) // Call renderToString from the bundleRenderer and generate the HTML (will update the context as well)
const self = this const self = this
return co(function * () { let APP = await self.renderToString(context)
let APP = yield self.renderToString(context) if (!context.nuxt.serverRendered) {
if (!context.nuxt.serverRendered) { APP = '<div id="__nuxt"></div>'
APP = '<div id="__nuxt"></div>' }
} const m = context.meta.inject()
const m = context.meta.inject() let HEAD = m.meta.text() + m.title.text() + m.link.text() + m.style.text() + m.script.text() + m.noscript.text()
let HEAD = m.meta.text() + m.title.text() + m.link.text() + m.style.text() + m.script.text() + m.noscript.text() if (self.options.router.base !== '/') {
if (self.options.router.base !== '/') { HEAD += `<base href="${self.options.router.base}">`
HEAD += `<base href="${self.options.router.base}">` }
} HEAD += context.renderResourceHints() + context.renderStyles()
HEAD += context.renderResourceHints() + context.renderStyles() APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })}</script>`
APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })}</script>` APP += context.renderScripts()
APP += context.renderScripts() const html = self.appTemplate({
const html = self.appTemplate({ HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(), BODY_ATTRS: m.bodyAttrs.text(),
BODY_ATTRS: m.bodyAttrs.text(), HEAD,
HEAD, APP
APP
})
return {
html,
error: context.nuxt.error,
redirected: context.redirected
}
}) })
return {
html,
error: context.nuxt.error,
redirected: context.redirected
}
} }
// Function used to do dom checking via jsdom // Function used to do dom checking via jsdom