Refactor generateRoutesAndFiles

This commit is contained in:
Pooya Parsa 2017-05-18 13:15:15 +04:30
parent 3f84161811
commit a70fc016e4
2 changed files with 84 additions and 83 deletions

View File

@ -9,8 +9,8 @@ import webpack from 'webpack'
import PostCompilePlugin from 'post-compile-webpack-plugin'
import serialize from 'serialize-javascript'
import { createBundleRenderer } from 'vue-server-renderer'
import { join, resolve, sep } from 'path'
import { isUrl } from './utils'
import { join, resolve, basename, dirname } from 'path'
import { isUrl, r } from './utils'
import clientWebpackConfig from './webpack/client.config.js'
import serverWebpackConfig from './webpack/server.config.js'
const debug = require('debug')('nuxt:build')
@ -20,27 +20,9 @@ const utimes = pify(fs.utimes)
const writeFile = pify(fs.writeFile)
const mkdirp = pify(fs.mkdirp)
const glob = pify(require('glob'))
const reqSep = /\//g
const sysSep = _.escapeRegExp(sep)
const normalize = string => string.replace(reqSep, sysSep)
const wp = function (p) {
/* istanbul ignore if */
if (/^win/.test(process.platform)) {
p = p.replace(/\\/g, '\\\\')
}
return p
}
const r = function () {
let args = Array.from(arguments)
if (_.last(args).includes('~')) {
return wp(_.last(args))
}
args = args.map(normalize)
return wp(resolve.apply(null, args))
}
let webpackStats = 'none'
// force green color
debug.color = 2
debug.color = 2 // force green color
const defaults = {
analyze: false,
@ -163,17 +145,8 @@ function addAppTemplate () {
}
async function generateRoutesAndFiles () {
debug('Generating routes...')
// Layouts
let layouts = {}
const layoutsFiles = await glob('layouts/*.vue', { cwd: this.srcDir })
layoutsFiles.forEach((file) => {
let name = file.split('/').slice(-1)[0].replace('.vue', '')
if (name === 'error') return
layouts[name] = r(this.srcDir, file)
})
const files = await glob('pages/**/*.vue', { cwd: this.srcDir })
// Interpret and move template files to .nuxt/
debug('Generating files...')
// -- Templates --
let templatesFiles = [
'App.vue',
'client.js',
@ -188,9 +161,8 @@ async function generateRoutesAndFiles () {
'components/nuxt-link.js',
'components/nuxt.vue'
]
this.options.store = fs.existsSync(join(this.srcDir, 'store'))
let templateVars = {
nuxt: this.options,
const templateVars = {
options: this.options,
uniqBy: _.uniqBy,
isDev: this.dev,
router: {
@ -203,7 +175,7 @@ async function generateRoutesAndFiles () {
env: this.options.env,
head: this.options.head,
middleware: fs.existsSync(join(this.srcDir, 'middleware')),
store: this.options.store,
store: this.options.store || fs.existsSync(join(this.srcDir, 'store')),
css: this.options.css,
plugins: this.options.plugins.map((p) => {
if (typeof p === 'string') {
@ -212,80 +184,107 @@ async function generateRoutesAndFiles () {
return { src: r(this.srcDir, p.src), ssr: (p.ssr !== false), injectAs: (p.injectAs || false) }
}),
appPath: './App.vue',
layouts: layouts,
layouts: Object.assign({}, this.options.layouts),
loading: (typeof this.options.loading === 'string' ? r(this.srcDir, this.options.loading) : this.options.loading),
transition: this.options.transition,
components: {
ErrorPage: null
ErrorPage: this.options.ErrorPage ? r(this.options.ErrorPage) : null
}
}
// -- Layouts --
if (fs.existsSync(resolve(this.srcDir, 'layouts'))) {
const layoutsFiles = await glob('layouts/*.vue', {cwd: this.srcDir})
layoutsFiles.forEach((file) => {
let name = file.split('/').slice(-1)[0].replace('.vue', '')
if (name === 'error') return
templateVars.layouts[name] = r(this.srcDir, file)
})
if (layoutsFiles.includes('layouts/error.vue')) {
templateVars.components.ErrorPage = r(this.srcDir, 'layouts/error.vue')
}
}
// If no default layout, create its folder and add the default folder
if (!templateVars.layouts.default) {
await mkdirp(r(this.dir, '.nuxt/layouts'))
templatesFiles.push('layouts/default.vue')
templateVars.layouts.default = r(__dirname, 'app', 'layouts', 'default.vue')
}
// -- Routes --
debug('Generating routes...')
// Format routes for the lib/app/router.js template
templateVars.router.routes = createRoutes(files, this.srcDir)
if (fs.existsSync(resolve(this.srcDir, 'pages'))) {
const files = await glob('pages/**/*.vue', {cwd: this.srcDir})
templateVars.router.routes = createRoutes(files, this.srcDir)
}
if (typeof this.options.router.extendRoutes === 'function') {
// let the user extend the routes
this.options.router.extendRoutes.call(this, templateVars.router.routes, r)
}
// Routes for Generate command
// Routes for generate command
this.routes = flatRoutes(templateVars.router.routes)
debug('Generating files...')
if (layoutsFiles.includes('layouts/error.vue')) {
templateVars.components.ErrorPage = r(this.srcDir, 'layouts/error.vue')
}
// If no default layout, create its folder and add the default folder
if (!layouts.default) {
await mkdirp(r(this.dir, '.nuxt/layouts'))
templatesFiles.push('layouts/default.vue')
layouts.default = r(__dirname, 'app', 'layouts', 'default.vue')
}
// -- Store --
// Add store if needed
if (this.options.store) {
templatesFiles.push('store.js')
}
// Resolve template files
const customTemplateFiles = this.options.build.templates.map(t => t.dst || basename(t.src || t))
templatesFiles = templatesFiles.map(file => {
// Allow override anything using a file with same name in srcDir/app
// Allow override templates using a file with same name in ${srcDir}/app
const customPath = r(this.srcDir, 'app', file)
const customFileExists = fs.existsSync(customPath)
// Skip if custom file was already provided in build.templates[]
if (customTemplateFiles.indexOf(file) !== -1 && !customFileExists) {
return
}
return {
src: customFileExists ? customPath : r(__dirname, 'app', file),
dst: file,
custom: customFileExists
}
})
// Add external template files (used in modules)
if (Array.isArray(this.options.build.templates)) {
templatesFiles = templatesFiles.concat(this.options.build.templates.map(t => {
return Object.assign({custom: true}, t)
}))
}
let moveTemplates = templatesFiles.map(({src, dst, options, custom}) => {
}).filter(i => !!i)
// -- Custom templates --
// Add custom template files
templatesFiles = templatesFiles.concat(this.options.build.templates.map(t => {
return Object.assign({
src: r(this.dir, t.src || t),
dst: t.dst || basename(t.src || t),
custom: true
}, t)
}))
// Interpret and move template files to .nuxt/
return templatesFiles.map(async ({src, dst, options, custom}) => {
// Add template to watchers
this.options.build.watch.push(src)
// Render template to dst
return readFile(src, 'utf8')
.then((fileContent) => {
const template = _.template(fileContent, {
imports: {
serialize,
hash
}
})
const content = template(Object.assign({}, templateVars, {
options: options || {},
custom,
src,
dst
}))
const path = r(this.dir, '.nuxt', dst)
return writeFile(path, content, 'utf8')
.then(() => {
// Fix webpack loop (https://github.com/webpack/watchpack/issues/25#issuecomment-287789288)
const dateFS = Date.now() / 1000 - 30
return utimes(path, dateFS, dateFS)
})
const fileContent = await readFile(src, 'utf8')
const template = _.template(fileContent, {
imports: {
serialize,
hash
}
})
const content = template(Object.assign({}, templateVars, {
options: options || {},
custom,
src,
dst
}))
const path = r(this.dir, '.nuxt', dst)
// Ensure parent dir exits
await mkdirp(dirname(path))
// Write file
await writeFile(path, content, 'utf8')
// Fix webpack loop (https://github.com/webpack/watchpack/issues/25#issuecomment-287789288)
const dateFS = Date.now() / 1000 - 30
return utimes(path, dateFS, dateFS)
})
await moveTemplates
}
function createRoutes (files, srcDir) {

View File

@ -27,7 +27,9 @@ class Nuxt {
plugins: [],
css: [],
modules: [],
layouts: {},
serverMiddlewares: [],
ErrorPage: null,
cache: false,
loading: {
color: 'black',
@ -148,7 +150,7 @@ class Nuxt {
if (this.customFilesWatcher) {
this.customFilesWatcher.close()
}
Promise.all(promises).then(() => {
return Promise.all(promises).then(() => {
if (typeof callback === 'function') callback()
})
}