标签。因此,在某些情况下,服务器端渲染的H5页面和客户端的H5页面标签不能够完全匹配,导致渲染失败。针对这个问题,建议在开发时尽量写全规范的H5模板。
#### 二、多页面项目打包
vue-server-renderer包中client-plugin和server-plugin插件与SPA页面的关系是一对一的,即一个SPA页面对应一套客户端Bundle和服务器端Bundle,也就是一个客户端json文件和一个服务器端json文件对应一个SPA应用。如果我们在项目中创建了多个SPA页面,则在打包时,client-plugin和server-plugin插件会报错提示有多个入口entry,无法正常匹配。
但很多情况我们需要在一个项目中拥有多个SPA页面,对于这个问题,我们可以使用shell脚本调用npm命令使用webpack进行多次打包,而在webpack中根据命令参数进行动态的SPA页面入口entry匹配。实际上,我们可以把这种做法理解为,将一个多SPA项目拆解成多个单SPA项目。
#### 三、asyncData需返回Promise对象
由于asyncData函数中进行数据预取和store初始化工作,是一个异步操作,而服务器端渲染需要在数据预取完成后将渲染好的页面返回给浏览器。因此需要将asyncData的返回值设置为Promise对象,同样,vuex中的action对象也需要返回一个Promise对象。
#### 四、服务器端对Vue钩子的调用情况
服务器端在Vue实例组件渲染时,仅会触发beforeCreate、created两个钩子。因此需要注意以下几点问题:
1.页面初始化的内容尽量放在beforeCreate、created钩子中;
2.会占用全局内存的逻辑,如定时器、全局变量、闭包等,尽量不要放在beforeCreate、created钩子中,否则在beforeDestory方法中将无法注销,导致内存泄漏。
#### 五、服务器端渲染模板页和SPA应用模板使用同一个html页面
有时,我们为了方便、易于管理以及项目简洁,想直接将SPA应用的模板页作为服务器端渲染时的模板页。这时需要注意一个问题,就是服务器端渲染的模板页比SPA应用模板页多一个注释标识,而在webpack打包时,会将SPA应用的模板中的注释删除掉。
对于这个问题,可以在webpack配置中设置不对SPA应用模板页进行打包,具体设置如下:
```javascript
// vue.config.js
module.exports = {
chainWebpack: (config) => {
config
.plugin('html-index')
.tap(options => {
options[0].minify = false;
return options;
});
},
};
```
vue-cli3会对每个SPA页面注册一个html插件进行webpack配置的管理。需要注意的是,当项目为单entry时,该插件的名称为'html';而项目为多entry(即配置了pages属性,即使pages中只有一个entry也会被识别为“多entry项目”)时,该插件名称为\`html-${entryName}\`,其中entryName为入口entry名。
#### 六、客户端与服务器端公用的js包需要同时支持浏览器端和node端
当客户端、服务器端共用js包时,主要是在数据预取的场景下,须使用具有“同构”策略的包,如使用axios代替vue-resource等。
## 回顾
在开头我们对一些服务器端渲染的问题进行过思考,并在文中做出了解答,在这里重新一一回顾下。
***1.Vue在页面渲染时以Vue实例为基本单元,在服务器端进行渲染时,是否也应对Vue实例进行渲染?***
官方【vue-server-renderer】包提供的方式就是对Vue实例进行渲染,并提供了Renderer、BundleRenderer两个对象,分别是对“单一Vue实例”、“Vue项目中的Vue实例”进行渲染。常用的方式是后者,会在服务器端根据用户请求的路由,动态匹配需要渲染的Vue实例。
***2.用户与客户端的关系是一对一,而与服务器端的关系是多对一,如何避免多个用户之间在服务器端的数据共享的问题?***
Vue服务器端渲染采用客户端、服务器端协作渲染的方案。
客户端负责静态资源的加载,采用的是单例模式;
而服务器端负责Vue实例的渲染工作,采用的是工厂模式,即所有可能产生“闭包”或“全局变量”的地方,都需要改造成工厂模式,包括但不仅限于创建Vue实例、Vuex实例(store)、store中的module模块、vue-router实例、其他公用js配置文件等。
***3.如何实现同构策略?即让服务器端能够运行前端的代码?***
首先,通过webpack进行打包,根据客户端、服务器端环境变量的不同,分别将项目打包为浏览器端可识别的模式,和Node端可识别的commonjs2模式;
其次,对一些公用js包,采用兼容浏览器、Node端的的包进行开发,如接口请求可采用axios.js进行处理。
***4.服务器端渲染的Vue项目,开发环境和生产环境分别应该如何部署?有何区别?***
共同点:
无论哪种环境下,该服务器端渲染方案均需使用客户端、服务器端两个Bundle共同渲染,因此需要对项目进行两次打包。其中,客户端Bundle包括前端项目原本打包出的浏览器可识别的静态文件,和客户端Bundle入口文件;服务器端Bundle则是将项目打包为commonjs2模式并使用source-map方式注入到json文件中。
不同点:
首先,生产环境的部署相对简单粗暴,即将打包后的客户端、服务器端Bundle放置到服务器上,使用一个node服务进行运行;
但开发环境的部署方式,则由于webpack打包运行后的客户端存储于内存中,而变得相对复杂一些。本文中使用的方案是通过http请求去读取客户端Bundle,而在Node中直接使用webpack包打包、读取和监听服务器Bundle。
***5.如何保证服务器端渲染改造后的代码仍能通过访问静态资源的方式直接访问到?***
针对这个问题,一种方案是在Node服务中对所有静态资源请求进行代理,通过http转发的方式将静态资源转发回浏览器端;另一种则是本文中使用的相对简单快捷的方式,在Node服务中搭建静态资源服务器,将所有静态资源挂载到特定路由下。
作者:安凤翔
- [滴滴云全线标准型云服务器限时特惠](https://www.didiyun.com/?channel=14816 "滴滴云全线标准型云服务器限时特惠")
- [新购云服务1月5折 3月4折 6月低至3折](https://www.didiyun.com/?channel=14816 "新购云服务1月5折 3月4折 6月低至3折")
- [注册即送新手大礼包](https://www.didiyun.com/?channel=14816 "注册即送新手大礼包")
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31559758/viewspace-2667273/
,如需转载,请注明出处,否则将追究法律责任。