Merge branch 'dev' of github.com:nuxt/nuxt.js into dev

This commit is contained in:
Sebastien Chopin 2017-06-12 19:37:28 +02:00
commit 9e433764d7
14 changed files with 528 additions and 391 deletions

View File

@ -4,51 +4,57 @@
process.env.DEBUG = 'nuxt:*' process.env.DEBUG = 'nuxt:*'
var fs = require('fs') var fs = require('fs')
var parseArgs = require('minimist')
var without = require('lodash').without var without = require('lodash').without
var Nuxt = require('../') var Nuxt = require('../')
var resolve = require('path').resolve var resolve = require('path').resolve
// --analyze option const argv = parseArgs(process.argv.slice(2), {
var analyzeBuild = false alias: {
if (process.argv.indexOf('--analyze') !== -1 || process.argv.indexOf('-a') !== -1) { h: 'help',
analyzeBuild = true c: 'config-file',
process.argv = without(process.argv, '--analyze', '-a') a: 'analyze'
},
boolean: ['h', 'a'],
string: ['c'],
default: {
c: 'nuxt.config.js'
}
})
if (argv.help) {
console.log(`
Description
Compiles the application for production deployment
Usage
$ nuxt build <dir>
Options
--analyze, -a Launch webpack-bundle-analyzer to optimize your bundles.
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
--help, -h Displays this message
`)
process.exit(0)
} }
var nuxtConfigFileName = 'nuxt.config.js' var rootDir = resolve(argv._[0] || '.')
var nuxtConfigFile = resolve(rootDir, argv['config-file'])
// --config-file option
var indexOfConfig = false
if (process.argv.indexOf('--config-file') !== -1) {
indexOfConfig = process.argv.indexOf('--config-file')
} else if (process.argv.indexOf('-c') !== -1) {
indexOfConfig = process.argv.indexOf('-c')
}
if (indexOfConfig !== false) {
nuxtConfigFileName = process.argv.slice(indexOfConfig)[1]
process.argv = without(process.argv, '--config-file', '-c', nuxtConfigFileName)
}
// Root directory parameter
var rootDir = resolve(process.argv.slice(2)[0] || '.')
var nuxtConfigFilePath = resolve(rootDir, nuxtConfigFileName)
var options = {} var options = {}
if (fs.existsSync(nuxtConfigFilePath)) { if (fs.existsSync(nuxtConfigFile)) {
options = require(nuxtConfigFilePath) options = require(nuxtConfigFile)
} else { } else if (argv['config-file'] !== 'nuxt.config.js') {
console.log(`Could not locate ${nuxtConfigFilePath}`) // eslint-disable-line no-console console.error(`> Could not load config file ${argv['config-file']}`)
process.exit(1)
} }
if (typeof options.rootDir !== 'string') { if (typeof options.rootDir !== 'string') {
options.rootDir = rootDir options.rootDir = rootDir
} }
options.dev = false // Create production build when calling `nuxt build` // Create production build when calling `nuxt build`
options.dev = false
// Analyze option
options.build = options.build || {} options.build = options.build || {}
if (analyzeBuild) { if (argv.analyze) {
options.build.analyze = analyzeBuild options.build.analyze = true
} }
console.log('[nuxt] Building...') // eslint-disable-line no-console console.log('[nuxt] Building...') // eslint-disable-line no-console

View File

