From da6335e22381a88c189c67c8b8fe6462eeb4e0d8 Mon Sep 17 00:00:00 2001 From: linhs Date: Tue, 2 Apr 2019 14:39:04 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=90=AD=E5=BB=BA=20ssr?= =?UTF-8?q?=20=E6=B5=81=E7=A8=8B=EF=BC=8C=E4=BD=86=E6=98=AF=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E4=B8=80=E4=BA=9B=E9=97=AE=E9=A2=98=E6=9C=AA=E8=A7=A3?= =?UTF-8?q?=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/webpack.config.client.js | 2 ++ build/webpack.config.server.js | 1 + client/config/routes.js | 10 +++++--- client/create-app.js | 23 +++++++++++++++++ client/server-entry.js | 16 ++++++++++++ package.json | 3 ++- server/routes/dev-ssr.js | 47 ++++++++++++++++++++++------------ server/routes/server-render.js | 20 +++++++++++++++ server/server-template.ejs | 6 +++-- server/server.js | 13 +++++++++- 10 files changed, 116 insertions(+), 25 deletions(-) create mode 100644 client/create-app.js create mode 100644 server/routes/server-render.js diff --git a/build/webpack.config.client.js b/build/webpack.config.client.js index 682fada..83ba9be 100644 --- a/build/webpack.config.client.js +++ b/build/webpack.config.client.js @@ -48,6 +48,7 @@ let config; if (isDev) { // webpack-merge 不影响 baseConfig,因为产生的是新结果 config = webpackMerge(baseConfig, { + mode: 'development', devtool: '#cheap-module-eval-source-map', devServer, module: { @@ -96,6 +97,7 @@ if (isDev) { }); } else { config = webpackMerge(baseConfig, { + mode: 'production', entry: { // 将类库与第三方依赖单独打包成 vendor,因为如果跟业务代码混在一起,那么由于业务经常更新所以导致这些都无法长期缓存 app: path.join(__dirname, '../client/index.js'), diff --git a/build/webpack.config.server.js b/build/webpack.config.server.js index 78a30cf..25bbcda 100644 --- a/build/webpack.config.server.js +++ b/build/webpack.config.server.js @@ -13,6 +13,7 @@ const baseConfig = require('./webpack.config.base'); const VueServerPlugin = require('vue-server-renderer/server-plugin') const config = webpackMerge(baseConfig, { + mode: 'none', entry: path.join(__dirname, '../client/server-entry.js'), target: 'node', // 服务端渲染必须传 devtool: 'source-map', diff --git a/client/config/routes.js b/client/config/routes.js index 337c82a..809364c 100644 --- a/client/config/routes.js +++ b/client/config/routes.js @@ -1,5 +1,5 @@ -// import Todo from '../views/todo/todo.vue' -// import Login from '../views/login/login.vue' +import Todo from '../views/todo/todo.vue' +import Login from '../views/login/login.vue' export default [ { // 默认根路径跳转至 app @@ -8,10 +8,12 @@ export default [ }, { path: '/app', - component: () => import('../views/todo/todo.vue'), + component: Todo, + // component: () => import('../views/todo/todo.vue'), }, { path: '/login', - component: () => import('../views/login/login.vue'), + component: Login, + // component: () => import('../views/login/login.vue'), }, ] diff --git a/client/create-app.js b/client/create-app.js new file mode 100644 index 0000000..fe7a758 --- /dev/null +++ b/client/create-app.js @@ -0,0 +1,23 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' +import Vuex from 'vuex' + +import App from './app.vue' +import createStore from './store/store' +import createRouter from './config/router' + +import './assets/styles/global.less' + +Vue.use(VueRouter) +Vue.use(Vuex) + +export default () => { + const router = createRouter() + const store = createStore() + const app = new Vue({ + router, + store, + render: h => h(App), + }) + return { app, router, store } +} diff --git a/client/server-entry.js b/client/server-entry.js index e69de29..35c8c9f 100644 --- a/client/server-entry.js +++ b/client/server-entry.js @@ -0,0 +1,16 @@ +import createApp from './create-app' + +// 这里的 context 等于 server-render 里的 context +export default context => { + const { app, router, store } = createApp() + return new Promise((resolve, reject) => { + router.push(context.url) // 给路由推一条记录,才能进入路由调用组件 + router.onReady(() => { + const matchedComponents = router.getMatchedComponents() + if (!matchedComponents.length) { + reject(new Error('no component matched')) + } + resolve(app) + }) + }) +} diff --git a/package.json b/package.json index 96c88ff..f81d62d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "clean": "rimraf dist", "lint": "eslint --ext .js --ext .jsx --ext .vue client/", "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue client/", - "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js" + "dev:client": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js", + "dev:server": "cross-env NODE_ENV=development node server/server.js" }, "husky": { "hooks": { diff --git a/server/routes/dev-ssr.js b/server/routes/dev-ssr.js index 388ac76..50dc753 100644 --- a/server/routes/dev-ssr.js +++ b/server/routes/dev-ssr.js @@ -1,13 +1,14 @@ const router = require('express').Router() + const path = require('path') const fs = require('fs') -const ejs = require('ejs') const axios = require('axios') // memory-fs 这个库跟 fs 几乎一样,唯一区别是它不会把文件写进磁盘上,而是保存在内存中 const MemoryFS = require('memory-fs') const webpack = require('webpack') const VueServerRenderer = require('vue-server-renderer') +const serverRender = require('./server-render') const serverConfig = require('../../build/webpack.config.server') const serverCompiler = webpack(serverConfig) @@ -21,30 +22,42 @@ serverCompiler.watch({}, (err, stats) => { } stats = stats.toJson() // 如果存在 eslint 的错误,它不是放在 err 中,而是 toJson 中 - stats.hasErrors.forEach(err => console.log(err)) - stats.hasWarnings.forEach(warning => console.log(warning)) + stats.errors.forEach(err => console.log(err)) + stats.warnings.forEach(warning => console.log(warning)) const bundlePath = path.join( serverConfig.output.path, 'vue-ssr-server-bundle.json', // 这是默认的文件名 ) bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8')) + console.log('new bundle generated') }) -const handleSSR = async (req, res, next) => { - // 什么时候不存在,就是服务刚启动的时候,webpack 才开始打包,此时 bundle 不存在 - if (!bundle) { - res.send('先等会,别着急 ...') - } +const handleSSR = async (req, res) => { + try { + // 什么时候不存在,就是服务刚启动的时候,webpack 才开始打包,此时 bundle 不存在 + if (!bundle) { + res.send('先等会,别着急 ...') + } - const clientManifestResp = await axios.get( - 'http://127.0.0.1:8000/vue-ssr-client-manifest.json' - ) - const clientManifest = clientManifestResp.data + const clientManifestResp = await axios.get( + 'http://127.0.0.1:8000/vue-ssr-client-manifest.json' + ) + const clientManifest = clientManifestResp.data + + const template = fs.readFileSync(path.join(__dirname, '../server-template.ejs'), 'utf-8') + const renderer = VueServerRenderer.createBundleRenderer(bundle, { + inject: false, + clientManifest, + }) - const template = fs.readFileSync(path.join('../server-template.ejs')) - const renderer = VueServerRenderer.createBundleRenderer(bundle, { - inject: false, - clientManifest, - }) + await serverRender(req, res, renderer, template) + } catch (err) { + console.log('--------------- err in dev-ssr ---------------') + console.log(err) + } } + +router.get('*', handleSSR) + +module.exports = router diff --git a/server/routes/server-render.js b/server/routes/server-render.js new file mode 100644 index 0000000..8ba54a1 --- /dev/null +++ b/server/routes/server-render.js @@ -0,0 +1,20 @@ +const ejs = require('ejs') + +module.exports = async (req, res, renderer, template) => { + res.setHeader('Content-Type', 'text/html') + const context = { url: req.path } + try { + // renderToString 会给 context 加入很多属性,例如 renderStyles + const appString = await renderer.renderToString(context) + const html = ejs.render(template, { + appString, + style: context.renderStyles(), + scripts: context.renderScripts(), + }) + res.send(html) + } catch (err) { + console.log('--------------- err in server-render ---------------') + console.error(err) + throw err + } +} diff --git a/server/server-template.ejs b/server/server-template.ejs index a148fe6..10e4c41 100644 --- a/server/server-template.ejs +++ b/server/server-template.ejs @@ -4,9 +4,11 @@ - Document + vue-ssr-learning + <%- style %> - + <%- appString %> + <%- scripts %> diff --git a/server/server.js b/server/server.js index d5f8bc8..b209167 100644 --- a/server/server.js +++ b/server/server.js @@ -1,11 +1,13 @@ const express = require('express') const app = express() +const pageRouter = require('./routes/dev-ssr') + const isDev = process.env.NODE_ENV === 'development' app.use((req, res, next) => { try { - console.log(req) + console.log(`request with path: ${req.path}`) next() } catch (err) { console.error(err) @@ -17,3 +19,12 @@ app.use((req, res, next) => { } } }) + +app.use('*', pageRouter) + +const HOST = process.env.HOST || '0.0.0.0' +const PORT = process.env.PORT || 3333 + +app.listen(PORT, HOST, () => { + console.log(`server is listening on ${HOST}:${PORT}`) +}) From 4b839995db70297ebe118ef495e455f8b972b617 Mon Sep 17 00:00:00 2001 From: linhs Date: Tue, 2 Apr 2019 18:23:15 +0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E8=B7=AF=E7=94=B1=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E5=87=BA=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/webpack.config.server.js | 44 ++++++++++++++++++++++++---------- client/config/routes.js | 12 +++++----- package-lock.json | 16 +++++++++++++ package.json | 2 ++ 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/build/webpack.config.server.js b/build/webpack.config.server.js index 25bbcda..afa991e 100644 --- a/build/webpack.config.server.js +++ b/build/webpack.config.server.js @@ -5,6 +5,7 @@ const webpack = require('webpack'); const webpackMerge = require('webpack-merge'); // 将非 JS 的文件单独打包分离出来,这里主要是希望单独引入 CSS const ExtractPlugin = require('extract-text-webpack-plugin'); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const baseConfig = require('./webpack.config.base'); // windows npm script 设置变量是通过 set NODE_ENV=production // mac npm script 设置变量是 NODE_ENV=production NODE_ENV=production @@ -28,28 +29,47 @@ const config = webpackMerge(baseConfig, { externals: Object.keys(require('../package.json').dependencies), module: { rules: [ + // { // 因为 vue-style-loader 是把 CSS 通过 JS 注入到 dom + // // 但是 node 端没有 dom 环境,那么就会报错 + // // 所以单独打包出来 + // test: /\.less$/, + // use: ExtractPlugin.extract({ + // fallback: 'vue-style-loader', + // use: [ + // 'css-loader', + // { + // loader: 'postcss-loader', + // options: { + // sourceMap: true, + // }, + // }, + // 'less-loader', + // ], + // }), + // }, { // 因为 vue-style-loader 是把 CSS 通过 JS 注入到 dom // 但是 node 端没有 dom 环境,那么就会报错 // 所以单独打包出来 test: /\.less$/, - use: ExtractPlugin.extract({ - fallback: 'vue-style-loader', - use: [ - 'css-loader', - { - loader: 'postcss-loader', - options: { - sourceMap: true, - }, + use: [ + 'null-loader', + 'css-loader', + { + loader: 'postcss-loader', + options: { + sourceMap: true, }, - 'less-loader', - ], - }), + }, + 'less-loader', + ], }, ], }, plugins: [ new ExtractPlugin('styles.[hash:8].css'), + // new MiniCssExtractPlugin({ + // filename: 'styles.[hash:8].css', + // }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), 'process.env.VUE_ENV': '"server"', diff --git a/client/config/routes.js b/client/config/routes.js index 809364c..e734d13 100644 --- a/client/config/routes.js +++ b/client/config/routes.js @@ -1,5 +1,5 @@ -import Todo from '../views/todo/todo.vue' -import Login from '../views/login/login.vue' +// import Todo from '../views/todo/todo.vue' +// import Login from '../views/login/login.vue' export default [ { // 默认根路径跳转至 app @@ -8,12 +8,12 @@ export default [ }, { path: '/app', - component: Todo, - // component: () => import('../views/todo/todo.vue'), + // component: Todo, + component: () => import('../views/todo/todo.vue'), }, { path: '/login', - component: Login, - // component: () => import('../views/login/login.vue'), + // component: Login, + component: () => import('../views/login/login.vue'), }, ] diff --git a/package-lock.json b/package-lock.json index 014bc18..9183ade 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5757,6 +5757,17 @@ "integrity": "sha1-CRP/CxIdtE71hIJCw4u7NdRMq94=", "dev": true }, + "mini-css-extract-plugin": { + "version": "0.5.0", + "resolved": "http://registry.npm.taobao.org/mini-css-extract-plugin/download/mini-css-extract-plugin-0.5.0.tgz", + "integrity": "sha1-rABZsCuWklFaY3EVsMyf7To1x7A=", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + } + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "http://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.1.tgz", @@ -6035,6 +6046,11 @@ "boolbase": "~1.0.0" } }, + "null-loader": { + "version": "0.1.1", + "resolved": "http://registry.npm.taobao.org/null-loader/download/null-loader-0.1.1.tgz", + "integrity": "sha1-F76av80/8OFRL2/Er8sfUDk3j64=" + }, "num2fraction": { "version": "1.2.2", "resolved": "http://registry.npm.taobao.org/num2fraction/download/num2fraction-1.2.2.tgz", diff --git a/package.json b/package.json index f81d62d..c9cc820 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "axios": "^0.18.0", "ejs": "^2.6.1", "express": "^4.16.4", + "null-loader": "^0.1.1", "vue": "^2.6.10", "vue-router": "^3.0.2", "vue-server-renderer": "^2.6.10", @@ -58,6 +59,7 @@ "less": "^3.9.0", "less-loader": "^4.1.0", "memory-fs": "^0.4.1", + "mini-css-extract-plugin": "^0.5.0", "postcss-loader": "^3.0.0", "rimraf": "^2.6.3", "style-loader": "^0.23.1", From da351d4e924b7e77c968479a2e1f50610e0a69c7 Mon Sep 17 00:00:00 2001 From: linhs Date: Wed, 3 Apr 2019 10:12:50 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=E8=B2=8C=E4=BC=BC=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86=20js=20=E6=89=93=E5=8C=85=E6=96=87=E4=BB=B6=E6=98=AF?= =?UTF-8?q?=20html=20=E4=BB=A3=E7=A0=81=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/webpack.config.base.js | 1 + build/webpack.config.server.js | 24 ------------------------ package-lock.json | 14 ++------------ package.json | 3 +-- server/routes/dev-ssr.js | 2 +- server/server-template.ejs | 4 +++- 6 files changed, 8 insertions(+), 40 deletions(-) diff --git a/build/webpack.config.base.js b/build/webpack.config.base.js index f9b2168..5371791 100644 --- a/build/webpack.config.base.js +++ b/build/webpack.config.base.js @@ -11,6 +11,7 @@ const config = { output: { filename: 'bundle.[hash:8].js', path: path.join(__dirname, '../dist'), + publicPath: 'http://127.0.0.1:8000/public/', }, module: { rules: [ diff --git a/build/webpack.config.server.js b/build/webpack.config.server.js index afa991e..067f68b 100644 --- a/build/webpack.config.server.js +++ b/build/webpack.config.server.js @@ -4,8 +4,6 @@ const path = require('path'); const webpack = require('webpack'); const webpackMerge = require('webpack-merge'); // 将非 JS 的文件单独打包分离出来,这里主要是希望单独引入 CSS -const ExtractPlugin = require('extract-text-webpack-plugin'); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const baseConfig = require('./webpack.config.base'); // windows npm script 设置变量是通过 set NODE_ENV=production // mac npm script 设置变量是 NODE_ENV=production NODE_ENV=production @@ -29,24 +27,6 @@ const config = webpackMerge(baseConfig, { externals: Object.keys(require('../package.json').dependencies), module: { rules: [ - // { // 因为 vue-style-loader 是把 CSS 通过 JS 注入到 dom - // // 但是 node 端没有 dom 环境,那么就会报错 - // // 所以单独打包出来 - // test: /\.less$/, - // use: ExtractPlugin.extract({ - // fallback: 'vue-style-loader', - // use: [ - // 'css-loader', - // { - // loader: 'postcss-loader', - // options: { - // sourceMap: true, - // }, - // }, - // 'less-loader', - // ], - // }), - // }, { // 因为 vue-style-loader 是把 CSS 通过 JS 注入到 dom // 但是 node 端没有 dom 环境,那么就会报错 // 所以单独打包出来 @@ -66,10 +46,6 @@ const config = webpackMerge(baseConfig, { ], }, plugins: [ - new ExtractPlugin('styles.[hash:8].css'), - // new MiniCssExtractPlugin({ - // filename: 'styles.[hash:8].css', - // }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), 'process.env.VUE_ENV': '"server"', diff --git a/package-lock.json b/package-lock.json index 9183ade..c4376cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5757,17 +5757,6 @@ "integrity": "sha1-CRP/CxIdtE71hIJCw4u7NdRMq94=", "dev": true }, - "mini-css-extract-plugin": { - "version": "0.5.0", - "resolved": "http://registry.npm.taobao.org/mini-css-extract-plugin/download/mini-css-extract-plugin-0.5.0.tgz", - "integrity": "sha1-rABZsCuWklFaY3EVsMyf7To1x7A=", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - } - }, "minimalistic-assert": { "version": "1.0.1", "resolved": "http://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.1.tgz", @@ -6049,7 +6038,8 @@ "null-loader": { "version": "0.1.1", "resolved": "http://registry.npm.taobao.org/null-loader/download/null-loader-0.1.1.tgz", - "integrity": "sha1-F76av80/8OFRL2/Er8sfUDk3j64=" + "integrity": "sha1-F76av80/8OFRL2/Er8sfUDk3j64=", + "dev": true }, "num2fraction": { "version": "1.2.2", diff --git a/package.json b/package.json index c9cc820..d84289e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "axios": "^0.18.0", "ejs": "^2.6.1", "express": "^4.16.4", - "null-loader": "^0.1.1", "vue": "^2.6.10", "vue-router": "^3.0.2", "vue-server-renderer": "^2.6.10", @@ -59,7 +58,7 @@ "less": "^3.9.0", "less-loader": "^4.1.0", "memory-fs": "^0.4.1", - "mini-css-extract-plugin": "^0.5.0", + "null-loader": "^0.1.1", "postcss-loader": "^3.0.0", "rimraf": "^2.6.3", "style-loader": "^0.23.1", diff --git a/server/routes/dev-ssr.js b/server/routes/dev-ssr.js index 50dc753..851720b 100644 --- a/server/routes/dev-ssr.js +++ b/server/routes/dev-ssr.js @@ -41,7 +41,7 @@ const handleSSR = async (req, res) => { } const clientManifestResp = await axios.get( - 'http://127.0.0.1:8000/vue-ssr-client-manifest.json' + 'http://127.0.0.1:8000/public/vue-ssr-client-manifest.json' ) const clientManifest = clientManifestResp.data diff --git a/server/server-template.ejs b/server/server-template.ejs index 10e4c41..1e71cda 100644 --- a/server/server-template.ejs +++ b/server/server-template.ejs @@ -8,7 +8,9 @@ <%- style %> - <%- appString %> +
+ <%- appString %> +
<%- scripts %> From 0db9234788618583a907baa38a3dadec1a200322 Mon Sep 17 00:00:00 2001 From: linhs Date: Wed, 3 Apr 2019 10:50:31 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=E6=A0=B7=E5=BC=8F=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E5=8D=95=E7=8B=AC=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/webpack.config.client.js | 30 ++++++++++++++++-------------- build/webpack.config.server.js | 3 ++- package-lock.json | 17 +++++++++++------ package.json | 2 +- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/build/webpack.config.client.js b/build/webpack.config.client.js index 83ba9be..d094882 100644 --- a/build/webpack.config.client.js +++ b/build/webpack.config.client.js @@ -5,7 +5,8 @@ const webpack = require('webpack'); const webpackMerge = require('webpack-merge'); const HtmlPlugin = require('html-webpack-plugin'); // 将非 JS 的文件单独打包分离出来,这里主要是希望单独引入 CSS -const ExtractPlugin = require('extract-text-webpack-plugin'); +// const ExtractPlugin = require('extract-text-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const baseConfig = require('./webpack.config.base'); const VueClientPlugin = require('vue-server-renderer/client-plugin'); @@ -112,24 +113,25 @@ if (isDev) { rules: [ { test: /\.less$/, - use: ExtractPlugin.extract({ - fallback: 'vue-style-loader', - use: [ - 'css-loader', - { - loader: 'postcss-loader', - options: { - sourceMap: true, - }, + use: [ + MiniCssExtractPlugin.loader, + 'css-loader', + { + loader: 'postcss-loader', + options: { + sourceMap: true, }, - 'less-loader', - ], - }), + }, + 'less-loader', + ], }, ], }, plugins: defaultPlugins.concat([ - new ExtractPlugin('styles.[hash:8].css'), + new MiniCssExtractPlugin({ + filename: 'styles.[contentHash:8].css' + }), + // new ExtractPlugin('styles.[hash:8].css'), // 在 webpack3 是 webpack.optimize.CommonsChunkPlugin new webpack.optimize.SplitChunksPlugin({ name: 'runtime', diff --git a/build/webpack.config.server.js b/build/webpack.config.server.js index 067f68b..71b008f 100644 --- a/build/webpack.config.server.js +++ b/build/webpack.config.server.js @@ -32,7 +32,8 @@ const config = webpackMerge(baseConfig, { // 所以单独打包出来 test: /\.less$/, use: [ - 'null-loader', + 'vue-style-loader', + // 'null-loader', 'css-loader', { loader: 'postcss-loader', diff --git a/package-lock.json b/package-lock.json index c4376cb..2ad0c18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5757,6 +5757,17 @@ "integrity": "sha1-CRP/CxIdtE71hIJCw4u7NdRMq94=", "dev": true }, + "mini-css-extract-plugin": { + "version": "0.5.0", + "resolved": "http://registry.npm.taobao.org/mini-css-extract-plugin/download/mini-css-extract-plugin-0.5.0.tgz", + "integrity": "sha1-rABZsCuWklFaY3EVsMyf7To1x7A=", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + } + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "http://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.1.tgz", @@ -6035,12 +6046,6 @@ "boolbase": "~1.0.0" } }, - "null-loader": { - "version": "0.1.1", - "resolved": "http://registry.npm.taobao.org/null-loader/download/null-loader-0.1.1.tgz", - "integrity": "sha1-F76av80/8OFRL2/Er8sfUDk3j64=", - "dev": true - }, "num2fraction": { "version": "1.2.2", "resolved": "http://registry.npm.taobao.org/num2fraction/download/num2fraction-1.2.2.tgz", diff --git a/package.json b/package.json index d84289e..bd2ee5f 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "less": "^3.9.0", "less-loader": "^4.1.0", "memory-fs": "^0.4.1", - "null-loader": "^0.1.1", + "mini-css-extract-plugin": "^0.5.0", "postcss-loader": "^3.0.0", "rimraf": "^2.6.3", "style-loader": "^0.23.1", From 5a994bec3d621d52a111f8dccfdb365cb3fab970 Mon Sep 17 00:00:00 2001 From: linhs Date: Wed, 3 Apr 2019 11:52:17 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=AE=8C=E6=88=90=20ssr=20=E8=AF=BE?= =?UTF-8?q?=E7=A8=8B=E7=AB=A0=E8=8A=82=205-4=EF=BC=8C=E5=B9=B6=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E4=BF=AE=E5=A4=8D=E4=B9=8B=E5=89=8D=E9=81=97=E7=95=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/webpack.config.base.js | 2 +- build/webpack.config.server.js | 1 - favicon.ico | Bin 0 -> 16958 bytes nodemon.json | 16 + package-lock.json | 552 +++++++++++++++++++++++++++++++++ package.json | 5 +- server/server-template.ejs | 1 + server/server.js | 9 + 8 files changed, 583 insertions(+), 3 deletions(-) create mode 100644 favicon.ico create mode 100644 nodemon.json diff --git a/build/webpack.config.base.js b/build/webpack.config.base.js index 5371791..b975af0 100644 --- a/build/webpack.config.base.js +++ b/build/webpack.config.base.js @@ -11,7 +11,7 @@ const config = { output: { filename: 'bundle.[hash:8].js', path: path.join(__dirname, '../dist'), - publicPath: 'http://127.0.0.1:8000/public/', + publicPath: '//127.0.0.1:8000/public/', }, module: { rules: [ diff --git a/build/webpack.config.server.js b/build/webpack.config.server.js index 71b008f..67db455 100644 --- a/build/webpack.config.server.js +++ b/build/webpack.config.server.js @@ -33,7 +33,6 @@ const config = webpackMerge(baseConfig, { test: /\.less$/, use: [ 'vue-style-loader', - // 'null-loader', 'css-loader', { loader: 'postcss-loader', diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..80403e8e8a08604c1f7c6c1d4a0d685f4928abc6 GIT binary patch literal 16958 zcmeI1%?-jZ428{!14ksz96LtEC`{75ItwcxHV6(9>LpSAs;H&nD+)!H$&dZ~Y`10y z|Mb22_tm!F}ZY zj>}h?{+Z_y*5v$?>6-s?Kj8m(EQ0?A2qgaDKlq>gAH)FpzX9jgrXc@Q{{-WZ`k(%X z`nN`;g52Yc{x{xpk^cp3sjB3E@;~`M+>33I|Dw-{*U;nqD!~@?#r(g9U!!Z_|AIeN z5&oCz-zYZM&;$P}*bDmLAN&h7=NfSxU1N**r~fT*NGp-!koVv5XEETv0r159NBlRi zd2I^fAN~_+5%{kbNP-;xlj?u?U%-~C3jf3Z@c&Q0|A7BgQWNyyKll&+ga3jUp#KrL j6;&*N1+c(BSs+EP;h56PQrgY^<3- vue-ssr-learning + <%- style %> diff --git a/server/server.js b/server/server.js index b209167..ae807a5 100644 --- a/server/server.js +++ b/server/server.js @@ -1,3 +1,4 @@ +const path = require('path') const express = require('express') const app = express() @@ -20,6 +21,14 @@ app.use((req, res, next) => { } }) +app.use((req, res, next) => { + if (req.path === '/favicon.ico') { + res.sendFile(path.join(__dirname, '../favicon.ico')) + } else { + next() + } +}) + app.use('*', pageRouter) const HOST = process.env.HOST || '0.0.0.0'