服务器端渲染的优势在于更好的seo以及更快的渲染速度,所以vue也开始支持服务器端渲染,即ssr。
基本知识
要使用服务器端渲染,需要使用server-entry.js和client-entry.js两个入口文件,两者都会使用到app.js进行打包,其中通过server-entry.js打包的代码是运行在node端,二通过client-entry.js打包代码运行在客户端。 具体的流程图如下所示。
在纯前端渲染时,一般使用的是web-dev-server这个插件,它可以自动帮助我们开启一个node端,主要作用是监控并打包代码,但是实际上还是纯前端渲染,另外配合web-hot-middleware来进行HMR热更新,这样可以在我们改变了代码之后自动打包并更新view,以此来提高开发效率。
而在vue服务器端渲染时,就不能只是使用web-dev-server和web-hot-middle了,因为我们需要添加服务器渲染的node代码逻辑,这样,我们可以自己开一个node服务器,使用webpack-dev-middle中间件进行打包、使用webpack-hot-middle中间件进行热更新,并添加服务器端渲染逻辑,即node端通过引入vue-serverer-renderer插件来渲染服务器端打包的bundle文件到客户端。
而在服务器端的配置文件webpack.server.js如下所示:
const webpack = require('webpack') const merge = require('webpack-merge') const base = require('./webpack.base.config') const nodeExternals = require('webpack-node-externals') const VueSSRServerPlugin = require('vue-server-renderer/server-plugin') module.exports = merge(base, { target: 'node', devtool: '#source-map', entry: './client/entry-server.js', output: { filename: 'server-bundle.js', libraryTarget: 'commonjs2' }, externals: nodeExternals({ // do not externalize CSS files in case we need to import it from a dep whitelist: /\.css$/ }), plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), 'process.env.VUE_ENV': '"server"', 'process.env.VUE_HOST': JSON.stringify(process.env.VUE_HOST || 'http://localhost:8888') }), new VueSSRServerPlugin() ] })
即通过webpack-merge来merge到webpack.base.config的文件,接着具体配置中,target: 'node'表示在node端运行,devtools: '#source-map'可以保证报错时定位到出错文件的行数,output.filename表示输出文件的名称,而output.libraryTarget表示模块入口形式,external表示外部不需要打包,最后就是使用到的plugins。
而之前所提到的webpack-dev-middleware和webpack-hot-middleware这两个插件可以配置在setup-dev-server.js中的,在index.js中配置服务器时,如果是开发环境,再引入setup-dev-server.js,否则不需要引入。
所以在bi项目中的两个服务器实际上都是node服务器,其中index.js创建的服务器是node服务器,提供ssr和其他的一些服务,而server下中src的index.js是一个node中间件服务器,起到的是代理服务的作用。