@ -7,41 +7,66 @@ var _ = require('lodash')
var debug = require('debug')('nuxt:build') var debug = require('debug')('nuxt:build')
debug.color = 2 // force green color debug.color = 2 // force green color
var fs = require('fs') var fs = require('fs')
var parseArgs = require('minimist')
var Nuxt = require('../') var Nuxt = require('../')
var chokidar = require('chokidar') var chokidar = require('chokidar')
var resolve = require('path').resolve var resolve = require('path').resolve
var without = require('lodash').without var without = require('lodash').without
var nuxtConfigFileName = 'nuxt.config.js' var argv = parseArgs(process.argv.slice(2), {
alias: {
h: 'help',
H: 'hostname',
p: 'port',
c: 'config-file'
},
boolean: ['h'],
string: ['H', 'c'],
default: {
c: 'nuxt.config.js'
}
})
// --config-file option if (argv.hostname === '') {
var indexOfConfig = false console.error(`> Provided hostname argument has no value`)
if (process.argv.indexOf('--config-file') !== -1) { process.exit(1)
indexOfConfig = process.argv.indexOf('--config-file')
} else if (process.argv.indexOf('-c') !== -1) {
indexOfConfig = process.argv.indexOf('-c')
} }
if (indexOfConfig !== false) { if (argv.help) {
nuxtConfigFileName = process.argv.slice(indexOfConfig)[1] console.log(`
process.argv = without(process.argv, '--config-file', '-c', nuxtConfigFileName) Description
Starts the application in development mode (hot-code reloading, error
reporting, etc)
Usage
$ nuxt dev <dir> -p <port number> -H <hostname>
Options
--port, -p A port number on which to start the application
--hostname, -H Hostname on which to start the application
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
--help, -h Displays this message
`)
process.exit(0)
} }
var rootDir = resolve(process.argv.slice(2)[0] || '.') var rootDir = resolve(argv._[0] || '.')
var nuxtConfigFile = resolve(rootDir, nuxtConfigFileName) var nuxtConfigFile = resolve(rootDir, argv['config-file'])
var options = {} var options = {}
if (fs.existsSync(nuxtConfigFile)) { if (fs.existsSync(nuxtConfigFile)) {
options = require(nuxtConfigFile) options = require(nuxtConfigFile)
} else if (argv['config-file'] !== 'nuxt.config.js') {
console.error(`> Could not load config file ${argv['config-file']}`)
process.exit(1)
} }
if (typeof options.rootDir !== 'string') { if (typeof options.rootDir !== 'string') {
options.rootDir = rootDir options.rootDir = rootDir
} }
options.dev = true // Add hot reloading and watching changes // Force development mode: add hot reloading and watching changes
options.dev = true
var nuxt = module.exports = new Nuxt(options) var nuxt = module.exports = new Nuxt(options)
var port = process.env.PORT || process.env.npm_package_config_nuxt_port var port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
var host = process.env.HOST || process.env.npm_package_config_nuxt_host var host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
var server = nuxt.server = new nuxt.Server(nuxt).listen(port, host) var server = nuxt.server = new nuxt.Server(nuxt).listen(port, host)
listenOnConfigChanges(nuxt, server) listenOnConfigChanges(nuxt, server)
@ -74,7 +99,6 @@ function listenOnConfigChanges(nuxt, server) {
process.exit(1) process.exit(1)
}) })
}, 200) }, 200)
var nuxtConfigFile = resolve(rootDir, nuxtConfigFileName)
chokidar.watch(nuxtConfigFile, Object.assign({}, nuxt.options.watchers.chokidar, { ignoreInitial: true })) chokidar.watch(nuxtConfigFile, Object.assign({}, nuxt.options.watchers.chokidar, { ignoreInitial: true }))
.on('all', build) .on('all', build)
} }

View File

