watch pages/ dir to updates routes dynamically

This commit is contained in:
Sébastien Chopin 2016-11-10 03:38:11 +01:00
parent d88948bdea
commit c97c4ec32e
13 changed files with 88 additions and 38 deletions

View File

@ -82,5 +82,5 @@ test('Route / exits and render HTML', async t => {
// Close server and ask nuxt to stop listening to file changes
test.after('Closing server and nuxt.js', t => {
server.close()
nuxt.stop()
nuxt.close()
})

View File

@ -1,7 +1,6 @@
/*!
* nuxt.js
* MIT Licensed
*/
/*
** nuxt.js
*/
'use strict'

View File

@ -1,3 +1,5 @@
'use strict'
require('es6-promise').polyfill()
require('es6-object-assign').polyfill()
import Vue from 'vue'

View File

@ -1,3 +1,5 @@
'use strict'
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'

View File

@ -1,3 +1,5 @@
'use strict'
import Vue from 'vue'
import Router from 'vue-router'
import Meta from 'vue-meta'

View File

@ -1,3 +1,5 @@
'use strict'
const debug = require('debug')('nuxt:render')
import Vue from 'vue'
import { pick } from 'lodash'

View File

@ -2,7 +2,9 @@
const debug = require('debug')('nuxt:build')
const _ = require('lodash')
const co = require('co')
const del = require('del')
const chokidar = require('chokidar')
const fs = require('fs')
const glob = require('glob-promise')
const hash = require('hash-sum')
@ -90,6 +92,34 @@ module.exports = function * () {
if (!this.dev) {
yield mkdirp(r(this.dir, '.nuxt/dist'))
}
// Resolve custom routes component path
this.options.routes.forEach((route) => {
if (route.component.slice(-4) !== '.vue') {
route.component = route.component + '.vue'
}
route.component = r(this.dir, route.component)
})
// Generate routes and interpret the template files
yield generateRoutesAndFiles.call(this)
/*
** Generate .nuxt/dist/ files
*/
if (this.dev) {
debug('Adding webpack middlewares...')
createWebpackMiddlewares.call(this)
webpackWatchAndUpdate.call(this)
watchPages.call(this)
} else {
debug('Building files...')
yield [
webpackRunClient.call(this),
webpackRunServer.call(this)
]
}
}
function * generateRoutesAndFiles () {
debug('Generating routes...')
/*
** Generate routes based on files
*/
@ -98,24 +128,14 @@ module.exports = function * () {
files.forEach((file) => {
let path = file.replace(/^pages/, '').replace(/index\.vue$/, '/').replace(/\.vue$/, '').replace(/\/{2,}/g, '/')
if (path[1] === '_') return
routes.push({ path: path, component: file })
})
this.options.routes.forEach((route) => {
if (route.component.slice(-4) !== '.vue') {
route.component = route.component + '.vue'
}
route.component = r(this.dir, route.component)
})
this.options.routes = routes.concat(this.options.routes)
// TODO: check .children
this.options.routes.forEach((route) => {
route._component = r(this.dir, route.component)
route._name = '_' + hash(route._component)
route.component = route._name
routes.push({ path: path, component: r(this.dir, file) })
})
// Concat pages routes and custom routes in this.routes
this.routes = routes.concat(this.options.routes)
/*
** Interpret and move template files to .nuxt/
*/
debug('Generating files...')
let templatesFiles = [
'App.vue',
'client.js',
@ -135,8 +155,15 @@ module.exports = function * () {
Loading: r(__dirname, '..', 'app', 'components', 'Loading.vue'),
ErrorPage: r(__dirname, '..', '..', 'pages', (this.dev ? '_error-debug.vue' : '_error.vue'))
},
routes: this.options.routes
routes: this.routes
}
// Format routes for the lib/app/router.js template
// TODO: check .children
templateVars.routes.forEach((route) => {
route._component = route.component
route._name = '_' + hash(route._component)
route.component = route._name
})
if (this.options.store) {
templateVars.storePath = r(this.dir, 'store')
}
@ -157,21 +184,6 @@ module.exports = function * () {
})
})
yield moveTemplates
debug('Files moved!')
/*
** Generate .nuxt/dist/ files
*/
if (this.dev) {
debug('Adding webpack middlewares...')
createWebpackMiddlewares.call(this)
webpackWatchAndUpdate.call(this)
} else {
debug('Building files...')
yield [
webpackRunClient.call(this),
webpackRunServer.call(this)
]
}
}
function getWebpackClientConfig () {
@ -187,7 +199,7 @@ function getWebpackServerConfig () {
function createWebpackMiddlewares () {
const clientConfig = getWebpackClientConfig.call(this)
// setup on the fly compilation + hot-reload
clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app]
clientConfig.entry.app = ['webpack-hot-middleware/client?reload=true', clientConfig.entry.app]
clientConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
@ -265,3 +277,22 @@ function createRenderer (bundle) {
this.renderToString = pify(this.renderer.renderToString)
this.renderToStream = this.renderer.renderToStream
}
function watchPages () {
const patterns = [ r(this.dir, 'pages/*.vue'), r(this.dir, 'pages/**/*.vue') ]
const options = {
ignored: '**/_*.vue',
ignoreInitial: true
}
const refreshFiles = _.debounce(() => {
console.log('Reload files', this.routes.length)
var d = Date.now()
co(generateRoutesAndFiles.bind(this))
.then(() => {
console.log('Time to gen:' + (Date.now() - d) + 'ms')
})
}, 200)
this.pagesFilesWatcher = chokidar.watch(patterns, options)
.on('add', refreshFiles)
.on('unlink', refreshFiles)
}

View File

@ -1,3 +1,5 @@
'use strict'
const vueLoaderConfig = require('./vue-loader.config')
const { join } = require('path')

View File

@ -1,3 +1,5 @@
'use strict'
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const base = require('./base.config')

View File

@ -1,3 +1,5 @@
'use strict'
const webpack = require('webpack')
const base = require('./base.config')
const { uniq } = require('lodash')

View File

@ -1,3 +1,5 @@
'use strict'
module.exports = function () {
let config = {
postcss: [

View File

@ -133,7 +133,7 @@ class Nuxt {
})
}
stop (callback) {
close (callback) {
let promises = []
if (this.webpackDevMiddleware) {
const p = new Promise((resolve, reject) => {
@ -147,6 +147,9 @@ class Nuxt {
})
promises.push(p)
}
if (this.pagesFilesWatcher) {
this.pagesFilesWatcher.close()
}
return co(function * () {
yield promises
})

View File

@ -1,6 +1,6 @@
{
"name": "nuxt",
"version": "0.3.0",
"version": "0.3.1",
"description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)",
"main": "index.js",
"license": "MIT",
@ -22,6 +22,7 @@
"babel-loader": "^6.2.7",
"babel-preset-es2015": "^6.18.0",
"babel-preset-stage-2": "^6.18.0",
"chokidar": "^1.6.1",
"co": "^4.6.0",
"cross-spawn": "^5.0.1",
"css-loader": "^0.25.0",