继前段时间的重庆地门经验并顺利拿到OFFER后,明天(5月2日)就是我入职的第三天了。 简单内部培训了一下午后,后端领导让我先了解一下Vue的服务端渲染是什么。 (苏维埃社会主义共和国)。
SSR,英文全称是ServersideRendering,中国人称之为服务器端渲染。
当我第一次看到这个词时,我感到很头疼。 我们先去官网了解一下SSR的定义:
Vue.js 可以渲染与服务器端 HTML 相同的组件
字符串,将它们直接发送到浏览器,最后将静态标记“混合”到客户端的完全交互式应用程序中。 这些既可以在服务器端也可以在客户端运行的代码程序也可以称为“同构”。
我弱弱地问领导,我们公司为什么要用服务端渲染?
领导冷冷的回答,原因有二。 一是因为我们公司的网站非常重视SEO,页面异步获取内容; 其次,我们也希望用户能够更快地看到完全渲染的页面,从而改善用户体验。 基于这两点,就需要服务端渲染(SSR)来解决这个问题。
那么服务端渲染的流程是怎样的呢? 话不多说,先上图:
使用服务端渲染时webpack 前端改造,首先要有一个服务器。 因为在开发vue项目时,需要启动一个webpack-dev-server服务,端口为8000webpack 前端改造,由于我们要使用它的热替换,这样可以促进开发效率。
因为webpack是一个独立的服务器,我们没有办法向其中添加服务器端渲染代码,而这些代码需要我们自己编写,所以我们需要启动另一个nodeserver来执行服务器端渲染逻辑。 我们将使用vue-server-renderer包来帮助我们在node.js环境中渲染vue代码生成的HTML代码。 这部分代码直接返回给用户,用户可以直接在浏览器中看到HTML内容。
以图片为例,我们看到两个渲染进程和两个服务器。 如果直接访问webpack-dev-server的话,和我们之前的开发流程是一样的。 这是一个纯粹的后端渲染过程。 如果我们要使用服务端渲染流程,就必须使用nodeserver服务,端口3333来体现差异。 并且需要打包一个逻辑在node端运行,使用webpack-server-compiler生成一个serverbundle,也就是服务器端的app.js。 NodeServer获取到ServerBundle后,可以执行vue-server-renderer渲染HTML代码,直接返回给用户。 这样的话就不需要通过js渲染页面内容了,减少了用户的等待时间。
明天文章的主要任务是首先使用webpack创建配置文件来打包服务器端代码。
第一步,如何编译服务端渲染的配置文件?
首先我们需要在项目根目录下找到build文件夹,然后在其下新建一个webpack.config.server.js文件。 我先给大家具体的配置代码:
const path = require('path')
const ExtractPlugin = require('extract-text-webpack-plugin')
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const VueServerPlugin = require('vue-server-renderer/server-plugin')
let config
config = merge(baseConfig, {
target: 'node',
entry: path.join(__dirname, '../client/server-entry.js'),
devtool: 'source-map',
output: {
libraryTarget: 'commonjs2',
filename: 'server-entry.js',
path: path.join(__dirname, '../server-build')
},
externals: Object.keys(require('../package.json').dependencies),
module: {
rules: [
{
test: /.styl/,
use: ExtractPlugin.extract({
fallback: 'vue-style-loader',
use: [
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
'stylus-loader'
]
})
}
]
},
plugins: [
new ExtractPlugin('styles.[contentHash:8].css'),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
'process.env.VUE_ENV': '"server"'
}),
new VueServerPlugin()
]
})
module.exports = config
我是 SSR 新手。 看完上面的代码你是不是感觉有点头晕? 别担心,我会带你一一了解。
target: 'node',
需要将目标指定为node,因为打包的程序是运行在node端,而不是浏览器端,所以打包目标必须指定为node环境。
entry: path.join(__dirname, '../client/server-entry.js'),
Entry需要提供单独的入口文件,因此需要在client文件夹中新建一个server-entry.js文件。
devtool: 'source-map',
Devtool需要指定source-map,因为vue-server-renderer有webpack插件,可以提供代码调试功能,但只能提示错误文件位于哪一行。
libraryTarget: 'commonjs2',
指定libraryTarget的类型为commonjs2,用于指定代码导出的入口方法。 在node.js中,模块为module.exports={...},commonjs2封装的代码导出方法与此类似。
externals: Object.keys(require('../package.json').dependencies),
外部因素是指外部激励。 首先我们可以打开 package.json 文件并查看依赖项。
我们通过 Object.keys() 得到的是一个链表。 externals告诉webpack不要将js代码打包到node_modules上。 devDependency上面还有一些工具类的东西,在应用实际运行的时候是不需要的。 仅在执行某些包装和工具操作时才需要它。
'process.env.VUE_ENV': '"server"'
这是vue服务器官方推荐的。 该属性可以用在 vue-server-renderer 上。
const VueServerPlugin = require('vue-server-renderer/server-plugin')
这个插件可以帮助我们单独生成一个json文件,可以用于Vue中的服务端渲染,可以帮助我们处理一些非常复杂的逻辑。
终于
文章到这里就算Vue的服务端渲染的介绍工作完成了(先使用webpack创建配置文件来打包服务端代码),下一篇文章会介绍如何使用koa、node服务器端框架,实现nodeserver。 最新文章会第一时间更新在我的公众号上,敬请关注。