Sfoglia il codice sorgente

tests for ssr bundleRenderer + template + clientManifest

Evan You 9 anni fa
parent
commit
655c0f185b

+ 1 - 2
package.json

@@ -106,8 +106,7 @@
     "serialize-javascript": "^1.3.0",
     "typescript": "^2.1.6",
     "uglify-js": "^2.6.2",
-    "vue-ssr-html-stream": "^2.1.0",
-    "vue-ssr-webpack-plugin": "^1.0.0",
+    "vue-ssr-webpack-plugin": "^2.0.0",
     "webpack": "^2.2.0",
     "weex-js-runtime": "^0.17.0-alpha4",
     "weex-vdom-tester": "^0.1.4"

+ 22 - 0
test/ssr/compile-with-webpack.js

@@ -0,0 +1,22 @@
+import path from 'path'
+import webpack from 'webpack'
+import MemoeryFS from 'memory-fs'
+
+export function compileWithWebpack (file, extraConfig, cb) {
+  const config = Object.assign({
+    entry: path.resolve(__dirname, 'fixtures', file),
+    module: {
+      rules: [{ test: /\.js$/, loader: 'babel-loader' }]
+    }
+  }, extraConfig)
+
+  const compiler = webpack(config)
+  const fs = new MemoeryFS()
+  compiler.outputFileSystem = fs
+
+  compiler.run((err, stats) => {
+    expect(err).toBeFalsy()
+    expect(stats.errors).toBeFalsy()
+    cb(fs)
+  })
+}

+ 5 - 0
test/ssr/fixtures/async-bar.js

@@ -0,0 +1,5 @@
+module.exports = {
+  render (h) {
+    return h('div', 'async bar')
+  }
+}

+ 0 - 0
test/ssr/fixtures/comp.js → test/ssr/fixtures/async-foo.js


+ 2 - 1
test/ssr/fixtures/split.js

@@ -1,7 +1,8 @@
 import Vue from '../../../dist/vue.runtime.common.js'
 
 // async component!
