Browse Source

update docs for ssr

dev
Evan You 8 years ago
parent
commit
92e91927f5
  1. 117
      packages/vue-server-renderer/README.md

117
packages/vue-server-renderer/README.md

@ -9,6 +9,7 @@ This package offers Node.js server-side rendering for Vue 2.0.
- [Renderer Options](#renderer-options)
- [Why Use `bundleRenderer`?](#why-use-bundlerenderer)
- [Creating the Server Bundle](#creating-the-server-bundle)
- [Creating the Client Manifest](#creating-the-client-manifest)
- [Component Caching](#component-caching)
- [Client Side Hydration](#client-side-hydration)
@ -213,12 +214,60 @@ const renderer = createRenderer({
> New in 2.2.0
- only used in `createBundleRenderer`
Explicitly declare the base directory for the server bundle to resolve node_modules from. This is only needed if your generated bundle file is placed in a different location from where the externalized NPM dependencies are installed.
Note that the `basedir` is automatically inferred if you use `vue-ssr-webpack-plugin` or provide an absolute path to `createBundleRenderer` as the first argument, so in most cases you don't need to provide this option. However, this option does allow you to explicitly overwrite the inferred value.
---
### clientManifest
> New in 2.3.0
- only used in `createBundleRenderer`
- only used when the `template` option is also provided
Provide a client build manifest object generated by `vue-ssr-webpack-plugin`. With the client manifest, the `bundleRenderer` has webpack build information of both the server and client, and thus will be able to automatically infer and inject asset links into the rendered HTML. For more details, see [Creating the Client Manifest](#creating-the-client-manifest).
---
### shouldPreload
> New in 2.3.0
- only used in `createBundleRenderer`
- only used when the `template` and `clientManifest` options are also provided
When a client manifest is present, the renderer will automatically inject [preload and prefetch directives](https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf) into the `<head>` section. By default, an asset will be preloaded when:
- It is used during the render. For example, if your bundle uses code split, only assets used by the chunks that were used during a render will be injected.
- It is of type `script` or `font`, because these are crucial for faster time-to-fisrt-paint / time-to-interaction. Images and other types of assets are **not** preloaded by default.
If you do want to preload assets other than scripts and fonts, `shouldPreload` gives you full control:
``` js
const renderer = createBundleRenderer(serverBundle, {
template,
clientManifest,
shouldPreload: (file, type) => {
// type is inferred based on the file extension.
// https://fetch.spec.whatwg.org/#concept-request-destination
if (type === 'script' || type === 'font') {
return true
}
if (type === 'image') {
// only preload important images
return file === 'hero.jpg'
}
}
})
```
---
### directives
Allows you to provide server-side implementations for your custom directives:
@ -307,6 +356,74 @@ module.exports = {
Since externalized modules will be shared across every request, you need to make sure that the dependency is **idempotent**. That is, using it across different requests should always yield the same result - it cannot have global state that may be changed by your application. Interactions between externalized modules are fine (e.g. using a Vue plugin).
## Creating the Client Manifest
`vue-server-renderer` 2.2 supports rendering the entire HTML page with the `template` option. 2.3 introduces another new feature, which allows us to pass a manifest of our client-side build to the `bundleRenderer`. This provides the renderer with information of both the server AND client builds, so it can automatically infer and inject preload / prefetch directives and script tags into the rendered HTML. This is particularly useful when rendering a bundle that leverages webpack's on-demand code splitting features: we can ensure the right chunks are preloaded / prefetched, and also directly embed `<script>` tags for needed async chunks in the HTML to avoid waterfall requests on the client, thus improving TTI (time-to-interactive).
To generate a client manifest, you need to add the client plugin to your client webpack config. In addition:
- Make sure to use `CommonsChunkPlugin` to split the webpack runtime into its own entry chunk, so that async chunks can be injected **after** the runtime and **before** your main app code.
- Since in this case `vue-server-renderer` will be dynamically injecting the asset links, you don't need to use `html-webpack-plugin`. However, the setup only handles JavaScript. If you want to use `html-webpack-plugin` for embedding other types of assets (e.g fonts), you can still use it - just make sure to configure it with `inject: false` so that it doesn't duplicate-inject the scripts.
``` js
// in your webpack client bundle config
const webpack = require('webpack')
const { VueSSRClientPlugin } = require('vue-ssr-webpack-plugin')
module.exports = {
// ...
plugins: [
// this splits the webpack runtime into a leading chunk
// so that async chunks can be injected right after it.
// this also enables better caching for your app/vendor code.
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// this will generate the client manifest JSON file.
new VueSSRClientPlugin()
]
}
```
This will generate an additional `vue-ssr-client-manifest.json` file in your build output. Simply require and pass it to the `bundleRenderer`:
``` js
const { createBundleRenderer } = require('vue-server-renderer')
const template = require('fs').readFileSync('/path/to/template.html', 'utf-8')
const serverBundle = require('/path/to/vue-ssr-bundle.json')
const clientManifest = require('/path/to/vue-ssr-client-manifest.json')
const renderer = createBundleRenderer(serverBundle, {
template,
clientManifest
})
```
With this setup, your server-rendered HTML for a build with code-splitting will look something like this:
``` html
<html><head>
<!-- chunks used for this render 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 async 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>`
```
You can also control precisely what to preload with the [shouldPreload](#shouldpreload) option.
## Component Caching
You can easily cache components during SSR by implementing the `serverCacheKey` function:

Loading…
Cancel
Save