@ -4,15 +4,44 @@
process.env.DEBUG = 'nuxt:*' process.env.DEBUG = 'nuxt:*'
var fs = require('fs') var fs = require('fs')
var parseArgs = require('minimist')
var Nuxt = require('../') var Nuxt = require('../')
var resolve = require('path').resolve var resolve = require('path').resolve
var rootDir = resolve(process.argv.slice(2)[0] || '.') var argv = parseArgs(process.argv.slice(2), {
var nuxtConfigFile = resolve(rootDir, 'nuxt.config.js') alias: {
h: 'help',
c: 'config-file'
},
boolean: ['h'],
string: ['c'],
default: {
c: 'nuxt.config.js'
}
})
if (argv.help) {
console.log(`
Description
Generate a static web application (server-rendered)
Usage
$ nuxt generate <dir>
Options
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
--help, -h Displays this message
`)
process.exit(0)
}
var rootDir = resolve(argv._[0] || '.')
var nuxtConfigFile = resolve(rootDir, argv['config-file'])
var options = {} var options = {}
if (fs.existsSync(nuxtConfigFile)) { if (fs.existsSync(nuxtConfigFile)) {
options = require(nuxtConfigFile) options = require(nuxtConfigFile)
} else if (argv['config-file'] !== 'nuxt.config.js') {
console.error(`> Could not load config file ${argv['config-file']}`)
process.exit(1)
} }
if (typeof options.rootDir !== 'string') { if (typeof options.rootDir !== 'string') {
options.rootDir = rootDir options.rootDir = rootDir

View File

@ -1,22 +1,69 @@
#!/usr/bin/env node #!/usr/bin/env node
var fs = require('fs') var fs = require('fs')
var parseArgs = require('minimist')
var Nuxt = require('../') var Nuxt = require('../')
var resolve = require('path').resolve var resolve = require('path').resolve
var join = require('path').join
var rootDir = resolve(process.argv.slice(2)[0] || '.') var argv = parseArgs(process.argv.slice(2), {
var nuxtConfigFile = resolve(rootDir, 'nuxt.config.js') alias: {
h: 'help',
H: 'hostname',
p: 'port',
c: 'config-file'
},
boolean: ['h'],
string: ['H', 'c'],
default: {
c: 'nuxt.config.js'
}
})
if (argv.hostname === '') {
console.error(`> Provided hostname argument has no value`)
process.exit(1)
}
if (argv.help) {
console.log(`
Description
Starts the application in production mode.
The application should be compiled with \`nuxt build\` first.
Usage
$ nuxt start <dir> -p <port number> -H <hostname>
Options
--port, -p A port number on which to start the application
--hostname, -H Hostname on which to start the application
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
--help, -h Displays this message
`)
process.exit(0)
}
var rootDir = resolve(argv._[0] || '.')
var nuxtConfigFile = resolve(rootDir, argv['config-file'])
var options = {} var options = {}
if (fs.existsSync(nuxtConfigFile)) { if (fs.existsSync(nuxtConfigFile)) {
options = require(nuxtConfigFile) options = require(nuxtConfigFile)
} else if (argv['config-file'] !== 'nuxt.config.js') {
console.error(`> Could not load config file ${argv['config-file']}`)
process.exit(1)
} }
if (typeof options.rootDir !== 'string') { if (typeof options.rootDir !== 'string') {
options.rootDir = rootDir options.rootDir = rootDir
} }
options.dev = false // Force production mode (no webpack middleware called) options.dev = false // Force production mode (no webpack middleware called)
var buildDir = join(options.rootDir, (options.buildDir || '.nuxt'), 'dist', 'server-bundle.json')
// Check if project is built for production
if (!fs.existsSync(buildDir)) {
console.error('> No build files found, please run `nuxt build` before launching `nuxt start`') // eslint-disable-line no-console
process.exit(1)
}
var nuxt = module.exports = new Nuxt(options) var nuxt = module.exports = new Nuxt(options)
var port = process.env.PORT || process.env.npm_package_config_nuxt_port var port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
var host = process.env.HOST || process.env.npm_package_config_nuxt_host var host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
var server = nuxt.server = new nuxt.Server(nuxt).listen(port, host) var server = nuxt.server = new nuxt.Server(nuxt).listen(port, host)

View File

@ -7,21 +7,13 @@ module.exports = {
app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js
}, },
vendor: ['lodash'], vendor: ['lodash'],
// Loaders config (Webpack 2)
loaders: [
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 100000, // 100KO
name: 'img/[name].[ext]?[hash]'
}
}
],
extend (config, { dev }) { extend (config, { dev }) {
if (dev) { if (dev) {
config.devtool = (dev ? 'eval-source-map' : false) config.devtool = (dev ? 'eval-source-map' : false)
} }
const urlLoader = config.module.rules.find((loader) => loader.loader === 'url-loader')
// Increase limit to 100KO
urlLoader.query.limit = 100000
} }
} }
} }

View File

@ -14,12 +14,22 @@ let router
<%= (store ? 'let store' : '') %> <%= (store ? 'let store' : '') %>
function mapTransitions(Components, to, from) { function mapTransitions(Components, to, from) {
const resolveTransitions = component => (typeof component.options.transition === 'function')
? component.options.transition(to, from)
: component.options.transition
const resolveRoute = route => resolveTransitions(route.matched[0].components.default)
return Components.map((Component) => { return Components.map((Component) => {
let transition = Component.options.transition const transitions = Object.assign({}, to ? resolveRoute(to) : resolveTransitions(Component))
if (typeof transition === 'function') { const from_transitions = from ? resolveRoute(from) : {}
return transition(to, from) // Combine transitions & prefer leave* transitions of from route
Object.keys(from_transitions).forEach(key=> {
if (from_transitions[key] && key.toLowerCase().indexOf('leave') !== -1) {
transitions[key] = from_transitions[key]
} }
return transition })
return transitions
}) })
} }

