mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
Merge branch 'dev' of github.com:nuxt/nuxt.js into dev
This commit is contained in:
commit
843d21b1ba
11
README.md
11
README.md
@ -168,12 +168,19 @@ You can start by using one of our starter templates:
|
||||
## Using nuxt.js programmatically
|
||||
|
||||
```js
|
||||
const Nuxt = require('nuxt')
|
||||
const { Nuxt, Builder } = require('nuxt')
|
||||
|
||||
// Launch nuxt build with given options
|
||||
// Import and set nuxt.js options
|
||||
let config = require('./nuxt.config.js')
|
||||
config.dev = !(process.env.NODE_ENV === 'production')
|
||||
|
||||
let nuxt = new Nuxt(config)
|
||||
|
||||
// Start build process (only in development)
|
||||
if (config.dev) {
|
||||
new Builder(nuxt).build()
|
||||
}
|
||||
|
||||
// You can use nuxt.render(req, res) or nuxt.renderRoute(route, context)
|
||||
```
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const now = Date.now()
|
||||
|
||||
const { readFileSync, readJSONSync, writeFileSync, copySync, removeSync } = require('fs-extra')
|
||||
const { resolve, relative } = require('path')
|
||||
|
||||
@ -38,7 +40,7 @@ requires = requires.filter(r => excludes.indexOf(r) === -1)
|
||||
let dependencies = {}
|
||||
requires.forEach(r => {
|
||||
if (!packageJSON.dependencies[r]) {
|
||||
console.warn('cannot resolve dependency version for ' + r)
|
||||
console.warn('Cannot resolve dependency version for ' + r)
|
||||
return
|
||||
}
|
||||
dependencies[r] = packageJSON.dependencies[r]
|
||||
@ -81,6 +83,7 @@ const extraFiles = [
|
||||
'bin/nuxt-build',
|
||||
'bin/nuxt-generate',
|
||||
'bin/nuxt-dev',
|
||||
'bin/nuxt',
|
||||
'dist/nuxt.js',
|
||||
'dist/nuxt.js.map'
|
||||
]
|
||||
@ -92,4 +95,9 @@ extraFiles.forEach(file => {
|
||||
const startIndexjs = resolve(startDir, 'index.js')
|
||||
writeFileSync(startIndexjs, String(readFileSync(startIndexjs)).replace('./dist/nuxt', './dist/core'))
|
||||
|
||||
console.log('generated ' + packageJSON.name + '@' + packageJSON.version)
|
||||
// Patch bin/nuxt-start
|
||||
const binStart = resolve(startDir, 'bin/nuxt-start')
|
||||
writeFileSync(binStart, String(readFileSync(binStart)).replace(/nuxt start/g, 'nuxt-start'))
|
||||
|
||||
const ms = Date.now() - now
|
||||
console.log(`Generated ${packageJSON.name}@${packageJSON.version} in ${ms}ms`)
|
||||
|
@ -4,13 +4,13 @@ const { Nuxt, Builder } = require('nuxt')
|
||||
const host = process.env.HOST || '127.0.0.1'
|
||||
const port = process.env.PORT || 3000
|
||||
|
||||
// Import and Set Nuxt.js options
|
||||
// Import and set Nuxt.js options
|
||||
let config = require('./nuxt.config.js')
|
||||
config.dev = !(process.env.NODE_ENV === 'production')
|
||||
|
||||
const nuxt = new Nuxt(config)
|
||||
|
||||
// Start build process if
|
||||
// Start build process in dev mode
|
||||
if (config.dev) {
|
||||
const builder = new Builder(nuxt)
|
||||
builder.build()
|
||||
|
@ -372,8 +372,19 @@ export default class Builder extends Tapable {
|
||||
return reject(err)
|
||||
}
|
||||
if (err) return console.error(err) // eslint-disable-line no-console
|
||||
|
||||
// Hide internal assets and source maps in stats
|
||||
const hiddenAssets = [
|
||||
/.map$/,
|
||||
/index\..+\.html$/,
|
||||
/vue-ssr-client-manifest.json/
|
||||
]
|
||||
const statsJson = stats.toJson(this.webpackStats, true)
|
||||
statsJson.assets = statsJson.assets.filter(asset => hiddenAssets.every(e => !e.test(asset.name)))
|
||||
|
||||
// Show build stats for production
|
||||
console.log(stats.toString(this.webpackStats)) // eslint-disable-line no-console
|
||||
console.log(stats.constructor.jsonToString(statsJson, true))// eslint-disable-line no-console
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (stats.hasErrors()) {
|
||||
return reject(new Error('Webpack build exited with errors'))
|
||||
|
@ -35,7 +35,7 @@ export default class Generator extends Tapable {
|
||||
await this.builder.build()
|
||||
}
|
||||
|
||||
await this.nuxt.applyPluginsAsync('generate', this)
|
||||
await this.nuxt.applyPluginsAsync('generator', this)
|
||||
|
||||
// Initialize dist directory
|
||||
if (init) {
|
||||
|
@ -5,3 +5,8 @@ export default {
|
||||
Builder,
|
||||
Generator
|
||||
}
|
||||
|
||||
export {
|
||||
Builder,
|
||||
Generator
|
||||
}
|
||||
|
@ -51,17 +51,19 @@ export default function webpackBaseConfig ({ isClient, isServer }) {
|
||||
'~~': join(this.options.rootDir),
|
||||
'@': join(this.options.srcDir),
|
||||
'@@': join(this.options.rootDir),
|
||||
'static': join(this.options.srcDir, 'static'), // use in template with <img src="~static/nuxt.png" />
|
||||
'assets': join(this.options.srcDir, 'assets') // use in template with <img src="~assets/nuxt.png" />
|
||||
'static': join(this.options.srcDir, 'static'),
|
||||
'~static': join(this.options.srcDir, 'static'),
|
||||
'assets': join(this.options.srcDir, 'assets'),
|
||||
'~assets': join(this.options.srcDir, 'assets')
|
||||
},
|
||||
modules: [
|
||||
join(this.options.rootDir, 'node_modules'),
|
||||
this.options.modulesDir,
|
||||
nodeModulesDir
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
join(this.options.rootDir, 'node_modules'),
|
||||
this.options.modulesDir,
|
||||
nodeModulesDir
|
||||
]
|
||||
},
|
||||
@ -78,7 +80,7 @@ export default function webpackBaseConfig ({ isClient, isServer }) {
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
query: defaults(this.options.build.babel, {
|
||||
presets: ['vue-app'],
|
||||
presets: [require.resolve('babel-preset-vue-app')],
|
||||
babelrc: false,
|
||||
cacheDirectory: !!this.options.dev
|
||||
})
|
||||
|
@ -3,6 +3,7 @@ import VueSSRServerPlugin from 'vue-server-renderer/server-plugin'
|
||||
import nodeExternals from 'webpack-node-externals'
|
||||
import { each } from 'lodash'
|
||||
import { resolve } from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import base from './base.config.js'
|
||||
|
||||
/*
|
||||
@ -31,16 +32,10 @@ export default function webpackServerConfig () {
|
||||
libraryTarget: 'commonjs2'
|
||||
}),
|
||||
performance: {
|
||||
hints: false
|
||||
hints: false,
|
||||
maxAssetSize: Infinity
|
||||
},
|
||||
externals: [
|
||||
// https://webpack.js.org/configuration/externals/#externals
|
||||
// https://github.com/liady/webpack-node-externals
|
||||
nodeExternals({
|
||||
// load non-javascript files with extensions, presumably via loaders
|
||||
whitelist: [/\.(?!(?:js|json)$).{1,5}$/i]
|
||||
})
|
||||
],
|
||||
externals: [],
|
||||
plugins: (config.plugins || []).concat([
|
||||
new VueSSRServerPlugin({
|
||||
filename: 'server-bundle.json'
|
||||
@ -54,6 +49,16 @@ export default function webpackServerConfig () {
|
||||
])
|
||||
})
|
||||
|
||||
// https://webpack.js.org/configuration/externals/#externals
|
||||
// https://github.com/liady/webpack-node-externals
|
||||
if (existsSync(this.options.modulesDir)) {
|
||||
config.externals.push(nodeExternals({
|
||||
// load non-javascript files with extensions, presumably via loaders
|
||||
whitelist: [/\.(?!(?:js|json)$).{1,5}$/i],
|
||||
modulesDir: this.options.modulesDir
|
||||
}))
|
||||
}
|
||||
|
||||
// --------------------------------------
|
||||
// Production specific config
|
||||
// --------------------------------------
|
||||
|
@ -3,7 +3,7 @@ import { extractStyles, styleLoader } from './helpers'
|
||||
|
||||
export default function ({ isClient }) {
|
||||
let babelOptions = JSON.stringify(defaults(this.options.build.babel, {
|
||||
presets: ['vue-app'],
|
||||
presets: [require.resolve('babel-preset-vue-app')],
|
||||
babelrc: false,
|
||||
cacheDirectory: !!this.options.dev
|
||||
}))
|
||||
|
@ -1,5 +1,12 @@
|
||||
import * as Utils from './utils'
|
||||
import Options from './options'
|
||||
|
||||
export default {
|
||||
Utils
|
||||
Utils,
|
||||
Options
|
||||
}
|
||||
|
||||
export {
|
||||
Utils,
|
||||
Options
|
||||
}
|
||||
|
@ -22,11 +22,13 @@ export default function Options (_options) {
|
||||
}
|
||||
|
||||
// Apply defaults
|
||||
_.defaultsDeep(options, defaultOptions)
|
||||
_.defaultsDeep(options, Options.defaults)
|
||||
|
||||
// Resolve dirs
|
||||
options.rootDir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
|
||||
options.srcDir = (typeof options.srcDir === 'string' && options.srcDir ? resolve(options.rootDir, options.srcDir) : options.rootDir)
|
||||
const hasValue = v => typeof v === 'string' && v
|
||||
options.rootDir = hasValue(options.rootDir) ? options.rootDir : process.cwd()
|
||||
options.srcDir = hasValue(options.srcDir) ? resolve(options.rootDir, options.srcDir) : options.rootDir
|
||||
options.modulesDir = resolve(options.rootDir, hasValue(options.modulesDir) ? options.modulesDir : 'node_modules')
|
||||
options.buildDir = join(options.rootDir, options.buildDir)
|
||||
|
||||
// If app.html is defined, set the template path to the user template
|
||||
@ -38,7 +40,7 @@ export default function Options (_options) {
|
||||
// Ignore publicPath on dev
|
||||
/* istanbul ignore if */
|
||||
if (options.dev && isUrl(options.build.publicPath)) {
|
||||
options.build.publicPath = defaultOptions.build.publicPath
|
||||
options.build.publicPath = Options.defaults.build.publicPath
|
||||
}
|
||||
|
||||
// If store defined, update store options to true unless explicitly disabled
|
||||
@ -52,7 +54,7 @@ export default function Options (_options) {
|
||||
mode = mode()
|
||||
}
|
||||
if (typeof mode === 'string') {
|
||||
mode = Modes[mode]
|
||||
mode = Options.modes[mode]
|
||||
}
|
||||
|
||||
// Apply mode
|
||||
@ -61,7 +63,7 @@ export default function Options (_options) {
|
||||
return options
|
||||
}
|
||||
|
||||
const Modes = {
|
||||
Options.modes = {
|
||||
universal: {
|
||||
build: {
|
||||
ssr: true
|
||||
@ -88,7 +90,7 @@ const Modes = {
|
||||
}
|
||||
}
|
||||
|
||||
export const defaultOptions = {
|
||||
Options.defaults = {
|
||||
mode: 'universal',
|
||||
dev: process.env.NODE_ENV !== 'production',
|
||||
buildDir: '.nuxt',
|
@ -1,13 +1,20 @@
|
||||
import Options from './options'
|
||||
import ModuleContainer from './module'
|
||||
import { Options, Utils } from 'common'
|
||||
import Module from './module'
|
||||
import Nuxt from './nuxt'
|
||||
import Renderer from './renderer'
|
||||
import * as Utils from 'utils'
|
||||
|
||||
export default {
|
||||
Options,
|
||||
ModuleContainer,
|
||||
Nuxt,
|
||||
Module,
|
||||
Renderer,
|
||||
Options,
|
||||
Utils
|
||||
}
|
||||
|
||||
export {
|
||||
Nuxt,
|
||||
Module,
|
||||
Renderer,
|
||||
Options,
|
||||
Utils
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ export default class ModuleContainer extends Tapable {
|
||||
|
||||
async _ready () {
|
||||
await sequence(this.options.modules, this.addModule.bind(this))
|
||||
await this.nuxt.applyPluginsAsync('module', this)
|
||||
await this.applyPluginsAsync('ready', this)
|
||||
}
|
||||
|
||||
addVendor (vendor) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Tapable from 'tappable'
|
||||
import chalk from 'chalk'
|
||||
import { Options } from 'common'
|
||||
import ModuleContainer from './module'
|
||||
import Renderer from './renderer'
|
||||
import Options from './options'
|
||||
import Debug from 'debug'
|
||||
import enableDestroy from 'server-destroy'
|
||||
import Module from 'module'
|
||||
@ -74,7 +74,7 @@ export default class Nuxt extends Tapable {
|
||||
})
|
||||
}))
|
||||
|
||||
resolve()
|
||||
resolve(this.applyPluginsAsync('listen', { server, port, host }))
|
||||
})
|
||||
|
||||
// Add server.destroy(cb) method
|
||||
|
@ -11,9 +11,9 @@ import { join, resolve } from 'path'
|
||||
import fs from 'fs-extra'
|
||||
import { createBundleRenderer } from 'vue-server-renderer'
|
||||
import { encodeHtml, getContext, setAnsiColors, isUrl } from 'utils'
|
||||
import { defaultOptions } from './options'
|
||||
import Debug from 'debug'
|
||||
import connect from 'connect'
|
||||
import { Options } from 'common'
|
||||
|
||||
const debug = Debug('nuxt:render')
|
||||
debug.color = 4 // Force blue color
|
||||
@ -46,14 +46,12 @@ export default class Renderer extends Tapable {
|
||||
spaTemplate: null,
|
||||
errorTemplate: parseTemplate('<pre>{{ stack }}</pre>') // Will be loaded on ready
|
||||
}
|
||||
|
||||
// Bind middleware to this context
|
||||
this.nuxtMiddleware = this.nuxtMiddleware.bind(this)
|
||||
this.errorMiddleware = this.errorMiddleware.bind(this)
|
||||
}
|
||||
|
||||
async _ready () {
|
||||
// Setup all middleWare
|
||||
await this.nuxt.applyPluginsAsync('renderer', this)
|
||||
|
||||
// Setup nuxt middleware
|
||||
await this.setupMiddleware()
|
||||
|
||||
// Load error template
|
||||
@ -67,12 +65,12 @@ export default class Renderer extends Tapable {
|
||||
await this.loadResources()
|
||||
}
|
||||
|
||||
await this.nuxt.applyPluginsAsync('renderer', this)
|
||||
// Call ready plugin
|
||||
await this.applyPluginsAsync('ready', this)
|
||||
}
|
||||
|
||||
async loadResources (_fs = fs) {
|
||||
let distPath = resolve(this.options.buildDir, 'dist')
|
||||
|
||||
let updated = []
|
||||
|
||||
resourceMap.forEach(({ key, fileName, transform }) => {
|
||||
@ -96,7 +94,6 @@ export default class Renderer extends Tapable {
|
||||
this.resources[key] = data
|
||||
updated.push(key)
|
||||
})
|
||||
|
||||
if (updated.length > 0) {
|
||||
// debug('Updated', updated.join(', '), isServer)
|
||||
this.createRenderer()
|
||||
@ -197,7 +194,7 @@ export default class Renderer extends Tapable {
|
||||
if (!this.options.dev) {
|
||||
const distDir = resolve(this.options.buildDir, 'dist')
|
||||
this.useMiddleware({
|
||||
path: isUrl(this.options.build.publicPath) ? defaultOptions.build.publicPath : this.options.build.publicPath,
|
||||
path: isUrl(this.options.build.publicPath) ? Options.defaults.build.publicPath : this.options.build.publicPath,
|
||||
handler: serveStatic(distDir, {
|
||||
index: false, // Don't serve index.html template
|
||||
maxAge: (this.options.dev ? 0 : '1y') // 1 year in production
|
||||
@ -211,10 +208,10 @@ export default class Renderer extends Tapable {
|
||||
})
|
||||
|
||||
// Finally use nuxtMiddleware
|
||||
this.useMiddleware(this.nuxtMiddleware)
|
||||
this.useMiddleware(this.nuxtMiddleware.bind(this))
|
||||
|
||||
// Error middleware for errors that occurred in middleware that declared above
|
||||
this.useMiddleware(this.errorMiddleware)
|
||||
this.useMiddleware(this.errorMiddleware.bind(this))
|
||||
}
|
||||
|
||||
async nuxtMiddleware (req, res, next) {
|
||||
@ -269,7 +266,7 @@ export default class Renderer extends Tapable {
|
||||
}
|
||||
}
|
||||
|
||||
async errorMiddleware (err, req, res, next, context) {
|
||||
errorMiddleware (err, req, res, next, context) {
|
||||
/* istanbul ignore if */
|
||||
if (context && context.redirected) {
|
||||
console.error(err) // eslint-disable-line no-console
|
||||
|
@ -1,3 +1,42 @@
|
||||
# Nuxt-Start
|
||||
# nuxt-start
|
||||
|
||||
WIP - Serve Nuxt.js Application for production
|
||||
> Start Nuxt.js Application in production mode.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install --save nuxt-start
|
||||
````
|
||||
|
||||
Add/Update your "start" script into your `package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start": "nuxt-start"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nuxt-start <dir> -p <port number> -H <hostname> -c <config file>
|
||||
```
|
||||
|
||||
## Programmatic Usage
|
||||
|
||||
```js
|
||||
const { Nuxt } = require('nuxt-start')
|
||||
|
||||
// Require nuxt config
|
||||
const config = require('./nuxt.config.js')
|
||||
|
||||
// Create a new nuxt instance
|
||||
const nuxt = new Nuxt(config)
|
||||
|
||||
// Start nuxt.js server
|
||||
nuxt.listen(3000) // nuxt.listen(port, host)
|
||||
|
||||
// Or use `nuxt.render` as an express middleware
|
||||
```
|
||||
|
@ -2,7 +2,7 @@ module.exports = function () {
|
||||
let ctr = 1
|
||||
|
||||
// Add hook for module
|
||||
this.nuxt.plugin('module', moduleContainer => {
|
||||
this.plugin('ready', moduleContainer => {
|
||||
this.nuxt.__module_hook = moduleContainer && ctr++
|
||||
})
|
||||
|
||||
|
@ -62,10 +62,9 @@ test('unique responses with component', async t => {
|
||||
await uniqueTest(t, '/component')
|
||||
})
|
||||
|
||||
test.todo('unique responses with async components (wait Vue 2.4)')
|
||||
// test('unique responses with async components', async t => {
|
||||
// await uniqueTest(t, '/asyncComponent')
|
||||
// })
|
||||
test('unique responses with async components', async t => {
|
||||
await uniqueTest(t, '/asyncComponent')
|
||||
})
|
||||
|
||||
test('unique responses with asyncData()', async t => {
|
||||
await uniqueTest(t, '/asyncData')
|
||||
|
Loading…
Reference in New Issue
Block a user