mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 16:12:12 +00:00
Merge branch 'modules' into dev
This commit is contained in:
commit
c7f31b6492
4
.gitignore
vendored
4
.gitignore
vendored
@ -19,3 +19,7 @@ coverage
|
|||||||
*.lcov
|
*.lcov
|
||||||
.nyc_output
|
.nyc_output
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# Intellij idea
|
||||||
|
*.iml
|
||||||
|
.idea
|
||||||
|
@ -52,7 +52,7 @@ if (analyzeBuild) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log('[nuxt] Building...') // eslint-disable-line no-console
|
console.log('[nuxt] Building...') // eslint-disable-line no-console
|
||||||
var nuxt = new Nuxt(options)
|
new Nuxt(options).then(nuxt => {
|
||||||
nuxt.build()
|
nuxt.build()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('[nuxt] Building done') // eslint-disable-line no-console
|
console.log('[nuxt] Building done') // eslint-disable-line no-console
|
||||||
@ -61,3 +61,4 @@ nuxt.build()
|
|||||||
console.error(err) // eslint-disable-line no-console
|
console.error(err) // eslint-disable-line no-console
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
@ -39,7 +39,7 @@ if (typeof options.rootDir !== 'string') {
|
|||||||
}
|
}
|
||||||
options.dev = true // Add hot reloading and watching changes
|
options.dev = true // Add hot reloading and watching changes
|
||||||
|
|
||||||
var nuxt = new Nuxt(options)
|
new Nuxt(options).then(nuxt => {
|
||||||
var server = new nuxt.Server(nuxt)
|
var server = new nuxt.Server(nuxt)
|
||||||
.listen(process.env.PORT || process.env.npm_package_config_nuxt_port, process.env.HOST || process.env.npm_package_config_nuxt_host)
|
.listen(process.env.PORT || process.env.npm_package_config_nuxt_port, process.env.HOST || process.env.npm_package_config_nuxt_host)
|
||||||
listenOnConfigChanges(nuxt, server)
|
listenOnConfigChanges(nuxt, server)
|
||||||
@ -49,6 +49,7 @@ nuxt.build()
|
|||||||
console.error(err) // eslint-disable-line no-console
|
console.error(err) // eslint-disable-line no-console
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
function listenOnConfigChanges (nuxt, server) {
|
function listenOnConfigChanges (nuxt, server) {
|
||||||
// Listen on nuxt.config.js changes
|
// Listen on nuxt.config.js changes
|
||||||
@ -68,7 +69,7 @@ function listenOnConfigChanges (nuxt, server) {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
nuxt.renderer = null
|
nuxt.renderer = null
|
||||||
debug('Rebuilding the app...')
|
debug('Rebuilding the app...')
|
||||||
return new Nuxt(options).build()
|
return (new Nuxt(options)).then(nuxt => nuxt.build())
|
||||||
})
|
})
|
||||||
.then((nuxt) => {
|
.then((nuxt) => {
|
||||||
server.nuxt = nuxt
|
server.nuxt = nuxt
|
||||||
|
@ -20,7 +20,7 @@ if (typeof options.rootDir !== 'string') {
|
|||||||
options.dev = false // Force production mode (no webpack middleware called)
|
options.dev = false // Force production mode (no webpack middleware called)
|
||||||
|
|
||||||
console.log('[nuxt] Generating...') // eslint-disable-line no-console
|
console.log('[nuxt] Generating...') // eslint-disable-line no-console
|
||||||
var nuxt = new Nuxt(options)
|
new Nuxt(options).then(nuxt => {
|
||||||
nuxt.generate()
|
nuxt.generate()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('[nuxt] Generate done') // eslint-disable-line no-console
|
console.log('[nuxt] Generate done') // eslint-disable-line no-console
|
||||||
@ -29,3 +29,4 @@ nuxt.generate()
|
|||||||
console.error(err) // eslint-disable-line no-console
|
console.error(err) // eslint-disable-line no-console
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
@ -16,10 +16,10 @@ if (typeof options.rootDir !== 'string') {
|
|||||||
}
|
}
|
||||||
options.dev = false // Force production mode (no webpack middleware called)
|
options.dev = false // Force production mode (no webpack middleware called)
|
||||||
|
|
||||||
var nuxt = new Nuxt(options)
|
new Nuxt(options).then(nuxt => {
|
||||||
|
|
||||||
new nuxt.Server(nuxt)
|
new nuxt.Server(nuxt)
|
||||||
.listen(
|
.listen(
|
||||||
process.env.PORT || process.env.npm_package_config_nuxt_port,
|
process.env.PORT || process.env.npm_package_config_nuxt_port,
|
||||||
process.env.HOST || process.env.npm_package_config_nuxt_host
|
process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||||
)
|
)
|
||||||
|
})
|
||||||
|
@ -1,15 +1,59 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
let files = require.context('~/store', true, /^\.\/.*\.(js|ts)$/)
|
// Recursive find files in ~/store
|
||||||
let filenames = files.keys()
|
const files = require.context('~/store', true, /^\.\/.*\.(js|ts)$/)
|
||||||
|
const filenames = files.keys()
|
||||||
|
|
||||||
|
// Store
|
||||||
|
let storeData = {}
|
||||||
|
|
||||||
|
// Check if store/index.js exists
|
||||||
|
if (filenames.indexOf('./index.js') !== -1) {
|
||||||
|
storeData = getModule('./index.js')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store modules
|
||||||
|
if (!storeData.modules) {
|
||||||
|
storeData.modules = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let filename of filenames) {
|
||||||
|
let name = filename.replace(/^\.\//, '').replace(/\.(js|ts)$/, '')
|
||||||
|
if (name === 'index') continue
|
||||||
|
|
||||||
|
let namePath = name.split(/\//)
|
||||||
|
let module = getModuleNamespace(storeData, namePath)
|
||||||
|
|
||||||
|
name = namePath.pop()
|
||||||
|
module[name] = getModule(filename)
|
||||||
|
module[name].namespaced = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// createStore
|
||||||
|
export const createStore = storeData instanceof Function ? storeData : () => {
|
||||||
|
return new Vuex.Store(Object.assign({}, storeData, {
|
||||||
|
state: storeData.state instanceof Function ? storeData.state() : {}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dynamically require module
|
||||||
function getModule (filename) {
|
function getModule (filename) {
|
||||||
let file = files(filename)
|
const file = files(filename)
|
||||||
return file.default
|
const module = file.default || file
|
||||||
? file.default
|
if (module.state && typeof module.state !== 'function') {
|
||||||
: file
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('[nuxt] store state should be a function.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (module.commit) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('[nuxt] store should export raw store options instead of an instance.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
function getModuleNamespace (storeData, namePath) {
|
function getModuleNamespace (storeData, namePath) {
|
||||||
@ -22,43 +66,3 @@ function getModuleNamespace (storeData, namePath) {
|
|||||||
storeData.modules[namespace].modules = storeData.modules[namespace].modules || {}
|
storeData.modules[namespace].modules = storeData.modules[namespace].modules || {}
|
||||||
return getModuleNamespace(storeData.modules[namespace], namePath)
|
return getModuleNamespace(storeData.modules[namespace], namePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
let store
|
|
||||||
let storeData = {}
|
|
||||||
|
|
||||||
// Check if store/index.js returns a vuex store
|
|
||||||
if (filenames.indexOf('./index.js') !== -1) {
|
|
||||||
let mainModule = getModule('./index.js')
|
|
||||||
if (mainModule.commit) {
|
|
||||||
console.error('[nuxt.js] store/index should export raw store options instead of an instance.')
|
|
||||||
} else {
|
|
||||||
if (mainModule.state && typeof mainModule.state !== 'function') {
|
|
||||||
console.error('[nuxt.js] store state should be a function.')
|
|
||||||
}
|
|
||||||
storeData = mainModule
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the store if there is no store yet
|
|
||||||
if (store == null) {
|
|
||||||
storeData.modules = storeData.modules || {}
|
|
||||||
for (let filename of filenames) {
|
|
||||||
let name = filename.replace(/^\.\//, '').replace(/\.(js|ts)$/, '')
|
|
||||||
if (name === 'index') continue
|
|
||||||
|
|
||||||
let namePath = name.split(/\//)
|
|
||||||
let module = getModuleNamespace(storeData, namePath)
|
|
||||||
|
|
||||||
name = namePath.pop()
|
|
||||||
module[name] = getModule(filename)
|
|
||||||
module[name].namespaced = true
|
|
||||||
|
|
||||||
if (typeof module[name].state !== 'function') {
|
|
||||||
console.error('[nuxt.js] store module state should be a function.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createStore () {
|
|
||||||
return new Vuex.Store(storeData)
|
|
||||||
}
|
|
||||||
|
27
lib/build.js
27
lib/build.js
@ -57,7 +57,9 @@ const defaults = {
|
|||||||
loaders: [],
|
loaders: [],
|
||||||
plugins: [],
|
plugins: [],
|
||||||
babel: {},
|
babel: {},
|
||||||
postcss: []
|
postcss: [],
|
||||||
|
templates: [],
|
||||||
|
watch: []
|
||||||
}
|
}
|
||||||
const defaultsLoaders = [
|
const defaultsLoaders = [
|
||||||
{
|
{
|
||||||
@ -189,6 +191,7 @@ function * generateRoutesAndFiles () {
|
|||||||
]
|
]
|
||||||
this.options.store = fs.existsSync(join(this.srcDir, 'store'))
|
this.options.store = fs.existsSync(join(this.srcDir, 'store'))
|
||||||
let templateVars = {
|
let templateVars = {
|
||||||
|
nuxt: this.options,
|
||||||
uniqBy: _.uniqBy,
|
uniqBy: _.uniqBy,
|
||||||
isDev: this.dev,
|
isDev: this.dev,
|
||||||
router: {
|
router: {
|
||||||
@ -221,7 +224,7 @@ function * generateRoutesAndFiles () {
|
|||||||
templateVars.router.routes = createRoutes(files, this.srcDir)
|
templateVars.router.routes = createRoutes(files, this.srcDir)
|
||||||
if (typeof this.options.router.extendRoutes === 'function') {
|
if (typeof this.options.router.extendRoutes === 'function') {
|
||||||
// let the user extend the routes
|
// let the user extend the routes
|
||||||
this.options.router.extendRoutes(templateVars.router.routes, r)
|
this.options.router.extendRoutes.call(this, templateVars.router.routes, r)
|
||||||
}
|
}
|
||||||
// Routes for Generate command
|
// Routes for Generate command
|
||||||
this.routes = flatRoutes(templateVars.router.routes)
|
this.routes = flatRoutes(templateVars.router.routes)
|
||||||
@ -239,8 +242,14 @@ function * generateRoutesAndFiles () {
|
|||||||
if (this.options.store) {
|
if (this.options.store) {
|
||||||
templatesFiles.push('store.js')
|
templatesFiles.push('store.js')
|
||||||
}
|
}
|
||||||
let moveTemplates = templatesFiles.map((file) => {
|
// Resolve all internal template files relative to app directory
|
||||||
return readFile(r(__dirname, 'app', file), 'utf8')
|
templatesFiles = templatesFiles.map(file => { return {src: r(__dirname, 'app', file), dst: file} })
|
||||||
|
// Add external template files (used in modules)
|
||||||
|
if (Array.isArray(this.options.build.templates)) {
|
||||||
|
templatesFiles = templatesFiles.concat(this.options.build.templates)
|
||||||
|
}
|
||||||
|
let moveTemplates = templatesFiles.map(({src, dst, options}) => {
|
||||||
|
return readFile(src, 'utf8')
|
||||||
.then((fileContent) => {
|
.then((fileContent) => {
|
||||||
const template = _.template(fileContent, {
|
const template = _.template(fileContent, {
|
||||||
imports: {
|
imports: {
|
||||||
@ -248,8 +257,10 @@ function * generateRoutesAndFiles () {
|
|||||||
hash
|
hash
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const content = template(templateVars)
|
const content = template(Object.assign({}, templateVars, {
|
||||||
const path = r(this.dir, '.nuxt', file)
|
options: options || {}
|
||||||
|
}))
|
||||||
|
const path = r(this.dir, '.nuxt', dst)
|
||||||
return writeFile(path, content, 'utf8')
|
return writeFile(path, content, 'utf8')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Fix webpack loop (https://github.com/webpack/watchpack/issues/25#issuecomment-287789288)
|
// Fix webpack loop (https://github.com/webpack/watchpack/issues/25#issuecomment-287789288)
|
||||||
@ -510,7 +521,11 @@ function watchPages () {
|
|||||||
const refreshFiles = _.debounce(() => {
|
const refreshFiles = _.debounce(() => {
|
||||||
co(generateRoutesAndFiles.bind(this))
|
co(generateRoutesAndFiles.bind(this))
|
||||||
}, 200)
|
}, 200)
|
||||||
|
// Watch for internals
|
||||||
this.pagesFilesWatcher = chokidar.watch(patterns, options)
|
this.pagesFilesWatcher = chokidar.watch(patterns, options)
|
||||||
.on('add', refreshFiles)
|
.on('add', refreshFiles)
|
||||||
.on('unlink', refreshFiles)
|
.on('unlink', refreshFiles)
|
||||||
|
// Watch for custom provided files
|
||||||
|
this.customFilesWatcher = chokidar.watch(_.uniq(this.options.build.watch), options)
|
||||||
|
.on('change', refreshFiles)
|
||||||
}
|
}
|
||||||
|
119
lib/module.js
Executable file
119
lib/module.js
Executable file
@ -0,0 +1,119 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
import path from 'path'
|
||||||
|
import fs from 'fs'
|
||||||
|
import {uniq} from 'lodash'
|
||||||
|
import hash from 'hash-sum'
|
||||||
|
import {chainFn} from './utils'
|
||||||
|
|
||||||
|
class Module {
|
||||||
|
constructor (nuxt) {
|
||||||
|
this.nuxt = nuxt
|
||||||
|
this.options = nuxt.options
|
||||||
|
}
|
||||||
|
|
||||||
|
addVendor (vendor) {
|
||||||
|
if (!vendor) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.options.build.vendor = uniq(this.options.build.vendor.concat(vendor))
|
||||||
|
}
|
||||||
|
|
||||||
|
addTemplate (template) {
|
||||||
|
if (!template) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Validate & parse source
|
||||||
|
const src = template.src || template
|
||||||
|
const srcPath = path.parse(src)
|
||||||
|
if (!src || typeof src !== 'string' || !fs.existsSync(src)) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn('[Nuxt] invalid template', template)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Generate unique and human readable dst filename
|
||||||
|
const dst = template.fileName ||
|
||||||
|
(path.basename(srcPath.dir) + '.' + srcPath.name + '.' + hash(src) + '.' + srcPath.ext)
|
||||||
|
// Add to templates list
|
||||||
|
const templateObj = {
|
||||||
|
src,
|
||||||
|
dst,
|
||||||
|
options: template.options
|
||||||
|
}
|
||||||
|
this.options.build.templates.push(templateObj)
|
||||||
|
// Watch template for changes
|
||||||
|
this.addWatch(src)
|
||||||
|
return templateObj
|
||||||
|
}
|
||||||
|
|
||||||
|
addWatch (pattern) {
|
||||||
|
this.options.build.watch.push(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
addPlugin (template) {
|
||||||
|
const {dst} = this.addTemplate(template)
|
||||||
|
// Add to nuxt plugins
|
||||||
|
this.options.plugins.push({
|
||||||
|
src: '~/.nuxt/' + dst,
|
||||||
|
ssr: Boolean(template.ssr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
addServerMiddleware (middleware) {
|
||||||
|
this.options.serverMiddlewares.push(middleware)
|
||||||
|
}
|
||||||
|
|
||||||
|
extendBuild (fn) {
|
||||||
|
this.options.build.extend = chainFn(this.options.build.extend, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
extendRoutes (fn) {
|
||||||
|
this.options.router.extendRoutes = chainFn(this.options.router.extendRoutes, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
installModule (moduleOpts) {
|
||||||
|
if (!moduleOpts) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Allows passing runtime options to each module
|
||||||
|
const options = moduleOpts.options || {}
|
||||||
|
let src = moduleOpts.src || moduleOpts
|
||||||
|
// Resolve module
|
||||||
|
let module
|
||||||
|
try {
|
||||||
|
if (typeof src === 'string') {
|
||||||
|
// Using ~ shorthand modules are resolved from project srcDir
|
||||||
|
if (src.indexOf('~') === 0) {
|
||||||
|
src = path.resolve(this.options.srcDir, src.substr(1))
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-eval
|
||||||
|
module = eval('require')(src)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('[Nuxt] Unable to resolve module', src)
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Validate module
|
||||||
|
if (!(module instanceof Function)) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('[Nuxt] Module should be a function', module)
|
||||||
|
}
|
||||||
|
// Call module with `this` context and pass options
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const result = module.call(this, options, err => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
resolve(module)
|
||||||
|
})
|
||||||
|
if (result && result.then instanceof Function) {
|
||||||
|
return result.then(resolve)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Module
|
28
lib/nuxt.js
28
lib/nuxt.js
@ -6,6 +6,7 @@ import compression from 'compression'
|
|||||||
import fs from 'fs-extra'
|
import fs from 'fs-extra'
|
||||||
import pify from 'pify'
|
import pify from 'pify'
|
||||||
import Server from './server'
|
import Server from './server'
|
||||||
|
import Module from './module'
|
||||||
import * as build from './build'
|
import * as build from './build'
|
||||||
import * as render from './render'
|
import * as render from './render'
|
||||||
import generate from './generate'
|
import generate from './generate'
|
||||||
@ -18,9 +19,16 @@ class Nuxt {
|
|||||||
var defaults = {
|
var defaults = {
|
||||||
dev: true,
|
dev: true,
|
||||||
env: {},
|
env: {},
|
||||||
head: {},
|
head: {
|
||||||
|
meta: [],
|
||||||
|
link: [],
|
||||||
|
style: [],
|
||||||
|
script: []
|
||||||
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
css: [],
|
css: [],
|
||||||
|
modules: [],
|
||||||
|
serverMiddlewares: [],
|
||||||
cache: false,
|
cache: false,
|
||||||
loading: {
|
loading: {
|
||||||
color: 'black',
|
color: 'black',
|
||||||
@ -59,8 +67,11 @@ class Nuxt {
|
|||||||
this.options = _.defaultsDeep(options, defaults)
|
this.options = _.defaultsDeep(options, defaults)
|
||||||
// Env variables
|
// Env variables
|
||||||
this.dev = this.options.dev
|
this.dev = this.options.dev
|
||||||
|
// Explicit srcDir and rootDir
|
||||||
this.dir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
|
this.dir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
|
||||||
this.srcDir = (typeof options.srcDir === 'string' && options.srcDir ? resolve(this.dir, options.srcDir) : this.dir)
|
this.srcDir = (typeof options.srcDir === 'string' && options.srcDir ? resolve(this.dir, options.srcDir) : this.dir)
|
||||||
|
options.rootDir = this.dir
|
||||||
|
options.srcDir = this.srcDir
|
||||||
// If store defined, update store options to true
|
// If store defined, update store options to true
|
||||||
if (fs.existsSync(join(this.srcDir, 'store'))) {
|
if (fs.existsSync(join(this.srcDir, 'store'))) {
|
||||||
this.options.store = true
|
this.options.store = true
|
||||||
@ -99,7 +110,16 @@ class Nuxt {
|
|||||||
this.generate = generate.bind(this)
|
this.generate = generate.bind(this)
|
||||||
// Add this.utils (tests purpose)
|
// Add this.utils (tests purpose)
|
||||||
this.utils = utils
|
this.utils = utils
|
||||||
return this
|
// Add module integration
|
||||||
|
this.module = new Module(this)
|
||||||
|
// Install all modules in sequence and then return `this` instance
|
||||||
|
return utils.sequence(options.modules, this.module.installModule.bind(this.module))
|
||||||
|
.then(() => this)
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('[nuxt] error while initializing modules') // eslint-disable-line no-console
|
||||||
|
console.error(err) // eslint-disable-line no-console
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
close (callback) {
|
close (callback) {
|
||||||
@ -122,6 +142,10 @@ class Nuxt {
|
|||||||
if (this.pagesFilesWatcher) {
|
if (this.pagesFilesWatcher) {
|
||||||
this.pagesFilesWatcher.close()
|
this.pagesFilesWatcher.close()
|
||||||
}
|
}
|
||||||
|
/* istanbul ignore if */
|
||||||
|
if (this.customFilesWatcher) {
|
||||||
|
this.customFilesWatcher.close()
|
||||||
|
}
|
||||||
return co(function * () {
|
return co(function * () {
|
||||||
yield promises
|
yield promises
|
||||||
})
|
})
|
||||||
|
@ -1,15 +1,28 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const http = require('http')
|
const http = require('http')
|
||||||
|
const connect = require('connect')
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
constructor (nuxt) {
|
constructor (nuxt) {
|
||||||
this.nuxt = nuxt
|
this.nuxt = nuxt
|
||||||
this.server = http.createServer(this.render.bind(this))
|
// Initialize
|
||||||
|
this.app = connect()
|
||||||
|
this.server = http.createServer(this.app)
|
||||||
|
// Add Middlewares
|
||||||
|
this.nuxt.options.serverMiddlewares.forEach(m => {
|
||||||
|
if (m instanceof Function) {
|
||||||
|
this.app.use(m)
|
||||||
|
} else if (m && m.path && m.handler) {
|
||||||
|
this.app.use(m.path, m.handler)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Add default render middleware
|
||||||
|
this.app.use(this.render.bind(this))
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
render (req, res) {
|
render (req, res, next) {
|
||||||
this.nuxt.render(req, res)
|
this.nuxt.render(req, res)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
16
lib/utils.js
16
lib/utils.js
@ -57,3 +57,19 @@ export function promisifyRoute (fn) {
|
|||||||
}
|
}
|
||||||
return promise
|
return promise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sequence (tasks, fn) {
|
||||||
|
return tasks.reduce((promise, task) => promise.then(() => fn(task)), Promise.resolve())
|
||||||
|
}
|
||||||
|
|
||||||
|
export function chainFn (base, fn) {
|
||||||
|
if (!(fn instanceof Function)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return function () {
|
||||||
|
if (base instanceof Function) {
|
||||||
|
base.apply(this, arguments)
|
||||||
|
}
|
||||||
|
fn.apply(this, arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"chokidar": "^1.6.1",
|
"chokidar": "^1.6.1",
|
||||||
"co": "^4.6.0",
|
"co": "^4.6.0",
|
||||||
"compression": "^1.6.2",
|
"compression": "^1.6.2",
|
||||||
|
"connect": "^3.6.1",
|
||||||
"css-loader": "^0.28.1",
|
"css-loader": "^0.28.1",
|
||||||
"debug": "^2.6.6",
|
"debug": "^2.6.6",
|
||||||
"extract-text-webpack-plugin": "^2.1.0",
|
"extract-text-webpack-plugin": "^2.1.0",
|
||||||
|
@ -13,7 +13,7 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir: resolve(__dirname, 'fixtures/basic'),
|
||||||
dev: true
|
dev: true
|
||||||
}
|
}
|
||||||
nuxt = new Nuxt(options)
|
nuxt = await new Nuxt(options)
|
||||||
await nuxt.build()
|
await nuxt.build()
|
||||||
server = new nuxt.Server(nuxt)
|
server = new nuxt.Server(nuxt)
|
||||||
server.listen(port, 'localhost')
|
server.listen(port, 'localhost')
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import test from 'ava'
|
import test from 'ava'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
test('Fail with routes() which throw an error', t => {
|
test('Fail with routes() which throw an error', async t => {
|
||||||
const Nuxt = require('../')
|
const Nuxt = require('../')
|
||||||
const options = {
|
const options = {
|
||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir: resolve(__dirname, 'fixtures/basic'),
|
||||||
@ -14,7 +14,7 @@ test('Fail with routes() which throw an error', t => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const nuxt = new Nuxt(options)
|
const nuxt = await new Nuxt(options)
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
var oldExit = process.exit
|
var oldExit = process.exit
|
||||||
var oldCE = console.error // eslint-disable-line no-console
|
var oldCE = console.error // eslint-disable-line no-console
|
||||||
|
@ -17,7 +17,7 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = false
|
config.dev = false
|
||||||
nuxt = new Nuxt(config)
|
nuxt = await new Nuxt(config)
|
||||||
try {
|
try {
|
||||||
await nuxt.generate() // throw an error (of /validate route)
|
await nuxt.generate() // throw an error (of /validate route)
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
|
@ -14,7 +14,7 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
rootDir: resolve(__dirname, 'fixtures/basic'),
|
rootDir: resolve(__dirname, 'fixtures/basic'),
|
||||||
dev: false
|
dev: false
|
||||||
}
|
}
|
||||||
nuxt = new Nuxt(options)
|
nuxt = await new Nuxt(options)
|
||||||
await nuxt.build()
|
await nuxt.build()
|
||||||
server = new nuxt.Server(nuxt)
|
server = new nuxt.Server(nuxt)
|
||||||
server.listen(port, 'localhost')
|
server.listen(port, 'localhost')
|
||||||
@ -45,6 +45,7 @@ test('/stateful', async t => {
|
|||||||
test('/store', async t => {
|
test('/store', async t => {
|
||||||
const { html } = await nuxt.renderRoute('/store')
|
const { html } = await nuxt.renderRoute('/store')
|
||||||
t.true(html.includes('<h1>Vuex Nested Modules</h1>'))
|
t.true(html.includes('<h1>Vuex Nested Modules</h1>'))
|
||||||
|
t.true(html.includes('<p>1</p>'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('/head', async t => {
|
test('/head', async t => {
|
||||||
|
@ -13,7 +13,7 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
rootDir: resolve(__dirname, 'fixtures/children'),
|
rootDir: resolve(__dirname, 'fixtures/children'),
|
||||||
dev: false
|
dev: false
|
||||||
}
|
}
|
||||||
nuxt = new Nuxt(options)
|
nuxt = await new Nuxt(options)
|
||||||
await nuxt.build()
|
await nuxt.build()
|
||||||
server = new nuxt.Server(nuxt)
|
server = new nuxt.Server(nuxt)
|
||||||
server.listen(port, 'localhost')
|
server.listen(port, 'localhost')
|
||||||
|
@ -7,7 +7,7 @@ const readFile = pify(fs.readFile)
|
|||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.before('Init Nuxt.js', async t => {
|
||||||
const Nuxt = require('../')
|
const Nuxt = require('../')
|
||||||
const nuxt = new Nuxt({
|
const nuxt = await new Nuxt({
|
||||||
rootDir: resolve(__dirname, 'fixtures/dynamic-routes'),
|
rootDir: resolve(__dirname, 'fixtures/dynamic-routes'),
|
||||||
dev: false
|
dev: false
|
||||||
})
|
})
|
||||||
|
@ -13,7 +13,7 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
rootDir: resolve(__dirname, 'fixtures/error'),
|
rootDir: resolve(__dirname, 'fixtures/error'),
|
||||||
dev: false
|
dev: false
|
||||||
}
|
}
|
||||||
nuxt = new Nuxt(options)
|
nuxt = await new Nuxt(options)
|
||||||
await nuxt.build()
|
await nuxt.build()
|
||||||
server = new nuxt.Server(nuxt)
|
server = new nuxt.Server(nuxt)
|
||||||
server.listen(port, 'localhost')
|
server.listen(port, 'localhost')
|
||||||
|
4
test/fixtures/basic/pages/store.vue
vendored
4
test/fixtures/basic/pages/store.vue
vendored
@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
<h1>{{ baz }}</h1>
|
<h1>{{ baz }}</h1>
|
||||||
|
<br>
|
||||||
|
<p>{{ $store.state.counter }}</p>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
16
test/fixtures/basic/store/index.js
vendored
Executable file
16
test/fixtures/basic/store/index.js
vendored
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
export const state = () => {
|
||||||
|
return {
|
||||||
|
counter: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
increment (state) {
|
||||||
|
state.counter++
|
||||||
|
}
|
||||||
|
}
|
@ -7,16 +7,16 @@ test('Nuxt.js Class', t => {
|
|||||||
t.is(typeof Nuxt, 'function')
|
t.is(typeof Nuxt, 'function')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Nuxt.js Instance', t => {
|
test('Nuxt.js Instance', async t => {
|
||||||
const nuxt = new Nuxt()
|
const nuxt = await new Nuxt()
|
||||||
t.is(typeof nuxt, 'object')
|
t.is(typeof nuxt, 'object')
|
||||||
t.is(nuxt.dev, true)
|
t.is(nuxt.dev, true)
|
||||||
t.is(typeof nuxt.build, 'function')
|
t.is(typeof nuxt.build, 'function')
|
||||||
t.is(typeof nuxt.generate, 'function')
|
t.is(typeof nuxt.generate, 'function')
|
||||||
})
|
})
|
||||||
|
|
||||||
test.serial('Fail when build not done and try to render', t => {
|
test.serial('Fail when build not done and try to render', async t => {
|
||||||
const nuxt = new Nuxt({
|
const nuxt = await new Nuxt({
|
||||||
dev: false,
|
dev: false,
|
||||||
rootDir: resolve(__dirname, 'fixtures/empty')
|
rootDir: resolve(__dirname, 'fixtures/empty')
|
||||||
})
|
})
|
||||||
@ -36,8 +36,8 @@ test.serial('Fail when build not done and try to render', t => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.serial('Fail to build when no pages/ directory but is in the parent', t => {
|
test.serial('Fail to build when no pages/ directory but is in the parent', async t => {
|
||||||
const nuxt = new Nuxt({
|
const nuxt = await new Nuxt({
|
||||||
dev: false,
|
dev: false,
|
||||||
rootDir: resolve(__dirname, 'fixtures', 'empty', 'pages')
|
rootDir: resolve(__dirname, 'fixtures', 'empty', 'pages')
|
||||||
})
|
})
|
||||||
@ -57,8 +57,8 @@ test.serial('Fail to build when no pages/ directory but is in the parent', t =>
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.serial('Fail to build when no pages/ directory', t => {
|
test.serial('Fail to build when no pages/ directory', async t => {
|
||||||
const nuxt = new Nuxt({
|
const nuxt = await new Nuxt({
|
||||||
dev: false,
|
dev: false,
|
||||||
rootDir: resolve(__dirname)
|
rootDir: resolve(__dirname)
|
||||||
})
|
})
|
||||||
|
@ -5,7 +5,7 @@ let utils
|
|||||||
// Init nuxt.js and create server listening on localhost:4000
|
// Init nuxt.js and create server listening on localhost:4000
|
||||||
test.before('Init Nuxt.js', async t => {
|
test.before('Init Nuxt.js', async t => {
|
||||||
const Nuxt = require('../')
|
const Nuxt = require('../')
|
||||||
let nuxt = new Nuxt({ dev: false })
|
let nuxt = await new Nuxt({ dev: false })
|
||||||
utils = nuxt.utils
|
utils = nuxt.utils
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = false
|
config.dev = false
|
||||||
nuxt = new Nuxt(config)
|
nuxt = await new Nuxt(config)
|
||||||
await nuxt.build()
|
await nuxt.build()
|
||||||
server = new nuxt.Server(nuxt)
|
server = new nuxt.Server(nuxt)
|
||||||
server.listen(port, 'localhost')
|
server.listen(port, 'localhost')
|
||||||
@ -96,11 +96,11 @@ test.after('Closing server and nuxt.js', t => {
|
|||||||
nuxt.close()
|
nuxt.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
test.after('Should be able to start Nuxt with build done', t => {
|
test.after('Should be able to start Nuxt with build done', async t => {
|
||||||
const Nuxt = require('../')
|
const Nuxt = require('../')
|
||||||
const rootDir = resolve(__dirname, 'fixtures/with-config')
|
const rootDir = resolve(__dirname, 'fixtures/with-config')
|
||||||
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
let config = require(resolve(rootDir, 'nuxt.config.js'))
|
||||||
config.rootDir = rootDir
|
config.rootDir = rootDir
|
||||||
config.dev = false
|
config.dev = false
|
||||||
nuxt = new Nuxt(config)
|
nuxt = await new Nuxt(config)
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user