From dbc0f044cfd293aa90e1221dac120fc6d4bc1c7c Mon Sep 17 00:00:00 2001 From: doabit Date: Sun, 7 Aug 2016 10:52:16 +0800 Subject: [PATCH] Update to new version --- .babelrc | 5 +- README.md | 10 ++- build/dev-client.js | 8 -- build/dev-server.js | 63 --------------- build/webpack.base.config.js | 38 ++------- build/webpack.client.config.js | 57 ++++++++++---- build/webpack.dev.config.js | 17 ---- build/webpack.server.config.js | 25 +++--- package.json | 34 ++++---- server.js | 86 ++++++++++++++++----- src/App.vue | 19 +---- src/app.js | 15 ++++ src/client-entry.js | 8 +- src/components/About.vue | 7 +- src/components/{Display.vue => Counter.vue} | 8 ++ src/components/Home.vue | 7 +- src/components/Topics.vue | 18 +++-- src/{router.js => router/index.js} | 12 +-- src/server-entry.js | 25 +++--- src/vuex/actions.js | 10 ++- src/vuex/store.js | 20 +++-- 21 files changed, 227 insertions(+), 265 deletions(-) delete mode 100644 build/dev-client.js delete mode 100644 build/dev-server.js delete mode 100644 build/webpack.dev.config.js create mode 100644 src/app.js rename src/components/{Display.vue => Counter.vue} (54%) rename src/{router.js => router/index.js} (50%) diff --git a/.babelrc b/.babelrc index bb8d835..a5e2e84 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,4 @@ { - "presets": ["es2015-webpack", "stage-2"] -} + "presets": [["es2015", { "modules": false }], "stage-2"], + "ignore": ["node_modules/*"] +} \ No newline at end of file diff --git a/README.md b/README.md index 533698a..59236f6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# vue-ssr-demo +# vue-ssr-starter-kit -> A Vue.js project with vue 2.0 and vue-router@next for server-side rendering. +> A Vue.js project with vue 2.0, vue-router and vuex starter kit for server side rendering. ## Build Setup @@ -15,4 +15,8 @@ npm start ```bash npm install npm run dev -``` \ No newline at end of file +``` + +## License + +[MIT](http://opensource.org/licenses/MIT) \ No newline at end of file diff --git a/build/dev-client.js b/build/dev-client.js deleted file mode 100644 index f9ea897..0000000 --- a/build/dev-client.js +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable */ -var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') - -hotClient.subscribe(function (event) { - if (event.action === 'reload') { - window.location.reload() - } -}) \ No newline at end of file diff --git a/build/dev-server.js b/build/dev-server.js deleted file mode 100644 index 16477aa..0000000 --- a/build/dev-server.js +++ /dev/null @@ -1,63 +0,0 @@ -var path = require('path') -var express = require('express') -var bodyParser = require('body-parser') -var webpack = require('webpack') -var webpackConfig = require('./webpack.dev.config') - -// default port where dev server listens for incoming traffic -var port = process.env.PORT || 3000 - -var app = express() -var compiler = webpack(webpackConfig) - -var devMiddleware = require('webpack-dev-middleware')(compiler, { - publicPath: webpackConfig.output.publicPath, - stats: { - colors: true, - chunks: false - } -}) - -var hotMiddleware = require('webpack-hot-middleware')(compiler) -// force page reload when html-webpack-plugin template changes -compiler.plugin('compilation', function (compilation) { - compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { - hotMiddleware.publish({ action: 'reload' }) - cb() - }) -}) - -app.use(bodyParser.json()) - -// serve webpack bundle output -app.use(devMiddleware) - -// enable hot-reload and state-preserving -// compilation error display -app.use(hotMiddleware) - -app.use(express.static(path.resolve(__dirname, '../dist'))) - -app.get('*', function(req, res) { - var title = "demo" - res.send(` - - - - ${title} - - -
- - - ` - ) -}) - -module.exports = app.listen(port, function (err) { - if (err) { - console.log(err) - return - } - console.log('Listening at http://localhost:' + port + '\n') -}) diff --git a/build/webpack.base.config.js b/build/webpack.base.config.js index 7184afd..62c3fee 100644 --- a/build/webpack.base.config.js +++ b/build/webpack.base.config.js @@ -1,26 +1,18 @@ -var path = require('path') -var webpack = require('webpack') +const path = require('path') module.exports = { + devtool: '#source-map', entry: { - app: './src/client-entry.js' + app: './src/client-entry.js', + vendor: ['vue', 'vue-router', 'vuex', 'vuex-router-sync', 'axios'] }, output: { path: path.resolve(__dirname, '../dist'), - publicPath: '/', + publicPath: '/dist/', filename: 'client-bundle.js' }, - resolve: { - extensions: ['', '.js', '.vue'], - fallback: [path.join(__dirname, '../node_modules')], - alias: { - 'src': path.resolve(__dirname, '../src'), - 'assets': path.resolve(__dirname, '../src/assets'), - 'components': path.resolve(__dirname, '../src/components') - } - }, resolveLoader: { - fallback: [path.join(__dirname, '../node_modules')] + root: path.join(__dirname, '../node_modules'), }, module: { loaders: [ @@ -33,10 +25,6 @@ module.exports = { loader: 'babel', exclude: /node_modules/ }, - { - test: /\.json$/, - loader: 'json' - }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file', @@ -45,15 +33,5 @@ module.exports = { } } ] - }, - plugins: [ - new webpack.DefinePlugin({ - 'process': { - env: { - NODE_ENV: JSON.stringify(process.env.NODE_ENV) - } - } - }) - ], - devtool: '#eval-source-map' -} \ No newline at end of file + } +} diff --git a/build/webpack.client.config.js b/build/webpack.client.config.js index f126759..3b9dcc0 100644 --- a/build/webpack.client.config.js +++ b/build/webpack.client.config.js @@ -1,17 +1,46 @@ +const base = require('./webpack.base.config') const webpack = require('webpack') -const merge = require('webpack-merge') -const baseWebpackConfig = require('./webpack.base.config') -webpackConfig = merge(baseWebpackConfig, {}) +const config = Object.assign({}, base, { + plugins: [ + // strip comments in Vue code + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') + }), + // extract vendor chunks for better caching + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + filename: 'client-vendor-bundle.js' + }) + ] +}) -// if (process.env.NODE_ENV === 'production') { -// webpackConfig.devtool = '#source-map' -// webpackConfig.plugins.push( -// new webpack.optimize.UglifyJsPlugin({ -// compress: { -// warnings: false -// } -// }) -// ) -// } -module.exports = webpackConfig +if (process.env.NODE_ENV === 'production') { + // extract CSS into a single file so it's applied on initial render + const ExtractTextPlugin = require('extract-text-webpack-plugin') + + config.vue = { + loaders: { + css: ExtractTextPlugin.extract({ + loader: "css-loader", + fallbackLoader: "vue-style-loader" + }) + } + } + + config.plugins.push( + new ExtractTextPlugin('styles.css'), + // this is needed in webpack 2 for minifying CSS + new webpack.LoaderOptionsPlugin({ + minimize: true + }), + // minify JS + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + } + }) + ) +} + +module.exports = config diff --git a/build/webpack.dev.config.js b/build/webpack.dev.config.js deleted file mode 100644 index ecaf95b..0000000 --- a/build/webpack.dev.config.js +++ /dev/null @@ -1,17 +0,0 @@ -const webpack = require('webpack') -const merge = require('webpack-merge') -const baseWebpackConfig = require('./webpack.base.config') - -Object.keys(baseWebpackConfig.entry).forEach(function (name) { - baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) -}) - -webpackConfig = merge(baseWebpackConfig, { - plugins: [ - // Webpack 2.0 fixed this mispelling - // new webpack.optimize.OccurrenceOrderPlugin(), - new webpack.HotModuleReplacementPlugin(), - new webpack.NoErrorsPlugin() - ] -}) -module.exports = webpackConfig diff --git a/build/webpack.server.config.js b/build/webpack.server.config.js index b25753a..f1425df 100644 --- a/build/webpack.server.config.js +++ b/build/webpack.server.config.js @@ -1,26 +1,19 @@ const webpack = require('webpack') -const merge = require('webpack-merge') -const baseWebpackConfig = require('./webpack.base.config') +const base = require('./webpack.base.config') -webpackConfig = merge(baseWebpackConfig, { +module.exports = Object.assign({}, base, { target: 'node', - entry: { - app: './src/server-entry.js' - }, - output: { + devtool: null, + entry: './src/server-entry.js', + output: Object.assign({}, base.output, { filename: 'server-bundle.js', libraryTarget: 'commonjs2' - }, + }), + externals: ['axios'], plugins: [ new webpack.DefinePlugin({ - 'process': { - env: { - NODE_ENV: '"production"', - VUE_ENV: '"server"' - } - } + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), + 'process.env.VUE_ENV': '"server"' }) ] }) - -module.exports = webpackConfig diff --git a/package.json b/package.json index aa1a965..3f7b552 100644 --- a/package.json +++ b/package.json @@ -1,42 +1,38 @@ { - "name": "vue-ssr-demo", - "description": "A Vue.js project wuth vue 2.0 and vue-router@next for server-side rendering.", + "name": "vue-ssr-starter-kit", + "description": "A Vue.js project wuth vue 2.0, vue-router and vuex for server side rendering.", "author": "doabit ", "private": true, "scripts": { - "start": "node server", - "dev": "nodemon --watch ./build ./build/dev-server.js", - "build:client": "cross-env NODE_ENV=production webpack --config ./build/webpack.client.config.js", - "build:server": "cross-env NODE_ENV=production webpack --config ./build/webpack.server.config.js", - "build": "cross-env NODE_ENV=production webpack --config ./build/webpack.client.config.js && cross-env NODE_ENV=production webpack --config ./build/webpack.server.config.js" + "start": "NODE_ENV=production node server", + "dev": "node server", + "build:client": "NODE_ENV=production webpack --config ./build/webpack.client.config.js --progress --hide-modules", + "build:server": "NODE_ENV=production webpack --config ./build/webpack.server.config.js --progress --hide-modules", + "build": "npm run build:client && npm run build:server" }, "dependencies": { "axios": "^0.13.1", - "body-parser": "^1.15.2", "express": "^4.14.0", "lru-cache": "^4.0.1", "serialize-javascript": "^1.3.0", "serve-favicon": "^2.3.0", - "vue": "^2.0.0-beta.6", - "vue-resource": "^0.9.3", + "vue": "^2.0.0-beta.7", "vue-router": "^2.0.0-rc.1", "vue-server-renderer": "^2.0.0-beta.6", - "vuex": "^2.0.0-rc.3" + "vuex": "^2.0.0-rc.4", + "vuex-router-sync": "^3.0.0" }, "devDependencies": { - "babel-core": "^6.0.0", + "babel-core": "^6.13.2", "babel-loader": "^6.0.0", - "babel-preset-es2015-webpack": "^6.0.0", + "babel-preset-es2015": "^6.13.2", "babel-preset-stage-2": "^6.13.0", - "cross-env": "^1.0.6", "css-loader": "^0.23.1", + "extract-text-webpack-plugin": "^2.0.0-beta.3", "file-loader": "^0.8.4", - "json-loader": "^0.5.4", - "nodemon": "^1.10.0", "vue-loader": "^9.2.2", "webpack": "^2.1.0-beta.20", - "webpack-dev-server": "^2.1.0-beta.0", - "webpack-hot-middleware": "^2.12.2", - "webpack-merge": "^0.14.1" + "webpack-dev-middleware": "^1.6.1", + "webpack-hot-middleware": "^2.12.2" } } diff --git a/server.js b/server.js index 3c7a8ad..e9a7118 100644 --- a/server.js +++ b/server.js @@ -1,5 +1,3 @@ -'use strict' - process.env.VUE_ENV = 'server' const fs = require('fs') @@ -9,24 +7,72 @@ const favicon = require('serve-favicon') const serialize = require('serialize-javascript') const createBundleRenderer = require('vue-server-renderer').createBundleRenderer -const renderer = createBundleRenderer(fs.readFileSync('./dist/server-bundle.js', 'utf-8'), { - cache: require('lru-cache')({ max: 10000 }) -}) - -const stats = [] +let renderer +function createRenderer (fs) { + const bundlePath = path.resolve(__dirname, 'dist/server-bundle.js') + return createBundleRenderer(fs.readFileSync(bundlePath, 'utf-8')) +} const app = express() -app.use(express.static(path.resolve(__dirname, 'dist'))) -app.use(favicon(path.resolve(__dirname, 'dist/logo.png'))) +if (process.env.NODE_ENV !== 'production') { + const webpack = require('webpack') + const clientConfig = require('./build/webpack.client.config') + + clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app] + clientConfig.plugins.push( + new webpack.HotModuleReplacementPlugin(), + new webpack.NoErrorsPlugin() + ) + + const clientCompiler = webpack(clientConfig) + app.use(require('webpack-dev-middleware')(clientCompiler, { + publicPath: clientConfig.output.publicPath, + stats: { + colors: true, + chunks: false + } + })) + app.use(require('webpack-hot-middleware')(clientCompiler)) + + // watch and update server renderer + const MFS = require('memory-fs') + const serverConfig = require('./build/webpack.server.config') + const serverCompiler = webpack(serverConfig) + const mfs = new MFS() + serverCompiler.outputFileSystem = mfs + serverCompiler.watch({}, (err, stats) => { + if (err) throw err + stats = stats.toJson() + stats.errors.forEach(err => console.error(err)) + stats.warnings.forEach(err => console.warn(err)) + renderer = createRenderer(mfs) + }) +} else { + app.use('/dist', express.static(path.resolve(__dirname, 'dist'))) + // create server renderer from real fs + renderer = createRenderer(fs) +} + +app.use(favicon(path.resolve(__dirname, 'src/assets/logo.png'))) app.get('*', (req, res) => { - const start = Date.now() + var s = Date.now() const context = { url: req.url } const renderStream = renderer.renderToStream(context) let firstChunk = true - res.write('') + res.write(` + + + + vue-2.0-ssr-demo + + ${process.env.NODE_ENV === 'production' + ? `` + : ``} + + `) renderStream.on('data', chunk => { if (firstChunk) { @@ -42,11 +88,12 @@ app.get('*', (req, res) => { }) renderStream.on('end', () => { - res.end(``) - const used = Date.now() - start - stats.push(used) - console.log(`request used: ${(Date.now() - start)}ms`) - console.log(`average: ${(stats.reduce((s, t) => s + t, 0) / stats.length).toFixed(2)}ms`) + res.end(` + + + ` + ) + console.log(`whole request: ${Date.now() - s}ms`) }) renderStream.on('error', err => { @@ -54,6 +101,7 @@ app.get('*', (req, res) => { }) }) -app.listen(3000, () => { - console.log('ready at localhost:3000') -}) \ No newline at end of file +const port = process.env.PORT || 3000 +app.listen(port, () => { + console.log(`server started at http://localhost:${port}`) +}) diff --git a/src/App.vue b/src/App.vue index d24959b..171a451 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,33 +1,16 @@ - -