当前位置: 首页 > 文档资料 > Vue.js 教程 >

8.14.5 Renderer 选项

优质
小牛编辑
140浏览
2023-12-01
  • 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的服务器端实现。