/vue-ssr-demo

webpack4从零搭建vue服务端渲染

Primary LanguageJavaScript

vue-ssr-demo

基于webpack4构建的vue服务端渲染模板,服务端渲染主要是为了优化seo及首屏渲染,搭建过程中难免会遇到一些问题,基本翻翻文档再参考一下vue-hackernews-2.0都比较好解决,这里就简单记录下对async css的注入优化

运行

yarn or npm install

# development
npm run dev

# production
npm run build
npm start

特性

  • eslint规范代码
  • store注入解决cookie共享
  • commit时使用lint-staged+`husky·对修改部分规范化
  • 支持stylus

异步chunk的css注入优化

webpack3+的时候,一般都是用extract-text-webpack-plugin去提取css的,到了webpack4+就推荐使用mini-css-extract-plugin来提取(也可以使用extract-text-webpack-plugin@next版,不推荐)

当用import()去做代码分割的时候,mini-css-extract-plugin会把这个async chunk中的css提取成一个单独的css文件,在服务端渲染的时候会自动注入资源,但是在注入css时,会把vue-ssr-client-manifest.json中所有的css资源(initialasync)都注入进去,假如有页面A-E,都用import()去做代码分割,不管渲染那个页面,都会得到如下结果

<link rel="stylesheet" href="/pageA.css">
<link rel="stylesheet" href="/pageB.css">
<link rel="stylesheet" href="/pageC.css">
<link rel="stylesheet" href="/pageD.css">
<link rel="stylesheet" href="/pageE.css">

这样的话就有4个请求是多余的,也会浪费流量,增加首屏时间,去参考下vue-hackernews-2.0的话,会发现是没有这个问题的,因为vue-hackernews-2.0使用的是extract-text-webpack-plugin,并且fallback是设置vue-style-loader去处理的,这样会把async chunk中的css打包到js中,服务端渲染是会把这部分css直接内联到html中返回,那这里用的是webpack4+,不用extract-text-webpack-plugin的话只能寻找其他方法了。

那服务端渲染时只注入需要的css,就需要知道当前是渲染那个页面,然后在找到对应的资源手动注入,通过调试发现经过vue-loader处理后的组件会带有__file="xxx.vue",里面的值就是组件的源文件名,通过这个__file属性,到打包出的js中去匹配查找就可以找出组件对应的chunkName,而这部分的jscsschunkName是一样的,这样就可以找出组件对应的css资源了

但是这套方案也是不完美的,只能处理页面级组件的样式(一般以页面做代码分割,就能满足大部分项目了),如果里面还有import()的子组件,这部分的css就没法注入了。具体代码查看build/asyncInjectAssets.jsserver.js