refactor(core): use strict mjs

This commit is contained in:
Pooya Parsa 2018-03-16 22:41:24 +03:30
parent ec616f109b
commit 6234ae84c0
25 changed files with 164 additions and 163 deletions

View File

@ -1,12 +1,12 @@
import { promisify } from 'util' import util from 'util'
import _ from 'lodash' import _ from 'lodash'
import chokidar from 'chokidar' import chokidar from 'chokidar'
import { remove, readFile, writeFile, mkdirp, existsSync } from 'fs-extra' import fsExtra from 'fs-extra'
import fs from 'fs' import fs from 'fs'
import hash from 'hash-sum' import hash from 'hash-sum'
import webpack from 'webpack' import webpack from 'webpack'
import serialize from 'serialize-javascript' import serialize from 'serialize-javascript'
import { join, resolve, basename, extname, dirname } from 'path' import path from 'path'
import MFS from 'memory-fs' import MFS from 'memory-fs'
import webpackDevMiddleware from 'webpack-dev-middleware' import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware' import webpackHotMiddleware from 'webpack-hot-middleware'
@ -14,14 +14,14 @@ import Debug from 'debug'
import Glob from 'glob' import Glob from 'glob'
import { r, wp, wChunk, createRoutes, parallel, relativeTo, waitFor, createSpinner } from '../common/utils' import { r, wp, wChunk, createRoutes, parallel, relativeTo, waitFor, createSpinner } from '../common/utils'
import Options from '../common/options' import Options from '../common/options'
import clientWebpackConfig from './webpack/client.config.js' import clientWebpackConfig from './webpack/client.config'
import serverWebpackConfig from './webpack/server.config.js' import serverWebpackConfig from './webpack/server.config'
import upath from 'upath' import upath from 'upath'
const debug = Debug('nuxt:build') const debug = Debug('nuxt:build')
debug.color = 2 // Force green color debug.color = 2 // Force green color
const glob = promisify(Glob) const glob = util.promisify(Glob)
export default class Builder { export default class Builder {
constructor(nuxt) { constructor(nuxt) {
@ -61,7 +61,7 @@ export default class Builder {
return _.uniqBy( return _.uniqBy(
this.options.plugins.map((p, i) => { this.options.plugins.map((p, i) => {
if (typeof p === 'string') p = { src: p } if (typeof p === 'string') p = { src: p }
const pluginBaseName = basename(p.src, extname(p.src)).replace( const pluginBaseName = path.basename(p.src, path.extname(p.src)).replace(
/[^a-zA-Z?\d\s:]/g, /[^a-zA-Z?\d\s:]/g,
'' ''
) )
@ -104,9 +104,9 @@ export default class Builder {
// Check if pages dir exists and warn if not // Check if pages dir exists and warn if not
this._nuxtPages = typeof this.options.build.createRoutes !== 'function' this._nuxtPages = typeof this.options.build.createRoutes !== 'function'
if (this._nuxtPages) { if (this._nuxtPages) {
if (!existsSync(join(this.options.srcDir, this.options.dir.pages))) { if (!fsExtra.existsSync(path.join(this.options.srcDir, this.options.dir.pages))) {
let dir = this.options.srcDir let dir = this.options.srcDir
if (existsSync(join(this.options.srcDir, '..', this.options.dir.pages))) { if (fsExtra.existsSync(path.join(this.options.srcDir, '..', this.options.dir.pages))) {
throw new Error( throw new Error(
`No \`${this.options.dir.pages}\` directory found in ${dir}. Did you mean to run \`nuxt\` in the parent (\`../\`) directory?` `No \`${this.options.dir.pages}\` directory found in ${dir}. Did you mean to run \`nuxt\` in the parent (\`../\`) directory?`
) )
@ -123,10 +123,10 @@ export default class Builder {
debug(`App root: ${this.options.srcDir}`) debug(`App root: ${this.options.srcDir}`)
// Create .nuxt/, .nuxt/components and .nuxt/dist folders // Create .nuxt/, .nuxt/components and .nuxt/dist folders
await remove(r(this.options.buildDir)) await fsExtra.remove(r(this.options.buildDir))
await mkdirp(r(this.options.buildDir, 'components')) await fsExtra.mkdirp(r(this.options.buildDir, 'components'))
if (!this.options.dev) { if (!this.options.dev) {
await mkdirp(r(this.options.buildDir, 'dist')) await fsExtra.mkdirp(r(this.options.buildDir, 'dist'))
} }
// Generate routes and interpret the template files // Generate routes and interpret the template files
@ -215,7 +215,7 @@ export default class Builder {
router: this.options.router, router: this.options.router,
env: this.options.env, env: this.options.env,
head: this.options.head, head: this.options.head,
middleware: existsSync(join(this.options.srcDir, this.options.dir.middleware)), middleware: fsExtra.existsSync(path.join(this.options.srcDir, this.options.dir.middleware)),
store: this.options.store, store: this.options.store,
css: this.options.css, css: this.options.css,
plugins: this.plugins, plugins: this.plugins,
@ -237,7 +237,7 @@ export default class Builder {
} }
// -- Layouts -- // -- Layouts --
if (existsSync(resolve(this.options.srcDir, this.options.dir.layouts))) { if (fsExtra.existsSync(path.resolve(this.options.srcDir, this.options.dir.layouts))) {
const layoutsFiles = await glob(`${this.options.dir.layouts}/**/*.{vue,js}`, { const layoutsFiles = await glob(`${this.options.dir.layouts}/**/*.{vue,js}`, {
cwd: this.options.srcDir, cwd: this.options.srcDir,
ignore: this.options.ignore ignore: this.options.ignore
@ -269,7 +269,7 @@ export default class Builder {
} }
// 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 (!templateVars.layouts.default) { if (!templateVars.layouts.default) {
await mkdirp(r(this.options.buildDir, 'layouts')) await fsExtra.mkdirp(r(this.options.buildDir, 'layouts'))
templatesFiles.push('layouts/default.vue') templatesFiles.push('layouts/default.vue')
templateVars.layouts.default = './layouts/default.vue' templateVars.layouts.default = './layouts/default.vue'
} }
@ -330,7 +330,7 @@ export default class Builder {
// Resolve template files // Resolve template files
const customTemplateFiles = this.options.build.templates.map( const customTemplateFiles = this.options.build.templates.map(
t => t.dst || basename(t.src || t) t => t.dst || path.basename(t.src || t)
) )
templatesFiles = templatesFiles templatesFiles = templatesFiles
@ -341,7 +341,7 @@ export default class Builder {
} }
// Allow override templates 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.options.srcDir, 'app', file) const customPath = r(this.options.srcDir, 'app', file)
const customFileExists = existsSync(customPath) const customFileExists = fsExtra.existsSync(customPath)
return { return {
src: customFileExists ? customPath : r(this.options.nuxtAppDir, file), src: customFileExists ? customPath : r(this.options.nuxtAppDir, file),
@ -358,7 +358,7 @@ export default class Builder {
return Object.assign( return Object.assign(
{ {
src: r(this.options.srcDir, t.src || t), src: r(this.options.srcDir, t.src || t),
dst: t.dst || basename(t.src || t), dst: t.dst || path.basename(t.src || t),
custom: true custom: true
}, },
t t
@ -368,7 +368,7 @@ export default class Builder {
// -- Loading indicator -- // -- Loading indicator --
if (this.options.loadingIndicator.name) { if (this.options.loadingIndicator.name) {
const indicatorPath1 = resolve( const indicatorPath1 = path.resolve(
this.options.nuxtAppDir, this.options.nuxtAppDir,
'views/loading', 'views/loading',
this.options.loadingIndicator.name + '.html' this.options.loadingIndicator.name + '.html'
@ -376,9 +376,9 @@ export default class Builder {
const indicatorPath2 = this.nuxt.resolveAlias( const indicatorPath2 = this.nuxt.resolveAlias(
this.options.loadingIndicator.name this.options.loadingIndicator.name
) )
const indicatorPath = existsSync(indicatorPath1) const indicatorPath = fsExtra.existsSync(indicatorPath1)
? indicatorPath1 ? indicatorPath1
: existsSync(indicatorPath2) ? indicatorPath2 : null : fsExtra.existsSync(indicatorPath2) ? indicatorPath2 : null
if (indicatorPath) { if (indicatorPath) {
templatesFiles.push({ templatesFiles.push({
src: indicatorPath, src: indicatorPath,
@ -408,7 +408,7 @@ export default class Builder {
// Add template to watchers // Add template to watchers
this.options.build.watch.push(src) this.options.build.watch.push(src)
// Render template to dst // Render template to dst
const fileContent = await readFile(src, 'utf8') const fileContent = await fsExtra.readFile(src, 'utf8')
let content let content
try { try {
const template = _.template(fileContent, { const template = _.template(fileContent, {
@ -435,11 +435,11 @@ export default class Builder {
/* istanbul ignore next */ /* istanbul ignore next */
throw new Error(`Could not compile template ${src}: ${err.message}`) throw new Error(`Could not compile template ${src}: ${err.message}`)
} }
const path = r(this.options.buildDir, dst) const _path = r(this.options.buildDir, dst)
// Ensure parent dir exits // Ensure parent dir exits
await mkdirp(dirname(path)) await fsExtra.mkdirp(path.dirname(_path))
// Write file // Write file
await writeFile(path, content, 'utf8') await fsExtra.writeFile(_path, content, 'utf8')
}) })
) )
@ -544,7 +544,7 @@ export default class Builder {
debug('Adding webpack middleware...') debug('Adding webpack middleware...')
// Create webpack dev middleware // Create webpack dev middleware
this.webpackDevMiddleware = promisify( this.webpackDevMiddleware = util.promisify(
webpackDevMiddleware( webpackDevMiddleware(
compiler, compiler,
Object.assign( Object.assign(
@ -559,9 +559,9 @@ export default class Builder {
) )
) )
this.webpackDevMiddleware.close = promisify(this.webpackDevMiddleware.close) this.webpackDevMiddleware.close = util.promisify(this.webpackDevMiddleware.close)
this.webpackHotMiddleware = promisify( this.webpackHotMiddleware = util.promisify(
webpackHotMiddleware( webpackHotMiddleware(
compiler, compiler,
Object.assign( Object.assign(
@ -644,9 +644,9 @@ export default class Builder {
// TODO: remove ignore when generateConfig enabled again // TODO: remove ignore when generateConfig enabled again
async generateConfig() /* istanbul ignore next */ { async generateConfig() /* istanbul ignore next */ {
const config = resolve(this.options.buildDir, 'build.config.js') const config = path.resolve(this.options.buildDir, 'build.config.js')
const options = _.omit(this.options, Options.unsafeKeys) const options = _.omit(this.options, Options.unsafeKeys)
await writeFile( await fsExtra.writeFile(
config, config,
`export default ${JSON.stringify(options, null, ' ')}`, `export default ${JSON.stringify(options, null, ' ')}`,
'utf8' 'utf8'

View File

@ -1,8 +1,8 @@
import _ from 'lodash' import _ from 'lodash'
import { resolve, join, dirname, sep } from 'path' import path from 'path'
import { minify } from 'html-minifier' import htmlMinifier from 'html-minifier'
import Chalk from 'chalk' import Chalk from 'chalk'
import { copy, remove, writeFile, mkdirp, removeSync, existsSync } from 'fs-extra' import fsExtra from 'fs-extra'
import { isUrl, promisifyRoute, waitFor, flatRoutes, printWarn, createSpinner } from '../common/utils' import { isUrl, promisifyRoute, waitFor, flatRoutes, printWarn, createSpinner } from '../common/utils'
export default class Generator { export default class Generator {
@ -12,10 +12,10 @@ export default class Generator {
this.builder = builder this.builder = builder
// Set variables // Set variables
this.staticRoutes = resolve(this.options.srcDir, this.options.dir.static) this.staticRoutes = path.resolve(this.options.srcDir, this.options.dir.static)
this.srcBuiltPath = resolve(this.options.buildDir, 'dist') this.srcBuiltPath = path.resolve(this.options.buildDir, 'dist')
this.distPath = resolve(this.options.rootDir, this.options.generate.dir) this.distPath = path.resolve(this.options.rootDir, this.options.generate.dir)
this.distNuxtPath = join( this.distNuxtPath = path.join(
this.distPath, this.distPath,
isUrl(this.options.build.publicPath) ? '' : this.options.build.publicPath isUrl(this.options.build.publicPath) ? '' : this.options.build.publicPath
) )
@ -127,7 +127,7 @@ export default class Generator {
if (isHandled) { if (isHandled) {
line += Chalk.grey(JSON.stringify(error, undefined, 2) + '\n') line += Chalk.grey(JSON.stringify(error, undefined, 2) + '\n')
} else { } else {
line += Chalk.grey(error.toString()) line += Chalk.grey(error.stack)
} }
return line return line
@ -141,36 +141,36 @@ export default class Generator {
// Disable SPA fallback if value isn't true or a string // Disable SPA fallback if value isn't true or a string
if (fallback !== true && typeof fallback !== 'string') return if (fallback !== true && typeof fallback !== 'string') return
const fallbackPath = join(this.distPath, fallback) const fallbackPath = path.join(this.distPath, fallback)
// Prevent conflicts // Prevent conflicts
if (existsSync(fallbackPath)) { if (fsExtra.existsSync(fallbackPath)) {
printWarn(`SPA fallback was configured, but the configured path (${fallbackPath}) already exists.`) printWarn(`SPA fallback was configured, but the configured path (${fallbackPath}) already exists.`)
return return
} }
// Render and write the SPA template to the fallback path // Render and write the SPA template to the fallback path
const { html } = await this.nuxt.renderRoute('/', { spa: true }) const { html } = await this.nuxt.renderRoute('/', { spa: true })
await writeFile(fallbackPath, html, 'utf8') await fsExtra.writeFile(fallbackPath, html, 'utf8')
} }
async initDist() { async initDist() {
// Clean destination folder // Clean destination folder
await remove(this.distPath) await fsExtra.remove(this.distPath)
await this.nuxt.callHook('generate:distRemoved', this) await this.nuxt.callHook('generate:distRemoved', this)
// Copy static and built files // Copy static and built files
/* istanbul ignore if */ /* istanbul ignore if */
if (existsSync(this.staticRoutes)) { if (fsExtra.existsSync(this.staticRoutes)) {
await copy(this.staticRoutes, this.distPath) await fsExtra.copy(this.staticRoutes, this.distPath)
} }
await copy(this.srcBuiltPath, this.distNuxtPath) await fsExtra.copy(this.srcBuiltPath, this.distNuxtPath)
// Add .nojekyll file to let Github Pages add the _nuxt/ folder // Add .nojekyll file to let Github Pages add the _nuxt/ folder
// https://help.github.com/articles/files-that-start-with-an-underscore-are-missing/ // https://help.github.com/articles/files-that-start-with-an-underscore-are-missing/
const nojekyllPath = resolve(this.distPath, '.nojekyll') const nojekyllPath = path.resolve(this.distPath, '.nojekyll')
writeFile(nojekyllPath, '') fsExtra.writeFile(nojekyllPath, '')
// Cleanup SSR related files // Cleanup SSR related files
const extraFiles = [ const extraFiles = [
@ -178,11 +178,11 @@ export default class Generator {
'index.ssr.html', 'index.ssr.html',
'server-bundle.json', 'server-bundle.json',
'vue-ssr-client-manifest.json' 'vue-ssr-client-manifest.json'
].map(file => resolve(this.distNuxtPath, file)) ].map(file => path.resolve(this.distNuxtPath, file))
extraFiles.forEach(file => { extraFiles.forEach(file => {
if (existsSync(file)) { if (fsExtra.existsSync(file)) {
removeSync(file) fsExtra.removeSync(file)
} }
}) })
@ -238,7 +238,7 @@ export default class Generator {
if (this.options.generate.minify) { if (this.options.generate.minify) {
try { try {
html = minify(html, this.options.generate.minify) html = htmlMinifier.minify(html, this.options.generate.minify)
} catch (err) /* istanbul ignore next */ { } catch (err) /* istanbul ignore next */ {
const minifyErr = new Error( const minifyErr = new Error(
`HTML minification failed. Make sure the route generates valid HTML. Failed HTML:\n ${html}` `HTML minification failed. Make sure the route generates valid HTML. Failed HTML:\n ${html}`
@ -250,22 +250,22 @@ export default class Generator {
let path let path
if (this.options.generate.subFolders) { if (this.options.generate.subFolders) {
path = join(route, sep, 'index.html') // /about -> /about/index.html path = path.join(route, path.sep, 'index.html') // /about -> /about/index.html
path = path === '/404/index.html' ? '/404.html' : path // /404 -> /404.html path = path === '/404/index.html' ? '/404.html' : path // /404 -> /404.html
} else { } else {
path = path =
route.length > 1 ? join(sep, route + '.html') : join(sep, 'index.html') route.length > 1 ? path.join(path.sep, route + '.html') : path.join(path.sep, 'index.html')
} }
// Call hook to let user update the path & html // Call hook to let user update the path & html
const page = { route, path, html } const page = { route, path, html }
await this.nuxt.callHook('generate:page', page) await this.nuxt.callHook('generate:page', page)
page.path = join(this.distPath, page.path) page.path = path.join(this.distPath, page.path)
// Make sure the sub folders are created // Make sure the sub folders are created
await mkdirp(dirname(page.path)) await fsExtra.mkdirp(path.dirname(page.path))
await writeFile(page.path, page.html, 'utf8') await fsExtra.writeFile(page.path, page.html, 'utf8')
await this.nuxt.callHook('generate:routeCreated', { await this.nuxt.callHook('generate:routeCreated', {
route, route,

View File

@ -4,8 +4,8 @@ import WarnFixPlugin from './plugins/warnfix'
import ProgressPlugin from './plugins/progress' import ProgressPlugin from './plugins/progress'
import webpack from 'webpack' import webpack from 'webpack'
import { cloneDeep } from 'lodash' import _ from 'lodash'
import { join, resolve } from 'path' import path from 'path'
import { isUrl, urlJoin } from '../../common/utils' import { isUrl, urlJoin } from '../../common/utils'
@ -28,11 +28,11 @@ export default function webpackBaseConfig({ name, isServer }) {
// Used by vue-loader so we can use in templates // Used by vue-loader so we can use in templates
// with <img src="~/assets/nuxt.png"/> // with <img src="~/assets/nuxt.png"/>
configAlias[this.options.dir.assets] = join( configAlias[this.options.dir.assets] = path.join(
this.options.srcDir, this.options.srcDir,
this.options.dir.assets this.options.dir.assets
) )
configAlias[this.options.dir.static] = join( configAlias[this.options.dir.static] = path.join(
this.options.srcDir, this.options.srcDir,
this.options.dir.static this.options.dir.static
) )
@ -45,7 +45,7 @@ export default function webpackBaseConfig({ name, isServer }) {
}, },
optimization: {}, optimization: {},
output: { output: {
path: resolve(this.options.buildDir, 'dist'), path: path.resolve(this.options.buildDir, 'dist'),
filename: this.getFileName('app'), filename: this.getFileName('app'),
chunkFilename: this.getFileName('chunk'), chunkFilename: this.getFileName('chunk'),
publicPath: isUrl(this.options.build.publicPath) publicPath: isUrl(this.options.build.publicPath)
@ -61,10 +61,10 @@ export default function webpackBaseConfig({ name, isServer }) {
extensions: ['.js', '.json', '.vue', '.jsx'], extensions: ['.js', '.json', '.vue', '.jsx'],
alias: Object.assign( alias: Object.assign(
{ {
'~': join(this.options.srcDir), '~': path.join(this.options.srcDir),
'~~': join(this.options.rootDir), '~~': path.join(this.options.rootDir),
'@': join(this.options.srcDir), '@': path.join(this.options.srcDir),
'@@': join(this.options.rootDir) '@@': path.join(this.options.rootDir)
}, },
configAlias configAlias
), ),
@ -159,5 +159,5 @@ export default function webpackBaseConfig({ name, isServer }) {
} }
// Clone deep avoid leaking config between Client and Server // Clone deep avoid leaking config between Client and Server
return cloneDeep(config) return _.cloneDeep(config)
} }

View File

@ -1,14 +1,14 @@
import { each } from 'lodash' import _ from 'lodash'
import webpack from 'webpack' import webpack from 'webpack'
// import VueSSRClientPlugin from 'vue-server-renderer/client-plugin' // import VueSSRClientPlugin from 'vue-server-renderer/client-plugin'
import VueSSRClientPlugin from './plugins/vue/client' import VueSSRClientPlugin from './plugins/vue/client'
import HTMLPlugin from 'html-webpack-plugin' import HTMLPlugin from 'html-webpack-plugin'
import FriendlyErrorsWebpackPlugin from '@nuxtjs/friendly-errors-webpack-plugin' import FriendlyErrorsWebpackPlugin from '@nuxtjs/friendly-errors-webpack-plugin'
import StylishPlugin from 'webpack-stylish' import StylishPlugin from 'webpack-stylish'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' import BundleAnalyzer from 'webpack-bundle-analyzer'
import { resolve } from 'path' import path from 'path'
import Debug from 'debug' import Debug from 'debug'
import base from './base.config.js' import base from './base.config'
const debug = Debug('nuxt:build') const debug = Debug('nuxt:build')
debug.color = 2 // Force green color debug.color = 2 // Force green color
@ -17,11 +17,11 @@ export default function webpackClientConfig() {
let config = base.call(this, { name: 'client', isServer: false }) let config = base.call(this, { name: 'client', isServer: false })
// Entry points // Entry points
config.entry.app = resolve(this.options.buildDir, 'client.js') config.entry.app = path.resolve(this.options.buildDir, 'client.js')
// Env object defined in nuxt.config.js // Env object defined in nuxt.config.js
let env = {} let env = {}
each(this.options.env, (value, key) => { _.each(this.options.env, (value, key) => {
env['process.env.' + key] = env['process.env.' + key] =
['boolean', 'number'].indexOf(typeof value) !== -1 ['boolean', 'number'].indexOf(typeof value) !== -1
? value ? value
@ -128,7 +128,7 @@ export default function webpackClientConfig() {
// Webpack Bundle Analyzer // Webpack Bundle Analyzer
if (this.options.build.analyze) { if (this.options.build.analyze) {
config.plugins.push( config.plugins.push(
new BundleAnalyzerPlugin(Object.assign({}, this.options.build.analyze)) new BundleAnalyzer.BundleAnalyzerPlugin(Object.assign({}, this.options.build.analyze))
) )
} }
} }

View File

@ -1,11 +1,11 @@
import { existsSync } from 'fs' import fs from 'fs'
import { resolve, join } from 'path' import path from 'path'
import { cloneDeep } from 'lodash' import ـ from 'lodash'
import { isPureObject } from '../../common/utils' import { isPureObject } from '../../common/utils'
import createResolver from 'postcss-import-resolver' import createResolver from 'postcss-import-resolver'
export default function postcssConfig() { export default function postcssConfig() {
let config = cloneDeep(this.options.build.postcss) let config = ـ.cloneDeep(this.options.build.postcss)
/* istanbul ignore if */ /* istanbul ignore if */
if (!config) { if (!config) {
@ -22,8 +22,8 @@ export default function postcssConfig() {
'.postcssrc.json', '.postcssrc.json',
'.postcssrc.yaml' '.postcssrc.yaml'
]) { ]) {
if (existsSync(resolve(dir, file))) { if (fs.existsSync(path.resolve(dir, file))) {
const postcssConfigPath = resolve(dir, file) const postcssConfigPath = path.resolve(dir, file)
return { return {
sourceMap: this.options.build.cssSourceMap, sourceMap: this.options.build.cssSourceMap,
config: { config: {
@ -50,10 +50,10 @@ export default function postcssConfig() {
'postcss-import': { 'postcss-import': {
resolve: createResolver({ resolve: createResolver({
alias: { alias: {
'~': join(this.options.srcDir), '~': path.join(this.options.srcDir),
'~~': join(this.options.rootDir), '~~': path.join(this.options.rootDir),
'@': join(this.options.srcDir), '@': path.join(this.options.srcDir),
'@@': join(this.options.rootDir) '@@': path.join(this.options.rootDir)
}, },
modules: [ modules: [
this.options.srcDir, this.options.srcDir,

View File

@ -2,10 +2,10 @@ import webpack from 'webpack'
// import VueSSRServerPlugin from 'vue-server-renderer/server-plugin' // import VueSSRServerPlugin from 'vue-server-renderer/server-plugin'
import VueSSRServerPlugin from './plugins/vue/server' import VueSSRServerPlugin from './plugins/vue/server'
import nodeExternals from 'webpack-node-externals' import nodeExternals from 'webpack-node-externals'
import { each } from 'lodash' import _ from 'lodash'
import { resolve } from 'path' import path from 'path'
import { existsSync } from 'fs' import fs from 'fs'
import base from './base.config.js' import base from './base.config'
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -17,7 +17,7 @@ export default function webpackServerConfig() {
// Env object defined in nuxt.config.js // Env object defined in nuxt.config.js
let env = {} let env = {}
each(this.options.env, (value, key) => { _.each(this.options.env, (value, key) => {
env['process.env.' + key] = env['process.env.' + key] =
['boolean', 'number'].indexOf(typeof value) !== -1 ['boolean', 'number'].indexOf(typeof value) !== -1
? value ? value
@ -30,7 +30,7 @@ export default function webpackServerConfig() {
config = Object.assign(config, { config = Object.assign(config, {
target: 'node', target: 'node',
node: false, node: false,
entry: resolve(this.options.buildDir, 'server.js'), entry: path.resolve(this.options.buildDir, 'server.js'),
output: Object.assign({}, config.output, { output: Object.assign({}, config.output, {
filename: 'server-bundle.js', filename: 'server-bundle.js',
libraryTarget: 'commonjs2' libraryTarget: 'commonjs2'
@ -60,7 +60,7 @@ export default function webpackServerConfig() {
// https://webpack.js.org/configuration/externals/#externals // https://webpack.js.org/configuration/externals/#externals
// https://github.com/liady/webpack-node-externals // https://github.com/liady/webpack-node-externals
this.options.modulesDir.forEach(dir => { this.options.modulesDir.forEach(dir => {
if (existsSync(dir)) { if (fs.existsSync(dir)) {
config.externals.push( config.externals.push(
nodeExternals({ nodeExternals({
// load non-javascript files with extensions, presumably via loaders // load non-javascript files with extensions, presumably via loaders

View File

@ -1,5 +1,5 @@
import ExtractTextPlugin from 'extract-text-webpack-plugin' import ExtractTextPlugin from 'extract-text-webpack-plugin'
import { join } from 'path' import path from 'path'
import postcssConfig from './postcss' import postcssConfig from './postcss'
export default function styleLoader(ext, loaders = [], isVueLoader = false) { export default function styleLoader(ext, loaders = [], isVueLoader = false) {
@ -57,8 +57,8 @@ export default function styleLoader(ext, loaders = [], isVueLoader = false) {
// css-loader // css-loader
// https://github.com/webpack-contrib/css-loader // https://github.com/webpack-contrib/css-loader
const cssLoaderAlias = {} const cssLoaderAlias = {}
cssLoaderAlias[`/${this.options.dir.assets}`] = join(this.options.srcDir, this.options.dir.assets) cssLoaderAlias[`/${this.options.dir.assets}`] = path.join(this.options.srcDir, this.options.dir.assets)
cssLoaderAlias[`/${this.options.dir.static}`] = join(this.options.srcDir, this.options.dir.static) cssLoaderAlias[`/${this.options.dir.static}`] = path.join(this.options.srcDir, this.options.dir.static)
loaders.unshift({ loaders.unshift({
loader: 'css-loader', loader: 'css-loader',

View File

@ -1,4 +1,4 @@
import { resolve } from 'path' import path from 'path'
export default { export default {
mode: 'universal', mode: 'universal',
@ -6,8 +6,8 @@ export default {
debug: undefined, // Will be equal to dev if not provided debug: undefined, // Will be equal to dev if not provided
buildDir: '.nuxt', buildDir: '.nuxt',
cacheDir: '.cache', cacheDir: '.cache',
nuxtDir: resolve(__dirname, '../..'), nuxtDir: path.resolve(__dirname, '../..'),
nuxtAppDir: resolve(__dirname, '../app'), nuxtAppDir: path.resolve(__dirname, '../app'),
modulesDir: ['node_modules'], // ~> relative to options.rootDir modulesDir: ['node_modules'], // ~> relative to options.rootDir
ignorePrefix: '-', ignorePrefix: '-',
ignore: [ ignore: [

View File

@ -1,7 +1,7 @@
import _ from 'lodash' import _ from 'lodash'
import Debug from 'debug' import Debug from 'debug'
import { join, resolve } from 'path' import path from 'path'
import { existsSync, readdirSync } from 'fs' import fs from 'fs'
import { isUrl, isPureObject } from '../common/utils' import { isUrl, isPureObject } from '../common/utils'
@ -59,17 +59,17 @@ Options.from = function (_options) {
// Resolve dirs // Resolve dirs
options.srcDir = hasValue(options.srcDir) options.srcDir = hasValue(options.srcDir)
? resolve(options.rootDir, options.srcDir) ? path.resolve(options.rootDir, options.srcDir)
: options.rootDir : options.rootDir
options.buildDir = resolve(options.rootDir, options.buildDir) options.buildDir = path.resolve(options.rootDir, options.buildDir)
options.cacheDir = resolve(options.rootDir, options.cacheDir) options.cacheDir = path.resolve(options.rootDir, options.cacheDir)
// Populate modulesDir // Populate modulesDir
options.modulesDir = [] options.modulesDir = []
.concat(options.modulesDir) .concat(options.modulesDir)
.concat(join(options.nuxtDir, 'node_modules')) .concat(path.join(options.nuxtDir, 'node_modules'))
.filter(dir => hasValue(dir)) .filter(dir => hasValue(dir))
.map(dir => resolve(options.rootDir, dir)) .map(dir => path.resolve(options.rootDir, dir))
// Sanitize extensions // Sanitize extensions
if (options.extensions.indexOf('js') === -1) { if (options.extensions.indexOf('js') === -1) {
@ -77,9 +77,9 @@ Options.from = function (_options) {
} }
// If app.html is defined, set the template path to the user template // If app.html is defined, set the template path to the user template
options.appTemplatePath = resolve(options.buildDir, 'views/app.template.html') options.appTemplatePath = path.resolve(options.buildDir, 'views/app.template.html')
if (existsSync(join(options.srcDir, 'app.html'))) { if (fs.existsSync(path.join(options.srcDir, 'app.html'))) {
options.appTemplatePath = join(options.srcDir, 'app.html') options.appTemplatePath = path.join(options.srcDir, 'app.html')
} }
// Ignore publicPath on dev // Ignore publicPath on dev
@ -91,8 +91,8 @@ Options.from = function (_options) {
// If store defined, update store options to true unless explicitly disabled // If store defined, update store options to true unless explicitly disabled
if ( if (
options.store !== false && options.store !== false &&
existsSync(join(options.srcDir, options.dir.store)) && fs.existsSync(path.join(options.srcDir, options.dir.store)) &&
readdirSync(join(options.srcDir, options.dir.store)) fs.readdirSync(path.join(options.srcDir, options.dir.store))
.find(filename => filename !== 'README.md' && filename[0] !== '.') .find(filename => filename !== 'README.md' && filename[0] !== '.')
) { ) {
options.store = true options.store = true

View File

@ -1,4 +1,4 @@
import { resolve, relative, sep } from 'path' import path from 'path'
import _ from 'lodash' import _ from 'lodash'
import Chalk from 'chalk' import Chalk from 'chalk'
import ORA from 'ora' import ORA from 'ora'
@ -10,7 +10,7 @@ export const printWarn = function (msg, from) {
} }
export const renderError = function (_error, from) { export const renderError = function (_error, from) {
const errStr = _error.toString() const errStr = _error.stack
const fromStr = from ? Chalk.red(` ${from}`) : '' const fromStr = from ? Chalk.red(` ${from}`) : ''
return '\n' + Chalk.bgRed.black(' ERROR ') + fromStr + '\n\n' + errStr return '\n' + Chalk.bgRed.black(' ERROR ') + fromStr + '\n\n' + errStr
} }
@ -181,7 +181,7 @@ export const wChunk = function wChunk(p = '') {
} }
const reqSep = /\//g const reqSep = /\//g
const sysSep = _.escapeRegExp(sep) const sysSep = _.escapeRegExp(path.sep)
const normalize = string => string.replace(reqSep, sysSep) const normalize = string => string.replace(reqSep, sysSep)
export const r = function r() { export const r = function r() {
@ -192,7 +192,7 @@ export const r = function r() {
return wp(lastArg) return wp(lastArg)
} }
return wp(resolve(...args.map(normalize))) return wp(path.resolve(...args.map(normalize)))
} }
export const relativeTo = function relativeTo() { export const relativeTo = function relativeTo() {
@ -200,36 +200,37 @@ export const relativeTo = function relativeTo() {
let dir = args.shift() let dir = args.shift()
// Resolve path // Resolve path
let path = r(...args) let _path = r(...args)
// Check if path is an alias // Check if path is an alias
if (path.indexOf('@') === 0 || path.indexOf('~') === 0) { if (_path.indexOf('@') === 0 || _path.indexOf('~') === 0) {
return path return _path
} }
// Make correct relative path // Make correct relative path
let rp = relative(dir, path) let rp = path.relative(dir, _path)
if (rp[0] !== '.') { if (rp[0] !== '.') {
rp = './' + rp rp = './' + rp
} }
return wp(rp) return wp(rp)
} }
export const flatRoutes = function flatRoutes(router, path = '', routes = []) { export const flatRoutes = function flatRoutes(router, _path = '', routes = []) {
router.forEach(r => { router.forEach(r => {
if (!r.path.includes(':') && !r.path.includes('*')) { if (!r.path.includes(':') && !r.path.includes('*')) {
/* istanbul ignore if */ /* istanbul ignore if */
if (r.children) { if (r.children) {
if (path === '' && r.path === '/') { if (_path === '' && r.path === '/') {
routes.push('/') routes.push('/')
} }
flatRoutes(r.children, path + r.path + '/', routes) flatRoutes(r.children, _path + r.path + '/', routes)
} else { } else {
path = path.replace(/^\/+$/, '/') _path = _path.replace(/^\/+$/, '/')
routes.push( routes.push(
(r.path === '' && path[path.length - 1] === '/' (r.path === '' && _path[_path.length - 1] === '/'
? path.slice(0, -1) ? _path.slice(0, -1)
: path) + r.path : _path) + r.path
) )
} }
} }

View File

@ -1,6 +1,6 @@
import Youch from '@nuxtjs/youch' import Youch from '@nuxtjs/youch'
import { join, resolve, relative, isAbsolute } from 'path' import path from 'path'
import { readFile } from 'fs-extra' import fs from 'fs-extra'
export default function errorMiddleware(err, req, res, next) { export default function errorMiddleware(err, req, res, next) {
// ensure statusCode, message and name fields // ensure statusCode, message and name fields
@ -83,20 +83,20 @@ async function readSource(frame) {
const searchPath = [ const searchPath = [
this.options.srcDir, this.options.srcDir,
this.options.rootDir, this.options.rootDir,
join(this.options.buildDir, 'dist'), path.join(this.options.buildDir, 'dist'),
this.options.buildDir, this.options.buildDir,
process.cwd() process.cwd()
] ]
// Scan filesystem for real source // Scan filesystem for real source
for (let pathDir of searchPath) { for (let pathDir of searchPath) {
let fullPath = resolve(pathDir, frame.fileName) let fullPath = path.resolve(pathDir, frame.fileName)
let source = await readFile(fullPath, 'utf-8').catch(() => null) let source = await fs.readFile(fullPath, 'utf-8').catch(() => null)
if (source) { if (source) {
frame.contents = source frame.contents = source
frame.fullPath = fullPath frame.fullPath = fullPath
if (isAbsolute(frame.fileName)) { if (path.isAbsolute(frame.fileName)) {
frame.fileName = relative(this.options.rootDir, fullPath) frame.fileName = path.relative(this.options.rootDir, fullPath)
} }
return return
} }

View File

@ -1,16 +1,16 @@
import Debug from 'debug' import Debug from 'debug'
import enableDestroy from 'server-destroy' import enableDestroy from 'server-destroy'
import Module from 'module' import Module from 'module'
import { isPlainObject } from 'lodash' import _ from 'lodash'
import chalk from 'chalk' import chalk from 'chalk'
import { existsSync } from 'fs-extra' import fs from 'fs-extra'
import path from 'path'
import Options from '../common/options' import Options from '../common/options'
import { sequence, printError } from '../common/utils' import { sequence, printError } from '../common/utils'
import { resolve, join } from 'path' import packageJSON from '../../package.json'
import { version } from '../../package.json'
import ModuleContainer from './module' import ModuleContainer from './module'
import Renderer from './renderer' import Renderer from './renderer'
import { requireModule } from '../common/module' import moduleUtil from '../common/module'
const debug = Debug('nuxt:') const debug = Debug('nuxt:')
debug.color = 5 debug.color = 5
@ -42,7 +42,7 @@ export default class Nuxt {
} }
static get version() { static get version() {
return version return packageJSON.version
} }
async ready() { async ready() {
@ -51,7 +51,7 @@ export default class Nuxt {
} }
// Add hooks // Add hooks
if (isPlainObject(this.options.hooks)) { if (_.isPlainObject(this.options.hooks)) {
this.addObjectHooks(this.options.hooks) this.addObjectHooks(this.options.hooks)
} else if (typeof this.options.hooks === 'function') { } else if (typeof this.options.hooks === 'function') {
this.options.hooks(this.hook) this.options.hooks(this.hook)
@ -157,22 +157,22 @@ export default class Nuxt {
}) })
} }
resolveAlias(path) { resolveAlias(_path) {
if (path.indexOf('@@') === 0 || path.indexOf('~~') === 0) { if (_path.indexOf('@@') === 0 || _path.indexOf('~~') === 0) {
return join(this.options.rootDir, path.substr(2)) return path.join(this.options.rootDir, _path.substr(2))
} }
if (path.indexOf('@') === 0 || path.indexOf('~') === 0) { if (_path.indexOf('@') === 0 || _path.indexOf('~') === 0) {
return join(this.options.srcDir, path.substr(1)) return path.join(this.options.srcDir, _path.substr(1))
} }
return resolve(this.options.srcDir, path) return path.resolve(this.options.srcDir, _path)
} }
resolvePath(path) { resolvePath(_path) {
// Try to resolve using NPM resolve path first // Try to resolve using NPM resolve path first
try { try {
const resolvedPath = Module._resolveFilename(path, { const resolvedPath = Module._resolveFilename(_path, {
paths: this.options.modulesDir paths: this.options.modulesDir
}) })
return resolvedPath return resolvedPath
@ -182,23 +182,23 @@ export default class Nuxt {
} }
} }
let _path = this.resolveAlias(path) let __path = this.resolveAlias(_path)
if (existsSync(_path)) { if (fs.existsSync(__path)) {
return _path return __path
} }
for (let ext of this.options.extensions) { for (let ext of this.options.extensions) {
if (existsSync(_path + '.' + ext)) { if (fs.existsSync(_path + '.' + ext)) {
return _path + '.' + ext return _path + '.' + ext
} }
} }
throw new Error(`Cannot resolve "${path}" from "${_path}"`) throw new Error(`Cannot resolve "${_path}" from "${__path}"`)
} }
requireModule(name) { requireModule(name) {
return requireModule(this.resolvePath(name)) return moduleUtil.requireModule(this.resolvePath(name))
} }
async close(callback) { async close(callback) {

View File

@ -3,9 +3,9 @@ import serialize from 'serialize-javascript'
import serveStatic from 'serve-static' import serveStatic from 'serve-static'
import compression from 'compression' import compression from 'compression'
import _ from 'lodash' import _ from 'lodash'
import { join, resolve } from 'path' import path from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import { createBundleRenderer } from 'vue-server-renderer' import vueServerRenderer from 'vue-server-renderer'
import Debug from 'debug' import Debug from 'debug'
import connect from 'connect' import connect from 'connect'
import launchMiddleware from 'launch-editor-middleware' import launchMiddleware from 'launch-editor-middleware'
@ -66,18 +66,18 @@ export default class Renderer {
} }
async loadResources(_fs = fs) { async loadResources(_fs = fs) {
let distPath = resolve(this.options.buildDir, 'dist') let distPath = path.resolve(this.options.buildDir, 'dist')
let updated = [] let updated = []
resourceMap.forEach(({ key, fileName, transform }) => { resourceMap.forEach(({ key, fileName, transform }) => {
let rawKey = '$$' + key let rawKey = '$$' + key
const path = join(distPath, fileName) const _path = path.join(distPath, fileName)
let rawData, data let rawData, data
if (!_fs.existsSync(path)) { if (!_fs.existsSync(_path)) {
return // Resource not exists return // Resource not exists
} }
rawData = _fs.readFileSync(path, 'utf8') rawData = _fs.readFileSync(_path, 'utf8')
if (!rawData || rawData === this.resources[rawKey]) { if (!rawData || rawData === this.resources[rawKey]) {
return // No changes return // No changes
} }
@ -92,7 +92,7 @@ export default class Renderer {
}) })
// Reload error template // Reload error template
const errorTemplatePath = resolve(this.options.buildDir, 'views/error.html') const errorTemplatePath = path.resolve(this.options.buildDir, 'views/error.html')
if (fs.existsSync(errorTemplatePath)) { if (fs.existsSync(errorTemplatePath)) {
this.resources.errorTemplate = parseTemplate( this.resources.errorTemplate = parseTemplate(
fs.readFileSync(errorTemplatePath, 'utf8') fs.readFileSync(errorTemplatePath, 'utf8')
@ -100,7 +100,7 @@ export default class Renderer {
} }
// Load loading template // Load loading template
const loadingHTMLPath = resolve(this.options.buildDir, 'loading.html') const loadingHTMLPath = path.resolve(this.options.buildDir, 'loading.html')
if (fs.existsSync(loadingHTMLPath)) { if (fs.existsSync(loadingHTMLPath)) {
this.resources.loadingHTML = fs.readFileSync(loadingHTMLPath, 'utf8') this.resources.loadingHTML = fs.readFileSync(loadingHTMLPath, 'utf8')
this.resources.loadingHTML = this.resources.loadingHTML.replace( this.resources.loadingHTML = this.resources.loadingHTML.replace(
@ -162,7 +162,7 @@ export default class Renderer {
} }
// Create bundle renderer for SSR // Create bundle renderer for SSR
this.bundleRenderer = createBundleRenderer( this.bundleRenderer = vueServerRenderer.createBundleRenderer(
this.resources.serverBundle, this.resources.serverBundle,
Object.assign( Object.assign(
{ {
@ -248,7 +248,7 @@ export default class Renderer {
// For serving static/ files to / // For serving static/ files to /
const staticMiddleware = serveStatic( const staticMiddleware = serveStatic(
resolve(this.options.srcDir, this.options.dir.static), path.resolve(this.options.srcDir, this.options.dir.static),
this.options.render.static this.options.render.static
) )
staticMiddleware.prefix = this.options.render.static.prefix staticMiddleware.prefix = this.options.render.static.prefix
@ -257,7 +257,7 @@ export default class Renderer {
// Serve .nuxt/dist/ files only for production // Serve .nuxt/dist/ files only for production
// For dev they will be served with devMiddleware // For dev they will be served with devMiddleware
if (!this.options.dev) { if (!this.options.dev) {
const distDir = resolve(this.options.buildDir, 'dist') const distDir = path.resolve(this.options.buildDir, 'dist')
this.useMiddleware({ this.useMiddleware({
path: this.publicPath, path: this.publicPath,
handler: serveStatic(distDir, { handler: serveStatic(distDir, {
@ -401,7 +401,7 @@ export default class Renderer {
/* istanbul ignore if */ /* istanbul ignore if */
if (!jsdom) { if (!jsdom) {
try { try {
jsdom = require('jsdom') jsdom = this.nuxt.requireModule('jsdom')
} catch (e) /* istanbul ignore next */ { } catch (e) /* istanbul ignore next */ {
/* eslint-disable no-console */ /* eslint-disable no-console */
console.error('Fail when calling nuxt.renderAndGetWindow(url)') console.error('Fail when calling nuxt.renderAndGetWindow(url)')