View File

@ -30,7 +30,7 @@ export default {
functional: true, functional: true,
render (h, { parent, data }) { render (h, { parent, data }) {
data.nuxtChild = true data.nuxtChild = true
const _parent = parent
const transitions = parent.$nuxt.nuxt.transitions const transitions = parent.$nuxt.nuxt.transitions
const defaultTransition = parent.$nuxt.nuxt.defaultTransition const defaultTransition = parent.$nuxt.nuxt.defaultTransition
let depth = 0 let depth = 0
@ -51,7 +51,7 @@ export default {
let listeners = {} let listeners = {}
listenersKeys.forEach((key) => { listenersKeys.forEach((key) => {
if (typeof transition[key] === 'function') { if (typeof transition[key] === 'function') {
listeners[key] = transition[key] listeners[key] = transition[key].bind(_parent)
} }
}) })
return h('transition', { return h('transition', {

View File

@ -35,31 +35,13 @@ const defaults = {
app: 'nuxt.bundle.[chunkhash].js' app: 'nuxt.bundle.[chunkhash].js'
}, },
vendor: [], vendor: [],
loaders: [],
plugins: [], plugins: [],
babel: {}, babel: {},
postcss: [], postcss: [],
templates: [], templates: [],
watch: [] watch: []
} }
const defaultsLoaders = [
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
query: {
limit: 1000, // 1KO
name: 'img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 1000, // 1 KO
name: 'fonts/[name].[hash:7].[ext]'
}
}
]
const defaultsPostcss = [ const defaultsPostcss = [
require('autoprefixer')({ require('autoprefixer')({
browsers: ['last 3 versions'] browsers: ['last 3 versions']
@ -69,7 +51,6 @@ const defaultsPostcss = [
export function options () { export function options () {
// Defaults build options // Defaults build options
let extraDefaults = {} let extraDefaults = {}
if (this.options.build && !Array.isArray(this.options.build.loaders)) extraDefaults.loaders = defaultsLoaders
if (this.options.build && !Array.isArray(this.options.build.postcss)) extraDefaults.postcss = defaultsPostcss if (this.options.build && !Array.isArray(this.options.build.postcss)) extraDefaults.postcss = defaultsPostcss
this.options.build = _.defaultsDeep(this.options.build, defaults, extraDefaults) this.options.build = _.defaultsDeep(this.options.build, defaults, extraDefaults)
/* istanbul ignore if */ /* istanbul ignore if */
@ -427,8 +408,9 @@ function getWebpackServerConfig () {
function createWebpackMiddleware () { function createWebpackMiddleware () {
const clientConfig = getWebpackClientConfig.call(this) const clientConfig = getWebpackClientConfig.call(this)
const host = process.env.HOST || process.env.npm_package_config_nuxt_host || '127.0.0.1' const host = process.env.HOST || process.env.npm_package_config_nuxt_host || 'localhost'
const port = process.env.PORT || process.env.npm_package_config_nuxt_port || '3000' const port = process.env.PORT || process.env.npm_package_config_nuxt_port || '3000'
// setup on the fly compilation + hot-reload // setup on the fly compilation + hot-reload
clientConfig.entry.app = _.flatten(['webpack-hot-middleware/client?reload=true', clientConfig.entry.app]) clientConfig.entry.app = _.flatten(['webpack-hot-middleware/client?reload=true', clientConfig.entry.app])
clientConfig.plugins.push( clientConfig.plugins.push(
@ -436,7 +418,10 @@ function createWebpackMiddleware () {
new webpack.NoEmitOnErrorsPlugin(), new webpack.NoEmitOnErrorsPlugin(),
new PostCompilePlugin(stats => { new PostCompilePlugin(stats => {
if (!stats.hasErrors() && !stats.hasWarnings()) { if (!stats.hasErrors() && !stats.hasWarnings()) {
console.log(`> Open http://${host}:${port}\n`) // eslint-disable-line no-console // We don't use os.host() here because browsers have special behaviour with localhost
// For example chrome allows Geolocation api only to https or localhost origins
let _host = host === '0.0.0.0' ? 'localhost' : host
console.log(`> Open http://${_host}:${port}\n`) // eslint-disable-line no-console
} }
}) })
) )

View File

@ -14,11 +14,6 @@ setAnsiColors(ansiHTML)
export async function render (req, res) { export async function render (req, res) {
// Wait for nuxt.js to be ready // Wait for nuxt.js to be ready
await this.ready() await this.ready()
// Check if project is built for production
if (!this.renderer && !this.dev) {
console.error('> No build files found, please run `nuxt build` before launching `nuxt start`') // eslint-disable-line no-console
process.exit(1)
}
/* istanbul ignore if */ /* istanbul ignore if */
if (!this.renderer || !this.appTemplate) { if (!this.renderer || !this.appTemplate) {
return new Promise((resolve) => { return new Promise((resolve) => {

View File

@ -46,12 +46,13 @@ class Server {
} }
listen (port, host) { listen (port, host) {
host = host || '127.0.0.1' host = host || 'localhost'
port = port || 3000 port = port || 3000
this.nuxt.ready() this.nuxt.ready()
.then(() => { .then(() => {
this.server.listen(port, host, () => { this.server.listen(port, host, () => {
console.log('Ready on http://%s:%s', host, port) // eslint-disable-line no-console let _host = host === '0.0.0.0' ? 'localhost' : host
console.log('Ready on http://%s:%s', _host, port) // eslint-disable-line no-console
}) })
}) })
return this return this

View File

@ -77,7 +77,23 @@ export default function ({ isClient, isServer }) {
{ test: /\.less$/, use: styleLoader.call(this, 'less', 'less-loader') }, { test: /\.less$/, use: styleLoader.call(this, 'less', 'less-loader') },
{ test: /\.sass$/, use: styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax&sourceMap') }, { test: /\.sass$/, use: styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax&sourceMap') },
{ test: /\.scss$/, use: styleLoader.call(this, 'sass', 'sass-loader?sourceMap') }, { test: /\.scss$/, use: styleLoader.call(this, 'sass', 'sass-loader?sourceMap') },
{ test: /\.styl(us)?$/, use: styleLoader.call(this, 'stylus', 'stylus-loader') } { test: /\.styl(us)?$/, use: styleLoader.call(this, 'stylus', 'stylus-loader') },
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
query: {
limit: 1000, // 1KO
name: 'img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 1000, // 1 KO
name: 'fonts/[name].[hash:7].[ext]'
}
}
] ]
}, },
plugins: this.options.build.plugins plugins: this.options.build.plugins
@ -88,8 +104,6 @@ export default function ({ isClient, isServer }) {
new ExtractTextPlugin({filename: this.options.build.filenames.css}) new ExtractTextPlugin({filename: this.options.build.filenames.css})
) )
} }
// Add nuxt build loaders (can be configured in nuxt.config.js)
config.module.rules = config.module.rules.concat(this.options.build.loaders)
// Return config // Return config
return config return config
} }

View File

@ -63,7 +63,7 @@ export default function () {
// Extend config // Extend config
if (typeof this.options.build.extend === 'function') { if (typeof this.options.build.extend === 'function') {
this.options.build.extend(config, { this.options.build.extend.call(this, config, {
dev: this.dev, dev: this.dev,
isServer: true isServer: true
}) })

View File

@ -80,6 +80,7 @@
"html-webpack-plugin": "^2.28.0", "html-webpack-plugin": "^2.28.0",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"memory-fs": "^0.4.1", "memory-fs": "^0.4.1",
"minimist": "^1.2.0",
"offline-plugin": "^4.8.1", "offline-plugin": "^4.8.1",
"opencollective": "^1.0.3", "opencollective": "^1.0.3",
"pify": "^3.0.0", "pify": "^3.0.0",

573
yarn.lock

File diff suppressed because it is too large Load Diff