Vue.js教程
8.14.5 Renderer 选项
阅读(

Vue.js 基础

Vue.js 过渡和动画

Vue.js 可复用性和组合

Vue.js 工具

Vue.js 模块化

Vue.js 响应式系统原理

Vue.js API

Vue.js 服务器端渲染 SSR

简介

基本用法

编写通用代码

源码结构

路由和代码分割

数据预取和状态

客户端混合

Bundle Renderer 简介

构建配置

CSS 管理

Head 管理

缓存

流式渲染

API参考

Class: BundleRenderer

Class: Renderer

createBundleRenderer

createRenderer

Renderer 选项

  • template

    为整个页面的 HTML 提供一个模板。此模板应包含注释<!--vue-ssr-outlet-->,作为渲染应用内容的占位符。

模板还支持使用渲染上下文 (render context) 进行基本插值:

  • 使用双花括号 (double-mustache) 进行 HTML 转义插值 (HTML-escaped interpolation);
  • 使用三花括号 (triple-mustache) 进行 HTML 不转义插值 (non-HTML-escaped interpolation)。

当在渲染上下文 (render context) 上存在一些特定属性时,模板会自动注入对应的内容:

  • context.head:(字符串)将会被作为 HTML 注入到页面的头部 (head) 里。

  • context.styles:(字符串)内联 CSS,将以 style 标签的形式注入到页面头部。注意,如过你使用了vue-loader+vue-style-loader来处理组件 CSS,此属性会在构建过程中被自动生成。

  • context.state:(对象)初始 Vuex store 状态,将以window.__INITIAL_STATE__的形式内联到页面。内联的 JSON 将使用serialize-javascript自动清理,以防止 XSS 攻击。

    此外,当提供clientManifest时,模板会自动注入以下内容:

  • 渲染当前页面所需的最优客户端 JavaScript 和 CSS 资源(支持自动推导异步代码分割所需的文件)

  • 为要渲染页面提供最佳的<link rel="preload/prefetch">资源提示(resource hints)。

    你也可以通过将inject: false传递给 renderer,来禁用所有自动注入。

具体查看:

  • 使用一个页面模板

  • 手动资源注入(Manual Asset Injection)

    • clientManifest

  • 2.3.0+

    通过此选项提供一个由vue-server-renderer/client-plugin生成的客户端构建 manifest 对象 (client build manifest object)。此对象包含了 webpack 整个构建过程的信息,从而可以让 bundle renderer 自动推导需要在 HTML 模板中注入的内容。更多详细信息,请查看生成 clientManifest

  • inject

    • 2.3.0+

    控制使用template时是否执行自动注入。默认是true

    参考:手动资源注入(Manual Asset Injection)

  • shouldPreload

    • 2.3.0+

    一个函数,用来控制什么文件应该生成<link rel="preload">资源预加载提示 (resource hints)。

默认情况下,只有 JavaScript 和 CSS 文件会被预加载,因为它们是启动应用时所必需的。

对于其他类型的资源(如图像或字体),预加载过多可能会浪费带宽,甚至损害性能,因此预加载什么资源具体依赖于场景。你可以使用shouldPreload选项精确控制预加载资源:

  const renderer = createBundleRenderer(bundle, {
    template,
    clientManifest,
    shouldPreload: (file, type) => {
      // 基于文件扩展名的类型推断。
      // https://fetch.spec.whatwg.org/#concept-request-destination
      if (type === 'script' || type === 'style') {
        return true
      }
      if (type === 'font') {
        // only preload woff2 fonts
        return /\.woff2$/.test(file)
      }
      if (type === 'image') {
        // only preload important images
        return file === 'hero.jpg'
      }
    }
  })
  • runInNewContext

    • 2.3.0+
    • 只用于createBundleRenderer
    • Expects:boolean | 'once'('once'仅在 2.3.1+ 中支持)

    默认情况下,对于每次渲染,bundle renderer 将创建一个新的 V8 上下文并重新执行整个 bundle。这具有一些好处 - 例如,应用程序代码与服务器进程隔离,我们无需担心文档中提到的状态单例问题。然而,这种模式有一些相当大的性能开销,因为重新创建上下文并执行整个 bundle 还是相当昂贵的,特别是当应用很大的时候。

    出于向后兼容的考虑,此选项默认为true,但建议你尽可能使用runInNewContext: falserunInNewContext: 'once'

在 2.3.0 中,此选项有一个 bug,其中runInNewContext: false仍然使用独立的全局上下文(separate global context)执行 bundle。以下信息假定版本为 2.3.1+。

使用runInNewContext: false,bundle 代码将与服务器进程在同一个global上下文中运行,所以请留意在应用程序代码中尽量避免修改global

使用runInNewContext: 'once'(2.3.1+),bundle 将在独立的全局上下文 (separate global context) 取值,然而只在启动时取值一次。这提供了一定程度的应用程序代码隔离,因为它能够防止 bundle 中的代码意外污染服务器进程的global对象。注意事项如下:

  1. 在此模式下,修改global(例如,polyfill)的依赖模块必须被打包进 bundle,不能被外部化 (externalize);
  2. 从 bundle 执行返回的值将使用不同的全局构造函数,例如,在服务器进程中捕获到 bundle 内部抛出的错误,使用的是 bundle 上下文中的 Error 构造函数,所以它不会是服务器进程中Error的一个实例。

    参考:源码结构

  3. basedir

    • 2.2.0+
    • 只用于createBundleRenderer

    显式地声明 server bundle 的运行目录。运行时将会以此目录为基准来解析node_modules中的依赖模块。只有在所生成的 bundle 文件与外部的 NPM 依赖模块放置在不同位置,或者vue-server-renderer是通过 NPM link 链接到当前项目中时,才需要配置此选项。

  4. cache

    提供组件缓存具体实现。缓存对象必须实现以下接口(使用 Flow 语法表示):

  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
    })
  })

请注意,缓存对象应至少要实现getset。此外,如果gethas接收第二个参数作为回调,那gethas也可以是可选的异步函数。这允许缓存使用异步 API,例如,一个 Redis 客户端:

  const renderer = createRenderer({
    cache: {
      get: (key, cb) => {
        redisClient.get(key, (err, res) => {
          // 处理任何错误
          cb(res)
        })
      },
      set: (key, val) => {
        redisClient.set(key, val)
      }
    }
  })
  • directives

对于自定义指令,允许提供服务器端实现:

  const renderer = createRenderer({
    directives: {
      example (vnode, directiveMeta) {
        // 基于指令绑定元数据(metadata)转换 vnode
      }
    }
  })

例如,请查看v-show的服务器端实现。

如果本教程对您帮助很大,请随意打赏。您的支持,将鼓励我们提供更好的教程!

← 键盘方向键翻页 →
返回顶部 手机访问 关注微信 返回底部

扫码访问歪脖网

随时随地,想看就看

关注歪脖网微信

分享 web 知识、交流 web 经验