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

This commit is contained in:
Sebastien Chopin 2017-06-05 11:24:09 +02:00
commit 3a2b732965
11 changed files with 102 additions and 71 deletions

View File

@ -6,9 +6,9 @@ node_js:
before_install: before_install:
- if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi - if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi
install: install:
- npm install - yarn install
- npm run build - yarn run build
script: script:
- npm test - yarn run test
after_success: after_success:
- npm run coverage - yarn run coverage

View File

@ -7,15 +7,16 @@ install:
# Get the latest stable version of Node.js or io.js # Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version - ps: Install-Product node $env:nodejs_version
# install modules # install modules
- npm install - yarn install
# Post-install test scripts. # Post-install test scripts.
test_script: test_script:
# Output useful info for debugging. # Output useful info for debugging.
- node --version - node --version
- npm --version - npm --version
- yarn --version
# run tests # run tests
- npm test - yarn run test
# Don't actually build. # Don't actually build.
build: off build: off

View File

@ -1,16 +1,13 @@
module.exports = { module.exports = {
loading: { color: 'cyan' },
build: { build: {
vendor: ['vue-i18n'] vendor: ['vue-i18n']
}, },
router: { router: {
middleware: 'i18n' middleware: 'i18n'
}, },
plugins: [ plugins: ['~plugins/i18n.js',],
// Will inject the plugin in the $root app and also in the context as `i18n`
{ src: '~plugins/i18n.js', injectAs: 'i18n' }
],
generate: { generate: {
routes: ['/', '/about', '/fr', '/fr/about'] routes: ['/', '/about', '/fr', '/fr/about']
}, }
loading: { color: 'cyan' },
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "nuxt-i18n", "name": "nuxt-i18n",
"dependencies": { "dependencies": {
"nuxt": "latest", "nuxt": "1.0.0-alpha.3",
"vue-i18n": "^7.0.0" "vue-i18n": "^7.0.0"
}, },
"scripts": { "scripts": {

View File

@ -19,6 +19,7 @@ const isDev = <%= isDev %>
export default async (context) => { export default async (context) => {
const { app, router<%= (store ? ', store' : '') %> } = await createApp(context) const { app, router<%= (store ? ', store' : '') %> } = await createApp(context)
const _app = new Vue(app) const _app = new Vue(app)
const _noopApp = new Vue({ render: (h) => h('div') })
// Add store to the context // Add store to the context
<%= (store ? 'context.store = store' : '') %> <%= (store ? 'context.store = store' : '') %>
// Add route to the context // Add route to the context
@ -84,7 +85,7 @@ export default async (context) => {
if (!context.nuxt.error) { if (!context.nuxt.error) {
await middlewareSeries(midd, ctx) await middlewareSeries(midd, ctx)
} }
if (context.redirected) return _app if (context.redirected) return _noopApp
// Set layout // Set layout
let layout = Components.length ? Components[0].options.layout : NuxtError.layout let layout = Components.length ? Components[0].options.layout : NuxtError.layout
if (typeof layout === 'function') layout = layout(ctx) if (typeof layout === 'function') layout = layout(ctx)
@ -109,7 +110,7 @@ export default async (context) => {
if (!context.nuxt.error) { if (!context.nuxt.error) {
await middlewareSeries(midd, ctx) await middlewareSeries(midd, ctx)
} }
if (context.redirected) return _app if (context.redirected) return _noopApp
// Call .validate() // Call .validate()
let isValid = true let isValid = true
Components.forEach((Component) => { Components.forEach((Component) => {

View File

@ -76,8 +76,10 @@ export function options () {
if (this.dev && isUrl(this.options.build.publicPath)) { if (this.dev && isUrl(this.options.build.publicPath)) {
this.options.build.publicPath = defaults.publicPath this.options.build.publicPath = defaults.publicPath
} }
}
export function production () {
// Production, create server-renderer // Production, create server-renderer
if (!this.dev) {
webpackStats = { webpackStats = {
chunks: false, chunks: false,
children: false, children: false,
@ -94,7 +96,6 @@ export function options () {
addAppTemplate.call(this) addAppTemplate.call(this)
} }
} }
}
export async function build () { export async function build () {
// Avoid calling this method multiple times // Avoid calling this method multiple times

View File

@ -42,6 +42,10 @@ export default async function () {
const s = Date.now() const s = Date.now()
let errors = [] let errors = []
/* /*
** Wait for modules to be initialized
*/
await this.ready()
/*
** Set variables ** Set variables
*/ */
this.options.generate = _.defaultsDeep(this.options.generate, defaults) this.options.generate = _.defaultsDeep(this.options.generate, defaults)

View File

@ -12,17 +12,18 @@ class Module {
constructor (nuxt) { constructor (nuxt) {
this.nuxt = nuxt this.nuxt = nuxt
this.options = nuxt.options this.options = nuxt.options
this.modules = [] this.requiredModules = []
this.initing = this.ready() this.initing = this.ready()
} }
async ready () { async ready () {
if (this.initing) { if (this.initing) {
await this.initing await this.initing
return return this
} }
// Install all modules in sequence // Install all modules in sequence
await sequence(this.options.modules, this.addModule.bind(this)) await sequence(this.options.modules, this.addModule.bind(this))
return this
} }
addVendor (vendor) { addVendor (vendor) {
@ -81,14 +82,11 @@ class Module {
} }
requireModule (moduleOpts) { requireModule (moduleOpts) {
if (this.modules.indexOf(moduleOpts) !== -1 || this.modules.indexOf(moduleOpts.src) !== -1) { // Require once
return false return this.addModule(moduleOpts, true)
}
this.modules.push(moduleOpts.src || moduleOpts)
return this.addModule(moduleOpts)
} }
addModule (moduleOpts) { addModule (moduleOpts, requireOnce) {
/* istanbul ignore if */ /* istanbul ignore if */
if (!moduleOpts) { if (!moduleOpts) {
return return
@ -128,6 +126,19 @@ class Module {
console.error(`[nuxt] Module [${originalSrc}] should export a function`) console.error(`[nuxt] Module [${originalSrc}] should export a function`)
process.exit(1) process.exit(1)
} }
// Module meta
if (!module.meta) {
module.meta = {}
}
if (module.meta.name) {
const alreadyRequired = this.requiredModules.indexOf(module.meta.name) !== -1
if (requireOnce && alreadyRequired) {
return
}
if (!alreadyRequired) {
this.requiredModules.push(module.meta.name)
}
}
// Call module with `this` context and pass options // Call module with `this` context and pass options
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const result = module.call(this, options, err => { const result = module.call(this, options, err => {

View File

@ -51,6 +51,9 @@ class Nuxt {
scrollBehavior: null scrollBehavior: null
}, },
render: { render: {
http2: {
push: false
},
static: {}, static: {},
gzip: { gzip: {
threshold: 0 threshold: 0
@ -124,20 +127,25 @@ class Nuxt {
// Add module integration // Add module integration
this.module = new Module(this) this.module = new Module(this)
// Init nuxt.js // Init nuxt.js
this.ready() this._ready = this.ready()
// Launch build in development but don't wait for him to be finished
if (this.dev) {
this.build()
}
// Return nuxt.js instance // Return nuxt.js instance
return this return this
} }
async ready () { async ready () {
if (this._ready) return this if (this._ready) {
await this._ready
return this
}
// Init modules // Init modules
await this.module.ready() await this.module.ready()
this._ready = true // Launch build in development but don't wait for it to be finished
if (this.dev) {
this.build()
} else {
build.production.call(this)
}
return this
} }
close (callback) { close (callback) {

View File

@ -5,12 +5,16 @@ import serialize from 'serialize-javascript'
import generateETag from 'etag' import generateETag from 'etag'
import fresh from 'fresh' import fresh from 'fresh'
import { getContext, setAnsiColors, encodeHtml } from './utils' import { getContext, setAnsiColors, encodeHtml } from './utils'
const debug = require('debug')('nuxt:render') const debug = require('debug')('nuxt:render')
// force blue color // force blue color
debug.color = 4 debug.color = 4
setAnsiColors(ansiHTML) setAnsiColors(ansiHTML)
export async function render (req, res) { export async function render (req, res) {
// Wait for nuxt.js to be ready
await this.ready()
// Check if project is built for production
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)
@ -23,8 +27,6 @@ export async function render (req, res) {
}, 1000) }, 1000)
}) })
} }
// Wait for nuxt.js to be ready
await this.ready()
// Get context // Get context
const context = getContext(req, res) const context = getContext(req, res)
res.statusCode = 200 res.statusCode = 200
@ -73,8 +75,8 @@ export async function render (req, res) {
} }
res.setHeader('ETag', etag) res.setHeader('ETag', etag)
} }
res.setHeader('Content-Type', 'text/html; charset=utf-8') // HTTP2 push headers
res.setHeader('Content-Length', Buffer.byteLength(html)) if (!error && this.options.render.http2.push) {
// Parse resourceHints to extract HTTP.2 prefetch/push headers // Parse resourceHints to extract HTTP.2 prefetch/push headers
// https://w3c.github.io/preload/#server-push-http-2 // https://w3c.github.io/preload/#server-push-http-2
const regex = /link rel="([^"]*)" href="([^"]*)" as="([^"]*)"/g const regex = /link rel="([^"]*)" href="([^"]*)" as="([^"]*)"/g
@ -86,7 +88,12 @@ export async function render (req, res) {
pushAssets.push(`<${href}>; rel=${rel}; as=${as}`) pushAssets.push(`<${href}>; rel=${rel}; as=${as}`)
} }
} }
res.setHeader('Link', pushAssets) // Pass with single Link header
// https://blog.cloudflare.com/http-2-server-push-with-multiple-assets-per-link-header
res.setHeader('Link', pushAssets.join(','))
}
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.setHeader('Content-Length', Buffer.byteLength(html))
res.end(html, 'utf8') res.end(html, 'utf8')
return html return html
} catch (err) { } catch (err) {
@ -162,7 +169,8 @@ export async function renderAndGetWindow (url, opts = {}) {
runScripts: 'dangerously', runScripts: 'dangerously',
beforeParse (window) { beforeParse (window) {
// Mock window.scrollTo // Mock window.scrollTo
window.scrollTo = () => {} window.scrollTo = () => {
}
} }
} }
if (opts.virtualConsole !== false) { if (opts.virtualConsole !== false) {

View File

@ -1,6 +1,6 @@
{ {
"name": "nuxt", "name": "nuxt",
"version": "1.0.0-alpha2", "version": "1.0.0-alpha.3",
"description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)", "description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)",
"contributors": [ "contributors": [
{ {