Repository: vuejs/vue
Pull request: feat(ssr): render initial and used async css chunks

<!--
Please make sure to read the Pull Request Guidelines:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
-->

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [ ] Bugfix
- [x] Feature
- [ ] Code style update
- [x] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [x] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [ ] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [ ] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

**Other information:**

This pr is trying to resolve #7897 : 
1. Put splitted chunks of css files into corresponding `async` and `initial` int `vue-ssr-client-manifest.json`
1. Let `renderStyles` render `initial` and used `async` css files.

Changed files:
filename: src/server/template-renderer/index.js
patch: @@ -108,13 +108,13 @@ export default class TemplateRenderer {
   }
 
   renderStyles (context: Object): string {
-    const cssFiles = this.clientManifest
-      ? this.clientManifest.all.filter(isCSS)
-      : []
+    const initial = this.preloadFiles || []
+    const async = this.getUsedAsyncFiles(context) || []
+    const cssFiles = initial.concat(async).filter(({ file }) => isCSS(file))
     return (
       // render links for css files
       (cssFiles.length
-        ? cssFiles.map(file => `<link rel="stylesheet" href="${this.publicPath}/${file}">`).join('')
+        ? cssFiles.map(({ file }) => `<link rel="stylesheet" href="${this.publicPath}/${file}">`).join('')
         : '') +
       // context.styles is a getter exposed by vue-style-loader which contains
       // the inline component styles collected during SSR
@@ -202,10 +202,10 @@ export default class TemplateRenderer {
 
   renderScripts (context: Object): string {
     if (this.clientManifest) {
-      const initial = this.preloadFiles
-      const async = this.getUsedAsyncFiles(context)
+      const initial = this.preloadFiles.filter(({ file }) => isJS(file))
+      const async = (this.getUsedAsyncFiles(context) || []).filter(({ file }) => isJS(file))
       const needed = [initial[0]].concat(async || [], initial.slice(1))
-      return needed.filter(({ file }) => isJS(file)).map(({ file }) => {
+      return needed.map(({ file }) => {
         return `<script src="${this.publicPath}/${file}" defer></script>`
       }).join('')
     } else {

filename: src/server/webpack-plugin/client.js
patch: @@ -1,6 +1,6 @@
 const hash = require('hash-sum')
 const uniq = require('lodash.uniq')
-import { isJS } from './util'
+import { isJS, isCSS } from './util'
 
 export default class VueSSRClientPlugin {
   constructor (options = {}) {
@@ -19,10 +19,10 @@ export default class VueSSRClientPlugin {
       const initialFiles = uniq(Object.keys(stats.entrypoints)
         .map(name => stats.entrypoints[name].assets)
         .reduce((assets, all) => all.concat(assets), [])
-        .filter(isJS))
+        .filter((file) => isJS(file) || isCSS(file)))
 
       const asyncFiles = allFiles
-        .filter(isJS)
+        .filter((file) => isJS(file) || isCSS(file))
         .filter(file => initialFiles.indexOf(file) < 0)
 
       const manifest = {