-const Foo = () => import('./comp')
+const Foo = () => import('./async-foo')
+const Bar = () => import('./async-bar') // eslint-disable-line
 
 export default context => {
   return new Promise(resolve => {

+ 1 - 4
test/ssr/jasmine.json

@@ -1,10 +1,7 @@
 {
   "spec_dir": "test/ssr",
   "spec_files": [
-    "ssr-env.spec.js",
-    "ssr-string.spec.js",
-    "ssr-stream.spec.js",
-    "ssr-bundle-render.spec.js"
+    "*.spec.js"
   ],
   "helpers": [
     "../../node_modules/babel-register/lib/node.js"

+ 22 - 32
test/ssr/ssr-bundle-render.spec.js

@@ -1,38 +1,28 @@
-import path from 'path'
-import webpack from 'webpack'
-import MemoeryFS from 'memory-fs'
-import VueSSRPlugin from 'vue-ssr-webpack-plugin'
+import { VueSSRServerPlugin } from 'vue-ssr-webpack-plugin'
+import { compileWithWebpack } from './compile-with-webpack'
 import { createBundleRenderer } from '../../packages/vue-server-renderer'
 
-export function createRenderer (file, cb, options) {
+export function createRenderer (file, options, cb) {
+  if (typeof options === 'function') {
+    cb = options
+    options = undefined
+  }
   const asBundle = !!(options && options.asBundle)
   if (options) delete options.asBundle
 
-  const config = {
+  compileWithWebpack(file, {
     target: 'node',
-    entry: path.resolve(__dirname, 'fixtures', file),
     devtool: asBundle ? '#source-map' : false,
     output: {
       path: '/',
       filename: 'bundle.js',
       libraryTarget: 'commonjs2'
     },
-    module: {
-      rules: [{ test: /\.js$/, loader: 'babel-loader' }]
-    },
     externals: [require.resolve('../../dist/vue.runtime.common.js')],
     plugins: asBundle
-      ? [new VueSSRPlugin()]
+      ? [new VueSSRServerPlugin()]
       : []
-  }
-
-  const compiler = webpack(config)
-  const fs = new MemoeryFS()
-  compiler.outputFileSystem = fs
-
-  compiler.run((err, stats) => {
-    expect(err).toBeFalsy()
-    expect(stats.errors).toBeFalsy()
+  }, fs => {
     const bundle = asBundle
       ? JSON.parse(fs.readFileSync('/vue-ssr-bundle.json', 'utf-8'))
       : fs.readFileSync('/bundle.js', 'utf-8')
@@ -108,7 +98,7 @@ describe('SSR: bundle renderer', () => {
         }
       }
     }
-    createRenderer('cache.js', renderer => {
+    createRenderer('cache.js', options, renderer => {
       const expected = '<div data-server-rendered="true">/test</div>'
       const key = 'app::1'
       renderer.renderToString((err, res) => {
@@ -125,7 +115,7 @@ describe('SSR: bundle renderer', () => {
           done()
         })
       })
-    }, options)
+    })
   })
 
   it('render with cache (get/set/has)', done => {
@@ -151,7 +141,7 @@ describe('SSR: bundle renderer', () => {
         }
       }
     }
-    createRenderer('cache.js', renderer => {
+    createRenderer('cache.js', options, renderer => {
       const expected = '<div data-server-rendered="true">/test</div>'
       const key = 'app::1'
       renderer.renderToString((err, res) => {
@@ -170,22 +160,22 @@ describe('SSR: bundle renderer', () => {
           done()
         })
       })
-    }, options)
+    })
   })
 
   it('renderToString (bundle format with code split)', done => {
-    createRenderer('split.js', renderer => {
+    createRenderer('split.js', { asBundle: true }, renderer => {
       const context = { url: '/test' }
       renderer.renderToString(context, (err, res) => {
         expect(err).toBeNull()
         expect(res).toBe('<div data-server-rendered="true">/test<div>async</div></div>')
         done()
       })
-    }, { asBundle: true })
+    })
   })
 
   it('renderToStream (bundle format with code split)', done => {
-    createRenderer('split.js', renderer => {
+    createRenderer('split.js', { asBundle: true }, renderer => {
       const context = { url: '/test' }
       const stream = renderer.renderToStream(context)
       let res = ''
@@ -196,27 +186,27 @@ describe('SSR: bundle renderer', () => {
         expect(res).toBe('<div data-server-rendered="true">/test<div>async</div></div>')
         done()
       })
-    }, { asBundle: true })
+    })
   })
 
   it('renderToString catch error (bundle format with source map)', done => {
-    createRenderer('error.js', renderer => {
+    createRenderer('error.js', { asBundle: true }, renderer => {
       renderer.renderToString(err => {
         expect(err.stack).toContain('test/ssr/fixtures/error.js:1:6')
         expect(err.message).toBe('foo')
         done()
       })
-    }, { asBundle: true })
+    })
   })
 
   it('renderToString catch error (bundle format with source map)', done => {
-    createRenderer('error.js', renderer => {
+    createRenderer('error.js', { asBundle: true }, renderer => {
       const stream = renderer.renderToStream()
       stream.on('error', err => {
         expect(err.stack).toContain('test/ssr/fixtures/error.js:1:6')
         expect(err.message).toBe('foo')
         done()
       })
-    }, { asBundle: true })
+    })
   })
 })

+ 84 - 8
test/ssr/ssr-template.spec.js

@@ -1,11 +1,44 @@
+import webpack from 'webpack'
 import Vue from '../../dist/vue.runtime.common.js'
+import { VueSSRClientPlugin } from 'vue-ssr-webpack-plugin'
+import { compileWithWebpack } from './compile-with-webpack'
 import { createRenderer } from '../../packages/vue-server-renderer'
 import { createRenderer as createBundleRenderer } from './ssr-bundle-render.spec.js'
 
+const defaultTemplate = `<html><head></head><body><!--vue-ssr-outlet--></body></html>`
+
+function generateClientManifest (file, cb) {
+  compileWithWebpack(file, {
+    output: {
+      path: '/',
+      filename: '[name].js'
+    },
+    plugins: [
+      new webpack.optimize.CommonsChunkPlugin({
+        name: 'manifest',
+        minChunks: Infinity
+      }),
+      new VueSSRClientPlugin()
+    ]
+  }, fs => {
+    cb(JSON.parse(fs.readFileSync('/vue-ssr-client-manifest.json', 'utf-8')))
+  })
+}
+
+function createRendererWithManifest (file, cb) {
+  generateClientManifest(file, clientManifest => {
+    createBundleRenderer(file, {
+      asBundle: true,
+      template: defaultTemplate,
+      clientManifest
+    }, cb)
+  })
+}
+
 describe('SSR: template option', () => {
   it('renderToString', done => {
     const renderer = createRenderer({
-      template: `<html><head></head><body><!--vue-ssr-outlet--></body></html>`
+      template: defaultTemplate
     })
 
     const context = {
@@ -30,7 +63,7 @@ describe('SSR: template option', () => {
 
   it('renderToStream', done => {
     const renderer = createRenderer({
-      template: `<html><head></head><body><!--vue-ssr-outlet--></body></html>`
+      template: defaultTemplate
     })
 
     const context = {
@@ -59,7 +92,10 @@ describe('SSR: template option', () => {
   })
 
   it('bundleRenderer + renderToString', done => {
-    createBundleRenderer('app.js', renderer => {
+    createBundleRenderer('app.js', {
+      asBundle: true,
+      template: defaultTemplate
+    }, renderer => {
       const context = {
         head: '<meta name="viewport" content="width=device-width">',
         styles: '<style>h1 { color: red }</style>',
@@ -77,13 +113,14 @@ describe('SSR: template option', () => {
         expect(context.msg).toBe('hello')
         done()
       })
-    }, {
-      template: `<html><head></head><body><!--vue-ssr-outlet--></body></html>`
     })
   })
 
   it('bundleRenderer + renderToStream', done => {
-    createBundleRenderer('app.js', renderer => {
+    createBundleRenderer('app.js', {
+      asBundle: true,
+      template: defaultTemplate
+    }, renderer => {
       const context = {
         head: '<meta name="viewport" content="width=device-width">',
         styles: '<style>h1 { color: red }</style>',
@@ -105,8 +142,47 @@ describe('SSR: template option', () => {
         expect(context.msg).toBe('hello')
         done()
       })
-    }, {
-      template: `<html><head></head><body><!--vue-ssr-outlet--></body></html>`
+    })
+  })
+
+  const expectedHTMLWithManifest =
+    `<html><head>` +
+      // used chunks should have preload
+      `<link rel="preload" href="/manifest.js" as="script">` +
+      `<link rel="preload" href="/main.js" as="script">` +
+      `<link rel="preload" href="/0.js" as="script">` +
+      // unused chunks should have prefetch
+      `<link rel="prefetch" href="/1.js" as="script">` +
+    `</head><body>` +
+      `<div data-server-rendered="true"><div>async</div></div>` +
+      // manifest chunk should be first
+      `<script src="/manifest.js"></script>` +
+      // async chunks should be before main chunk
+      `<script src="/0.js"></script>` +
+      `<script src="/main.js"></script>` +
+    `</body></html>`
+
+  it('bundleRenderer + renderToString + clientManifest', done => {
+    createRendererWithManifest('split.js', renderer => {
+      renderer.renderToString({}, (err, res) => {
+        expect(err).toBeNull()
+        expect(res).toContain(expectedHTMLWithManifest)
+        done()
+      })
+    })
+  })
+
+  it('bundleRenderer + renderToStream + clientManifest', done => {
+    createRendererWithManifest('split.js', renderer => {
+      const stream = renderer.renderToStream({})
+      let res = ''
+      stream.on('data', chunk => {
+        res += chunk.toString()
+      })
+      stream.on('end', () => {
+        expect(res).toContain(expectedHTMLWithManifest)
+        done()
+      })
     })
   })
 })