vue服务端渲染在项目中的应用

vue服务端渲染在项目中的应用

很多项目首页的渲染方案,都是通过js去拉接口数据回来然后动态生成dom结构,这样有个不好的地方,就是你需要通过一个loading来遮挡页面的初始化渲染,为了视觉上的体验,不能让用户看到页面从无到有这么的一个加载过程,影响体验效果,通过chrome查看source里面的页面文件,你就只看到一个简单的html,页面结构是没有的,这样也不利于现在搜索引擎去爬页面数据,不利于SEO,一是考虑页面能尽快的呈现给用户、二是SEO,那么服务端渲染就很有必要了

   服务端渲染,既在返回给客户端的html是已经生成好了的结构,这样会加大传输大小,但这点大小通过优化就不值一提了,更快的把内容呈现给用户,增加用户页面停留时间,传统渲染直接php框架模版语法或者java、python等语言的,这里写出vue的服务端渲染(reactjs也是有的),我们项目中其实是用到了renderToString来先生成字符串,赋值到html去,做了两次打包处理,我们是在打包阶段做的服务端渲染,不是那种通过node,传统意义上的服务端渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//引入vue-server-renderer
const renderer = require('vue-server-renderer').createRenderer();
//针对本地环境做区分
<% if(htmlWebpackPlugin.options.IS_DEV) {%>
<div id="app"></div>
<%} else {%>
<%= htmlWebpackPlugin.options.injectData.content %>
<%}%>
//大致配置
const ssrCompiler = webpack({
context: config.DIR,
entry: ...,
output: {
ssr.bundle.js
},
module: {
rules: [
...
]
},
resolveLoader: {
modules: []
},
resolve: {
modules: [c]
},
plugins: [
],
externals: [nodeExternals({
modulesDir: config.NODE_MODULES,
whitelist: /\.css$/
})],
target: "node"
});
const standardCompiler = webpack({
context: xx,
entry: Object.assign({ vendor: ["vue", "vuex", "vue-resource"]},...)
output: {
},
module: {
rules: [
...
]
},
resolve: {
modules: [...],
alias: {
...
}
},
resolveLoader: {
modules: []
},
plugins: [
new webpack.DefinePlugin({
'process.env': {NODE_ENV: '"production"', IS_SSR: 'false'}
}),
new webpack.LoaderOptionsPlugin({minimize: true}),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("css/[name].[chunkhash:8].css"),
new webpack.optimize.CommonsChunkPlugin({names: ['vendor']})
].concat(),
cache: false,
target: "web"
});
//整合流程
ssrCompiler.run(function(err, stats) {
if(err) throw err;
let code = stats.compilation.assets['ssr.bundle.js'].source();
//https://stackoverflow.com/questions/20899863/the-module-property-is-undefined-when-using-vm-runinthiscontext
let m = require('module');
rm('-f', path.join(config.ACTIVITY_BUILD_DIR, 'ssr.bundle.js'));
vm.runInThisContext(m.wrap(code))(exports, require, module);
let app = module.exports.createApp();
renderer.renderToString(app, (err, html) => {
if (err) throw err;
//赋值
injectHTMLData.content = html;
standardCompiler.run(function(err, stats) {
callback && callback();
});
});
});

/第一步生成ss.bundle.js文件、通过ss.bundle.js打包成html字符串、赋值给HtmlWebpackPlugin插件/

ssr阶段执行钩子

  我们有时会在某些钩子函数里面用到window,但是在ssr阶段并不存在这个对象,所以应该添加typeof判断,ssr阶段methods、mounted、beforeMounted等不调用,写入这些阶段不需要判断,但是像computed、beforeCreate、created这种的话就得加了

坚持技术分享,您的支持将鼓励我继续创作!