使用(可選的)選項(xiàng)創(chuàng)建一個(gè) Renderer
實(shí)例。
const { createRenderer } = require('vue-server-renderer')
const renderer = createRenderer({ /* 選項(xiàng) */ })
使用 server bundle 和(可選的)選項(xiàng)創(chuàng)建一個(gè) BundleRenderer
實(shí)例。
const { createBundleRenderer } = require('vue-server-renderer')
const renderer = createBundleRenderer(serverBundle, { /* 選項(xiàng) */ })
serverBundle
參數(shù)可以是以下之一:
.js
或 .json
)。必須以 /
開頭才會(huì)被識(shí)別為文件路徑。vue-server-renderer/server-plugin
生成的 bundle 對(duì)象。更多細(xì)節(jié)請(qǐng)查看 Server Bundle 指引 和 構(gòu)建配置。
函數(shù)簽名:
renderer.renderToString(vm, context?, callback?): ?Promise<string>
將 Vue 實(shí)例渲染為字符串。上下文對(duì)象 (context object) 可選?;卣{(diào)函數(shù)是典型的 Node.js 風(fēng)格回調(diào),其中第一個(gè)參數(shù)是可能拋出的錯(cuò)誤,第二個(gè)參數(shù)是渲染完畢的字符串。
在 2.5.0+ 版本中,此 callback 回調(diào)函數(shù)是可選項(xiàng)。在不傳遞 callback 時(shí),此方法返回一個(gè) Promise 對(duì)象,在其 resolve 后返回最終渲染的 HTML。
函數(shù)簽名:
renderer.renderToStream(vm[, context]): stream.Readable
將 Vue 實(shí)例渲染為一個(gè) Node.js 可讀流 。上下文對(duì)象 (context object) 可選。更多細(xì)節(jié)請(qǐng)查看流式渲染。
函數(shù)簽名:
bundleRenderer.renderToString([context, callback]): ?Promise<string>
將 bundle 渲染為字符串。上下文對(duì)象 (context object) 可選。回調(diào)是一個(gè)典型的 Node.js 風(fēng)格回調(diào),其中第一個(gè)參數(shù)是可能拋出的錯(cuò)誤,第二個(gè)參數(shù)是渲染完畢的字符串。
在 2.5.0+ 版本中,此 callback 回調(diào)函數(shù)是可選項(xiàng)。在不傳遞 callback 時(shí),此方法返回一個(gè) Promise 對(duì)象,在其 resolve 后返回最終渲染的 HTML。
函數(shù)簽名:
bundleRenderer.renderToStream([context]): stream.Readable
將 bundle 渲染為一個(gè) Node.js 可讀流 。上下文對(duì)象 (context object) 可選。更多細(xì)節(jié)請(qǐng)查看流式渲染。
為整個(gè)頁(yè)面的 HTML 提供一個(gè)模板。此模板應(yīng)包含注釋 <!--vue-ssr-outlet-->
,作為渲染應(yīng)用程序內(nèi)容的占位符。
模板還支持使用渲染上下文 (render context) 進(jìn)行基本插值:
當(dāng)在渲染上下文 (render context) 上存在一些特定屬性時(shí),模板會(huì)自動(dòng)注入對(duì)應(yīng)的內(nèi)容:
context.head
:(字符串)將會(huì)被作為 HTML 注入到頁(yè)面的頭部 (head) 里。context.styles
:(字符串)內(nèi)聯(lián) CSS,將以 style 標(biāo)簽的形式注入到頁(yè)面頭部。注意,如果你使用了 vue-loader
+ vue-style-loader
來(lái)處理組件 CSS,此屬性會(huì)在構(gòu)建過(guò)程中被自動(dòng)生成。context.state
:(對(duì)象)初始 Vuex store 狀態(tài),將以 window.__INITIAL_STATE__
的形式內(nèi)聯(lián)到頁(yè)面。內(nèi)聯(lián)的 JSON 將使用 serialize-javascript 自動(dòng)清理,以防止 XSS 攻擊。在 2.5.0+ 版本中,嵌入式 script 也可以在生產(chǎn)模式 (production mode) 下自行移除。
此外,當(dāng)提供 clientManifest
時(shí),模板會(huì)自動(dòng)注入以下內(nèi)容:
<link rel="preload/prefetch">
資源提示 (resource hints)。
你也可以通過(guò)將 inject: false
傳遞給 renderer,來(lái)禁用所有自動(dòng)注入。
具體查看:
通過(guò)此選項(xiàng)提供一個(gè)由 vue-server-renderer/client-plugin
生成的客戶端構(gòu)建 manifest 對(duì)象(client build manifest object)。此對(duì)象包含了 webpack 整個(gè)構(gòu)建過(guò)程的信息,從而可以讓 bundle renderer 自動(dòng)推導(dǎo)需要在 HTML 模板中注入的內(nèi)容。更多詳細(xì)信息,請(qǐng)查看生成 clientManifest。
控制使用 template
時(shí)是否執(zhí)行自動(dòng)注入。默認(rèn)是 true
。
參考:手動(dòng)資源注入(Manual Asset Injection)。
一個(gè)函數(shù),用來(lái)控制什么文件應(yīng)該生成 <link rel="preload">
資源預(yù)加載提示 (resource hints)。
默認(rèn)情況下,只有 JavaScript 和 CSS 文件會(huì)被預(yù)加載,因?yàn)樗鼈兪菃?dòng)應(yīng)用時(shí)所必需的。
對(duì)于其他類型的資源(如圖像或字體),預(yù)加載過(guò)多可能會(huì)浪費(fèi)帶寬,甚至損害性能,因此預(yù)加載什么資源具體依賴于場(chǎng)景。你可以使用 shouldPreload
選項(xiàng)精確控制預(yù)加載資源:
const renderer = createBundleRenderer(bundle, {
template,
clientManifest,
shouldPreload: (file, type) => {
// 基于文件擴(kuò)展名的類型推斷。
// https://fetch.spec.whatwg.org/#concept-request-destination
if (type === 'script' || type === 'style') {
return true
}
if (type === 'font') {
// 只預(yù)加載 woff2 字體
return /\.woff2$/.test(file)
}
if (type === 'image') {
// 只預(yù)加載重要 images
return file === 'hero.jpg'
}
}
})
一個(gè)函數(shù),用來(lái)控制對(duì)于哪些文件,是需要生成 <link rel="prefetch">
資源提示。
默認(rèn)情況下,異步 chunk 中的所有資源都將被預(yù)取,因?yàn)檫@是低優(yōu)先級(jí)指令; 然而,為了更好地控制帶寬使用情況,你也可以自定義要預(yù)取的資源。此選項(xiàng)具有與 shouldPreload
相同的函數(shù)簽名。
createBundleRenderer
boolean | 'once'
('once'
只在 2.3.1+ 支持)默認(rèn)情況下,對(duì)于每次渲染,bundle renderer 將創(chuàng)建一個(gè)新的 V8 上下文并重新執(zhí)行整個(gè) bundle。這具有一些好處 - 例如,應(yīng)用程序代碼與服務(wù)器進(jìn)程隔離,我們無(wú)需擔(dān)心文檔中提到的狀態(tài)單例問(wèn)題。然而,這種模式有一些相當(dāng)大的性能開銷,因?yàn)橹匦聞?chuàng)建上下文并執(zhí)行整個(gè) bundle 還是相當(dāng)昂貴的,特別是當(dāng)應(yīng)用很大的時(shí)候。
出于向后兼容的考慮,此選項(xiàng)默認(rèn)為 true
,但建議你盡可能使用 runInNewContext: false
或 runInNewContext: 'once'
。
在 2.3.0 中,此選項(xiàng)有一個(gè) bug,其中
runInNewContext: false
仍然使用獨(dú)立的全局上下文 (separate global context) 執(zhí)行 bundle。以下信息假定版本為 2.3.1+。
使用 runInNewContext: false
,bundle 代碼將與服務(wù)器進(jìn)程在同一個(gè) global
上下文中運(yùn)行,所以請(qǐng)留意在應(yīng)用程序代碼中盡量避免修改 global
。
使用 runInNewContext: 'once'
(2.3.1+),bundle 將在獨(dú)立的全局
上下文(separate global context)取值,然而只在啟動(dòng)時(shí)取值一次。這提供了一定程度的應(yīng)用程序代碼隔離,因?yàn)樗軌蚍乐?bundle 中的代碼意外污染服務(wù)器進(jìn)程的 global
對(duì)象。注意事項(xiàng)如下:
global
(例如,polyfill)的依賴模塊必須被打包進(jìn) bundle,不能被外部化 (externalize);Error
的一個(gè)實(shí)例。createBundleRenderer
顯式地聲明 server bundle 的運(yùn)行目錄。運(yùn)行時(shí)將會(huì)以此目錄為基準(zhǔn)來(lái)解析 node_modules
中的依賴模塊。只有在所生成的 bundle 文件與外部的 NPM 依賴模塊放置在不同位置,或者 vue-server-renderer
是通過(guò) NPM link 鏈接到當(dāng)前項(xiàng)目中時(shí),才需要配置此選項(xiàng)。
提供組件緩存具體實(shí)現(xiàn)。緩存對(duì)象必須實(shí)現(xiàn)以下接口(使用 Flow 語(yǔ)法表示):
type RenderCache = {
get: (key: string, cb?: Function) => string | void;
set: (key: string, val: string) => void;
has?: (key: string, cb?: Function) => boolean | void;
};
典型用法是傳入 lru-cache :
const LRU = require('lru-cache')
const renderer = createRenderer({
cache: LRU({
max: 10000
})
})
請(qǐng)注意,緩存對(duì)象應(yīng)至少要實(shí)現(xiàn) get
和 set
。此外,如果 get
和 has
接收第二個(gè)參數(shù)作為回調(diào),那 get
和 has
也可以是可選的異步函數(shù)。這允許緩存使用異步 API,例如,一個(gè) Redis 客戶端:
const renderer = createRenderer({
cache: {
get: (key, cb) => {
redisClient.get(key, (err, res) => {
// 處理任何錯(cuò)誤
cb(res)
})
},
set: (key, val) => {
redisClient.set(key, val)
}
}
})
對(duì)于自定義指令,允許提供服務(wù)器端實(shí)現(xiàn):
const renderer = createRenderer({
directives: {
example (vnode, directiveMeta) {
// 基于指令綁定元數(shù)據(jù)(metadata)轉(zhuǎn)換 vnode
}
}
})
例如,請(qǐng)查看 v-show
的服務(wù)器端實(shí)現(xiàn)。
webpack 插件作為獨(dú)立文件提供,并且應(yīng)當(dāng)直接 require:
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
生成的默認(rèn)文件是:
vue-ssr-server-bundle.json
用于服務(wù)器端插件;vue-ssr-client-manifest.json
用于客戶端插件。創(chuàng)建插件實(shí)例時(shí)可以自定義文件名:
const plugin = new VueSSRServerPlugin({
filename: 'my-server-bundle.json'
})
更多信息請(qǐng)查看構(gòu)建配置。
更多建議: