diff --git a/LANGS.md b/LANGS.md index 25b60e8a..f379e75a 100644 --- a/LANGS.md +++ b/LANGS.md @@ -1 +1,2 @@ * [English](en/) +* [Русский](ru/) diff --git a/en/README.md b/en/README.md index 084c25b9..1763b33b 100644 --- a/en/README.md +++ b/en/README.md @@ -1,50 +1,54 @@ -# Vue.js Server-Side Rendering Guide +# Vue.js 服务器端渲染指南 -> **Note:** this guide requires the following minimum versions of Vue and supporting libraries: +> **注意:** 本指南需要最低为如下版本的 Vue,以及以下 library 支持: > - vue & vue-server-renderer >= 2.3.0 > - vue-router >= 2.5.0 > - vue-loader >= 12.0.0 & vue-style-loader >= 3.0.0 -> If you have previously used Vue 2.2 with SSR, you will notice that the recommended code structure is now [a bit different](./structure.md) (with the new [runInNewContext](./api.md#runinnewcontext) option set to `false`). Your existing app should continue to work, but it's recommended to migrate to the new recommendations. +> 如果先前已经使用过 Vue 2.2 的服务器端渲染(SSR),您应该注意到,推荐的代码结构现在[略有不同](./structure.md)(使用新的 [runInNewContext](./api.md#runinnewcontext) 选项,并设置为 `false`)。现有的应用程序可以继续运行,但建议您迁移到新的推荐规范。 -## What is Server-Side Rendering (SSR)? +## 什么是服务器端渲染(SSR)? -Vue.js is a framework for building client-side applications. By default, Vue components produce and manipulate DOM in the browser as output. However, it is also possible to render the same components into HTML strings on the server, send them directly to the browser, and finally "hydrate" the static markup into a fully interactive app on the client. +Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序。 -A server-rendered Vue.js app can also be considered "isomorphic" or "universal", in the sense that the majority of your app's code runs on both the server **and** the client. +服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在**服务器**和**客户端**上运行。 -## Why SSR? +## 为什么使用服务器端渲染(SSR)? -Compared to a traditional SPA (Single-Page Application), the advantage of SSR primarily lies in: +与传统 SPA(Single-Page Application - 单页应用程序)相比,服务器端渲染(SSR)的优势主要在于: -- Better SEO, as the search engine crawlers will directly see the fully rendered page. +- 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。 - Note that as of now, Google and Bing can index synchronous JavaScript applications just fine. Synchronous being the key word there. If your app starts with a loading spinner, then fetches content via Ajax, the crawler will not wait for you to finish. This means if you have content fetched asynchronously on pages where SEO is important, SSR might be necessary. + 请注意,截至目前,Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引。在这里,同步是关键。如果您的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。 -- Faster time-to-content, especially on slow internet or slow devices. Server-rendered markup doesn't need to wait until all JavaScript has been downloaded and executed to be displayed, so your user will see a fully-rendered page sooner. This generally results in better user experience, and can be critical for applications where time-to-content is directly associated with conversion rate. +- 更快的内容到达时间(time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。无需等待所有的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,所以你的用户将会更快速地看到完整渲染的页面。通常可以产生更好的用户体验,并且对于那些「内容到达时间(time-to-content)与转化率直接相关」的应用程序而言,服务器端渲染(SSR)至关重要。 -There are also some trade-offs to consider when using SSR: +使用服务器端渲染(SSR)时还需要有一些权衡之处: -- Development constraints. Browser-specific code can only be used inside certain lifecycle hooks; some external libraries may need special treatment to be able to run in a server-rendered app. +- 开发条件所限。浏览器特定的代码,只能在某些生命周期钩子函数(lifecycle hook)中使用;一些外部扩展库(external library)可能需要特殊处理,才能在服务器渲染应用程序中运行。 -- More involved build setup and deployment requirements. Unlike a fully static SPA that can be deployed on any static file server, a server-rendered app requires an environment where a Node.js server can run. +- 涉及构建设置和部署的更多要求。与可以部署在任何静态文件服务器上的完全静态单页面应用程序(SPA)不同,服务器渲染应用程序,需要处于 Node.js server 运行环境。 -- More server-side load. Rendering a full app in Node.js is obviously going to be more CPU-intensive than just serving static files, so if you expect high traffic, be prepared for corresponding server load and wisely employ caching strategies. +- 更多的服务器端负载。在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源(CPU-intensive - CPU 密集),因此如果您预料在高流量环境(high traffic)下使用,请准备相应的服务器负载,并明智地采用缓存策略。 -Before using SSR for your app, the first question you should ask it whether you actually need it. It mostly depends on how important time-to-content is for your app. For example, if you are building an internal dashboard where an extra few hundred milliseconds on initial load doesn't matter that much, SSR would be an overkill. However, in cases where time-to-content is absolutely critical, SSR can help you achieve the best possible initial load performance. +在对您的应用程序使用服务器端渲染(SSR)之前,您应该问第一个问题是否真的需要它。这主要取决于内容到达时间(time-to-content)对应用程序的重要程度。例如,如果您正在构建一个内部仪表盘,初始加载时的额外几百毫秒并不重要,这种情况下去使用服务器端渲染(SSR)将是一个小题大作之举。然而,内容到达时间(time-to-content)要求是绝对关键的指标,在这种情况下,服务器端渲染(SSR)可以帮助您实现最佳的初始加载性能。 -## SSR vs Prerendering +## 服务器端渲染 vs 预渲染(SSR vs Prerendering) -If you're only investigating SSR to improve the SEO of a handful of marketing pages (e.g. `/`, `/about`, `/contact`, etc), then you probably want __prerendering__ instead. Rather than using a web server to compile HTML on-the-fly, prerendering simply generates static HTML files for specific routes at build time. The advantage is setting up prerendering is much simpler and allows you to keep your frontend as a fully static site. +如果您调研服务器端渲染(SSR)只是用来改善少数营销页面(例如 `/`, `/about`, `/contact` 等)的 SEO,那么您可能需要__预渲染__。无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时(build time)简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将您的前端作为一个完全静态的站点。 -If you're using Webpack, you can easily add prerendering with the [prerender-spa-plugin](https://github.com/chrisvfritz/prerender-spa-plugin). It's been extensively tested with Vue apps - and in fact, [the creator](https://github.com/chrisvfritz) is a member of the Vue core team. +如果您使用 webpack,您可以使用 [prerender-spa-plugin](https://github.com/chrisvfritz/prerender-spa-plugin) 轻松地添加预渲染。它已经被 Vue 应用程序广泛测试 - 事实上,[作者](https://github.com/chrisvfritz)是 Vue 核心团队的成员。 -## About This Guide +## 关于此指南 -This guide is focused on server-rendered Single-Page Applications using Node.js as the server. Mixing Vue SSR with other backend setups is a topic of its own and is not covered in this guide. +本指南专注于,使用 Node.js server 的服务器端单页面应用程序渲染。将 Vue 服务器端渲染(SSR)与其他后端设置进行混合使用,是其它后端自身的一个主题,本指南不包括在内。 -This guide will be very in-depth and assumes you are already familiar with Vue.js itself, and have decent working knowledge of Node.js and webpack. If you prefer a higher-level solution that provides a smooth out-of-the-box experience, you should probably give [Nuxt.js](http://nuxtjs.org/) a try. It's built upon the same Vue stack but abstracts away a lot of the boilerplate, and provides some extra features such as static site generation. However, it may not suit your use case if you need more direct control of your app's structure. Regardless, it would still be beneficial to read through this guide to better understand how things work together. +本指南将会非常深入,并且假设您已经熟悉 Vue.js 本身,并且具有 Node.js 和 webpack 的相当不错的应用经验。如果您具有更高级解决方案,可以提供一个平缓的开箱即用体验,您应该去尝试使用 [Nuxt.js](http://nuxtjs.org/)。它建立在同等的 Vue 技术栈之上,但抽象出很多模板,并提供了一些额外的功能,例如静态站点生成。但是,如果您需要更直接地控制应用程序的结构,Nuxt.js 并不适合这种使用场景。无论如何,阅读本指南将更有助于更好地了解一切如何运行。 -As you read along, it would be helpful to refer to the official [HackerNews Demo](https://github.com/vuejs/vue-hackernews-2.0/), which makes use of most of the techniques covered in this guide. +当您阅读时,参考官方 [HackerNews Demo](https://github.com/vuejs/vue-hackernews-2.0/) 将会有所帮助,此示例使用了本指南涵盖的大部分技术。 -Finally, note that the solutions in this guide are not definitive - we've found them to be working well for us, but that doesn't mean they cannot be improved. They might get revised in the future - and feel free to contribute by submitting pull requests! +最后,请注意,本指南中的解决方案不是限定的 - 我们发现它们对我们来说很好,但这并不意味着无法继续改进。可能会在未来持续改进,欢迎通过随意提交 pull request 作出贡献! + +*** + +> 原文:https://ssr.vuejs.org/en/ \ No newline at end of file diff --git a/en/SUMMARY.md b/en/SUMMARY.md index efd9eaf7..9d7793dd 100644 --- a/en/SUMMARY.md +++ b/en/SUMMARY.md @@ -1,21 +1,21 @@ -- [Basic Usage](basic.md) -- [Writing Universal Code](universal.md) -- [Source Code Structure](structure.md) -- [Routing and Code-Splitting](routing.md) -- [Data Pre-fetching and State](data.md) -- [Client Side Hydration](hydration.md) -- [Introducing Bundle Renderer](bundle-renderer.md) -- [Build Configuration](build-config.md) -- [CSS Management](css.md) -- [Head Management](head.md) -- [Caching](caching.md) -- [Streaming](streaming.md) -- [API Reference](api.md) +- [基本用法](basic.md) +- [编写通用代码](universal.md) +- [源码结构](structure.md) +- [路由和代码分割](routing.md) +- [数据预取和状态](data.md) +- [客户端混合](hydration.md) +- [Bundle Renderer 指引](bundle-renderer.md) +- [构建配置](build-config.md) +- [CSS 管理](css.md) +- [Head 管理](head.md) +- [缓存](caching.md) +- [流式渲染](streaming.md) +- [API 参考](api.md) - [createRenderer](api.md#createrendereroptions) - [createBundleRenderer](api.md#createbundlerendererbundle-options) - [Class: Renderer](api.md#class-renderer) - [Class: BundleRenderer](api.md#class-bundlerenderer) - - [Renderer Options](api.md#renderer-options) + - [Renderer 选项](api.md#renderer-options) - [template](api.md#template) - [clientManifest](api.md#clientmanifest) - [inject](api.md#inject) @@ -24,4 +24,4 @@ - [basedir](api.md#basedir) - [cache](api.md#cache) - [directives](api.md#directives) - - [Webpack Plugins](api.md#webpack-plugins) + - [webpack 插件](api.md#webpack-plugins) diff --git a/en/api.md b/en/api.md index 8c82f6b5..3fa88a96 100644 --- a/en/api.md +++ b/en/api.md @@ -1,8 +1,8 @@ -# API Reference +# API 参考 ## `createRenderer([options])` -Create a [`Renderer`](#class-renderer) instance with (optional) [options](#renderer-options). +使用(可选的)[选项](#renderer-options)创建一个 [`Renderer`](#class-renderer) 实例。 ``` js const { createRenderer } = require('vue-server-renderer') @@ -11,115 +11,114 @@ const renderer = createRenderer({ ... }) ## `createBundleRenderer(bundle[, options])` -Create a [`BundleRenderer`](#class-bundlerenderer) instance with a server bundle and (optional) [options](#renderer-options). +使用 server bundle 和(可选的)[选项](#renderer-options)创建一个 [`BundleRenderer`](#class-bundlerenderer) 实例。 ``` js const { createBundleRenderer } = require('vue-server-renderer') const renderer = createBundleRenderer(serverBundle, { ... }) ``` -The `serverBundle` argument can be one of the following: +`serverBundle` 参数可以是以下之一: -- An absolute path to generated bundle file (`.js` or `.json`). Must start with `/` to be treated as a file path. +- 绝对路径,用于生成 bundle 文件(`.js` 或 `.json`)。必须以 `/` 开头,作为文件路径处理。 -- A bundle object generated by webpack + `vue-server-renderer/server-plugin`. +- 由 webpack + `vue-server-renderer/server-plugin` 生成的 bundle 对象。 -- A string of JavaScript code (not recommended). +- JavaScript 代码字符串(不推荐)。 -See [Introducing the Server Bundle](./bundle-renderer.md) and [Build Configuration](./build-config.md) for more details. +更多细节请查看 [Server Bundle 指引](./bundle-renderer.md) 和[构建配置](./build-config.md)。 ## `Class: Renderer` - #### `renderer.renderToString(vm[, context], callback)` - Render a Vue instance to string. The context object is optional. The callback is a typical Node.js style callback where the first argument is the error and the second argument is the rendered string. + 将 Vue 示例渲染为字符串。上下文对象(context object)可选。回调函数是典型的 Node.js 风格回调,其中第一个参数是 error,第二个参数是渲染的字符串。 - #### `renderer.renderToStream(vm[, context])` - Render a Vue instance to a Node.js stream. The context object is optional. See [Streaming](./streaming.md) for more details. + 将 Vue 示例渲染为 Node.js 流(stream)。上下文对象(context object)可选。更多细节请查看[流式渲染](./streaming.md)。 ## `Class: BundleRenderer` - #### `bundleRenderer.renderToString([context, ]callback)` - Render the bundle to a string. The context object is optional. The callback is a typical Node.js style callback where the first argument is the error and the second argument is the rendered string. + 将 bundle 渲染为字符串。上下文对象(context object)可选。回调是一个典型的Node.js样式回调,其中第一个参数是错误,第二个参数是呈现的字符串。 - #### `bundleRenderer.renderToStream([context])` - Render the bundle to a Node.js stream. The context object is optional. See [Streaming](./streaming.md) for more details. + 将 bundle 渲染为 Node.js 流(stream). 上下文对象(context object)可选。更多细节请查看[流式渲染](./streaming.md)。 -## Renderer Options +## Renderer 选项 - #### `template` - Provide a template for the entire page's HTML. The template should contain a comment `` which serves as the placeholder for rendered app content. + 为整个页面的 HTML 提供一个模板。此模板应包含注释 ``,作为渲染应用程序内容的占位符。 - The template also supports basic interpolation using the render context: + 模板还支持使用渲染上下文(render context)进行基本插值: - - Use double-mustache for HTML-escaped interpolation; - - Use triple-mustache for non-HTML-escaped interpolation. + - 使用双花括号(double-mustache)进行 HTML 转义插值(HTML-escaped interpolation); + - 使用三花括号(triple-mustache)进行 HTML 不转义插值(non-HTML-escaped interpolation)。 - The template automatically injects appropriate content when certain data is found on the render context: + 当在渲染上下文(render context)找到某些数据时,模板会自动注入合适的内容: - - `context.head`: (string) any head markup that should be injected into the head of the page. + - `context.head`:(字符串)任意 head 标记(markup),将注入到页面头部。 - - `context.styles`: (string) any inline CSS that should be injected into the head of the page. Note this property will be automatically populated if using `vue-loader` + `vue-style-loader` for component CSS. + - `context.styles`:(字符串)任意内联 CSS,将注入到页面头部。注意,如果对组件 CSS 使用 `vue-loader` + `vue-style-loader`,此属性将自动填充。 - - `context.state`: (Object) initial Vuex store state that should be inlined in the page as `window.__INITIAL_STATE__`. The inlined JSON is automatically sanitized with [serialize-javascript](https://github.com/yahoo/serialize-javascript) to prevent XSS. + - `context.state`:(对象)初始 Vuex store 状态,将作为 `window.__INITIAL_STATE__` 内联到页面。内联的 JSON 将使用 [serialize-javascript](https://github.com/yahoo/serialize-javascript) 自动清理,以防止 XSS 攻击。 - In addition, when `clientManifest` is also provided, the template automatically injects the following: + 此外,当提供 `clientManifest` 时,模板会自动注入以下内容: - - Client-side JavaScript and CSS assets needed by the render (with async chunks automatically inferred); - - Optimal `` resource hints for the rendered page. + - 渲染所需的客户端 JavaScript 和 CSS 资源(使用异步 chunk 自动推断); + - 为要渲染页面提供最佳的 `` 资源提示(resource hints)。 - You can disable all automatic injections by also passing `inject: false` to the renderer. + 你也可以通过将 `inject: false` 传递给 renderer,来禁用所有自动注入。 - See also: + 具体查看: - - [Using a Page Template](./basic.md#using-a-page-template) - - [Manual Asset Injection](./build-config.md#manual-asset-injection) + - [使用一个页面模板](./basic.md#using-a-page-template) + - [手动资源注入(Manual Asset Injection)](./build-config.md#manual-asset-injection) - #### `clientManifest` - 2.3.0+ - - only used in `createBundleRenderer` - Provide a client build manifest object generated by `vue-server-renderer/server-plugin`. The client manifest provides the bundle renderer with the proper information for automatic asset injection into the HTML template. For more details, see [Generating clientManifest](./build-config.md#generating-clientmanifest). + 生成由 `vue-server-renderer/client-plugin` 生成的客户端构建 manifest 对象(client build manifest object)。客户端 manifest 对象(client manifest)通过「向 HTML 模板自动资源注入」可以为 bundle renderer 提供合适信息。更多详细信息,请查看[生成 clientManifest](./build-config.md#generating-clientmanifest)。 - #### `inject` - 2.3.0+ - Controls whether to perform automatic injections when using `template`. Defaults to `true`. + 控制使用 `template` 时是否执行自动注入。默认是 `true`。 - See also: [Manual Asset Injection](./build-config.md#manual-asset-injection). + 参考:[手动资源注入(Manual Asset Injection)](./build-config.md#manual-asset-injection)。 - #### `shouldPreload` - 2.3.0+ - A function to control what files should have `` resource hints generated. + 一个函数,用来控制什么文件应该生成 `` 资源预加载提示(resource hints)。 - By default, only JavaScript and CSS files will be preloaded, as they are absolutely needed for your application to boot. + 默认情况下,只有 JavaScript 和 CSS 文件会被预加载,因为它们是引导应用程序所必需的。 - For other types of assets such as images or fonts, preloading too much may waste bandwidth and even hurt performance, so what to preload will be scenario-dependent. You can control precisely what to preload using the `shouldPreload` option: + 对于其他类型的资源(如图像或字体),预加载过多可能会浪费带宽,甚至损害性能,因此预加载什么资源具体依赖于场景。你可以使用 `shouldPreload` 选项精确控制预加载资源: ``` js const renderer = createBundleRenderer(bundle, { 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 === 'style') { return true } if (type === 'font') { - // only preload woff2 fonts + // 只预加载 woff2 字体 return /\.woff2$/.test(file) } if (type === 'image') { - // only preload important images + // 只预加载重要 images return file === 'hero.jpg' } } @@ -129,24 +128,34 @@ See [Introducing the Server Bundle](./bundle-renderer.md) and [Build Configurati - #### `runInNewContext` - 2.3.0+ - - only used in `createBundleRenderer` + - 只用于 `createBundleRenderer` + - 期望值:`boolean | 'once'`(`'once'` 只在 2.3.1+ 支持) - By default, for each render the bundle renderer will create a fresh V8 context and re-execute the entire bundle. This has some benefits - for example, we don't need to worry about the "stateful singleton" problem we mentioned earlier. However, this mode comes at some considerable performance cost because re-executing the bundle is expensive especially when the app gets bigger. + 默认情况下,对于每次渲染,bundle renderer 将创建一个新的 V8 上下文并重新执行整个 bundle。这具有一些好处 - 例如,应用程序代码与服务器进程隔离,我们无需担心文档中提到的[状态单例问题](./structure.md#avoid-stateful-singletons)。然而,这种模式有一些相当大的性能开销,因为重新执行 bundle 带来 高性能开销,特别是当应用程序很大时。 - This option defaults to `true` for backwards compatibility, but it is recommended to use `runInNewContext: false` whenever you can. + 此选项默认为 `true` 用于向后兼容,但建议你尽可能使用 `runInNewContext: false` 或 `runInNewContext: 'once'`。 - See also: [Source Code Structure](./structure.md) + > 在 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)的依赖模块不能进行外部暴露; + 2. 从 bundle 执行返回的值将使用不同的全局构造函数,例如,在服务器进程中捕获到 bundle 的内部错误,不会是 `Error` 的一个实例。 + + 参考:[源码结构](./structure.md) - #### `basedir` - 2.2.0+ - - only used in `createBundleRenderer` + - 只用于 `createBundleRenderer` - Explicitly declare the base directory for the server bundle to resolve `node_modules` dependencies from. This is only needed if your generated bundle file is placed in a different location from where the externalized NPM dependencies are installed, or your `vue-server-renderer` is npm-linked into your current project. + 显式地声明 server bundle 的基本目录(base directory),以从 `node_modules` 解析依赖模块。只有在所生成的 bundle 文件与外部的 NPM 依赖模块放置在不同位置,或者 `vue-server-renderer` 是通过 npm-linked 链接当前项目中时,才需要配置。 - #### `cache` - Provide a [component cache](./caching.md#component-level-caching) implementation. The cache object must implement the following interface (using Flow notations): + 提供[组件缓存](./caching.md#component-level-caching)具体实现。缓存对象必须实现以下接口(使用 Flow 记号): ``` js type RenderCache = { @@ -156,7 +165,7 @@ See [Introducing the Server Bundle](./bundle-renderer.md) and [Build Configurati }; ``` - A typical usage is passing in an [lru-cache](https://github.com/isaacs/node-lru-cache): + 典型用法是传入 [lru-cache](https://github.com/isaacs/node-lru-cache): ``` js const LRU = require('lru-cache') @@ -168,14 +177,14 @@ See [Introducing the Server Bundle](./bundle-renderer.md) and [Build Configurati }) ``` - Note that the cache object should at least implement `get` and `set`. In addition, `get` and `has` can be optionally async if they accept a second argument as callback. This allows the cache to make use of async APIs, e.g. a redis client: + 请注意,缓存对象应至少要实现 `get` 和 `set`。此外,如果 `get` 和 `has` 接收第二个参数作为回调,那 `get` 和 `has` 也可以是可选的异步函数。这允许缓存使用异步 API,例如,一个 redis 客户端: ``` js const renderer = createRenderer({ cache: { get: (key, cb) => { redisClient.get(key, (err, res) => { - // handle error if any + // 处理任何错误 cb(res) }) }, @@ -188,35 +197,35 @@ See [Introducing the Server Bundle](./bundle-renderer.md) and [Build Configurati - #### `directives` - Allows you to provide server-side implementations for your custom directives: + 对于自定义指令,允许提供服务器端实现: ``` js const renderer = createRenderer({ directives: { example (vnode, directiveMeta) { - // transform vnode based on directive binding metadata + // 基于指令绑定元数据(metadata)转换 vnode } } }) ``` - As an example, check out [`v-show`'s server-side implementation](https://github.com/vuejs/vue/blob/dev/src/platforms/web/server/directives/show.js). + 例如,请查看 [`v-show` 的服务器端实现](https://github.com/vuejs/vue/blob/dev/src/platforms/web/server/directives/show.js)。 -## Webpack Plugins +## webpack 插件 -The webpack plugins are provided as standalone files and should be required directly: +webpack 插件作为独立文件提供,并且应当直接 require: ``` js const VueSSRServerPlugin = require('vue-server-renderer/server-plugin') const VueSSRClientPlugin = require('vue-server-renderer/client-plugin') ``` -The default files generated are: +生成的默认文件是: -- `vue-ssr-server-bundle.json` for the server plugin; -- `vue-ssr-client-manifest.json` for the client plugin. +- `vue-ssr-server-bundle.json` 用于服务器端插件; +- `vue-ssr-client-manifest.json` 用于客户端插件。 -The filenames can be customized when creating the plugin instances: +创建插件实例时可以自定义文件名: ``` js const plugin = new VueSSRServerPlugin({ @@ -224,4 +233,8 @@ const plugin = new VueSSRServerPlugin({ }) ``` -See [Build Configuration](./build-config.md) for more information. +更多信息请查看[构建配置](./build-config.md)。 + +*** + +> 原文:https://ssr.vuejs.org/en/api.html \ No newline at end of file diff --git a/en/basic.md b/en/basic.md index c5dcebbe..5ab098c3 100644 --- a/en/basic.md +++ b/en/basic.md @@ -1,42 +1,42 @@ -# Basic Usage +# 基本用法 -## Installation +## 安装 ``` bash npm install vue vue-server-renderer --save ``` -We will be using NPM throughout the guide, but feel free to use [Yarn](https://yarnpkg.com/en/) instead. +我们将在整个指南中使用 NPM,但是还可以随意使用 [Yarn](https://yarnpkg.com/en/)。 -#### Notes +#### 注意 -- It's recommended to use Node.js version 6+. -- `vue-server-renderer` and `vue` must have matching versions. -- `vue-server-renderer` relies on some Node.js native modules and therefore can only be used in Node.js. We may provide a simpler build that can be run in other JavaScript runtimes in the future. +- 推荐使用 Node.js 版本 6+。 +- `vue-server-renderer` 和 `vue` 必须匹配版本。 +- `vue-server-renderer` 依赖一些 Node.js 原生模块,因此只能在 Node.js 中使用。我们可能会提供一个更简单的构建,可以在将来在其他「JavaScript 运行时(runtime)」运行。 -## Rendering a Vue Instance +## 渲染一个 Vue 实例 ``` js -// Step 1: Create a Vue instance +// 第 1 步:创建一个 Vue 实例 const Vue = require('vue') const app = new Vue({ template: `
Hello World
` }) -// Step 2: Create a renderer +// 第 2 步:创建一个 renderer const renderer = require('vue-server-renderer').createRenderer() -// Step 3: Render the Vue instance to HTML +// 第 3 步:将 Vue 实例渲染为 HTML renderer.renderToString(app, (err, html) => { if (err) throw err console.log(html) - // =>

hello world

+ // =>
Hello World
}) ``` -## Integrating with a Server +## 与服务器集成 -It is pretty straightforward when used inside a Node.js server, for example [Express](https://expressjs.com/): +在 Node.js 服务器中使用时相当简单直接,例如 [Express](https://expressjs.com/): ``` bash npm install express --save @@ -52,7 +52,7 @@ server.get('*', (req, res) => { data: { url: req.url }, - template: `
The visited URL is: {{ url }}
` + template: `
访问的 URL 是: {{ url }}
` }) renderer.renderToString(app, (err, html) => { @@ -73,11 +73,11 @@ server.get('*', (req, res) => { server.listen(8080) ``` -## Using a Page Template +## 使用一个页面模板 -When you render a Vue app, the renderer only generates the markup of the app. In the example we had to wrap the output with an extra HTML page shell. +当你在渲染 Vue 应用程序时,renderer 只从应用程序生成 HTML 标记(markup)。在这个示例中,我们必须用一个额外的 HTML 页面包裹容器,来包裹生成的 HTML 标记。 -To simplify this, you can directly provide a page template when creating the renderer. Most of the time we will put the page template in its own file, e.g. `index.template.html`: +为了简化这些,你可以直接在创建 renderer 时提供一个页面模板。多数时候,我们会将页面模板放在特有的文件中,例如 `index.template.html`: ``` html @@ -89,9 +89,9 @@ To simplify this, you can directly provide a page template when creating the ren ``` -Notice the `` comment -- this is where your app's markup will be injected. +注意 `` 注释 -- 这里将是应用程序 HTML 标记注入的地方。 -We can then read and pass the file to the Vue renderer: +然后,我们可以读取和传输文件到 Vue renderer 中: ``` js const renderer = createRenderer({ @@ -99,18 +99,21 @@ const renderer = createRenderer({ }) renderer.renderToString(app, (err, html) => { - console.log(html) // will be the full page with app content injected. + console.log(html) // html 将是注入应用程序内容的完整页面 }) ``` -### Template Interpolation +### 模板插值 -The template also supports simple interpolation. Given the following template: +模板还支持简单插值。给定如下模板: ``` html + {{ title }} + + {{{ meta }}} @@ -119,7 +122,7 @@ The template also supports simple interpolation. Given the following template: ``` -We can provide interpolation data by passing a "render context object" as the second argument to `renderToString`: +我们可以通过传入一个"渲染上下文对象",作为 `renderToString` 函数的第二个参数,来提供插值数据: ``` js const context = { @@ -131,17 +134,21 @@ const context = { } renderer.renderToString(app, context, (err, html) => { - // page title will be "hello" - // with meta tags injected + // 页面 title 将会是 "Hello" + // meta 标签也会注入 }) ``` -The `context` object can also be shared with the Vue app instance, allowing components to dynamically register data for template interpolation. +也可以与 Vue 应用程序实例共享 `context` 对象,允许模板插值中的组件动态地注册数据。 + +此外,模板支持一些高级特性,例如: + +- 在使用 `*.vue` 组件时,自动注入「关键的 CSS(critical CSS)」; +- 在使用 `clientManifest` 时,自动注入「资源链接(asset links)和资源预加载提示(resource hints)」; +- 在嵌入 Vuex 状态进行客户端融合(client-side hydration)时,自动注入以及 XSS 防御。 -In addition, the template supports some advanced features such as: +在之后的指南中介绍相关概念时,我们将详细讨论这些。 -- Auto injection of critical CSS when using `*.vue` components; -- Auto injection of asset links and resource hints when using `clientManifest`; -- Auto injection and XSS prevention when embedding Vuex state for client-side hydration. +*** -We will discuss these when we introduce the associated concepts later in the guide. +> 原文:https://ssr.vuejs.org/en/basic.html \ No newline at end of file diff --git a/en/build-config.md b/en/build-config.md index 3beb9032..a98d4a8f 100644 --- a/en/build-config.md +++ b/en/build-config.md @@ -1,81 +1,88 @@ -# Build Configuration +# 构建配置 -We will assume you already know how to configure webpack for a client-only project. The config for an SSR project will be largely similar, but we suggest breaking the config into three files: *base*, *client* and *server*. The base config contains config shared for both environments, such as output path, aliases, and loaders. The server config and client config can simply extend the base config using [webpack-merge](https://github.com/survivejs/webpack-merge). +我们假设你已经知道,如何为纯客户端(client-only)项目配置 webpack。服务器端渲染(SSR)项目的配置大体上与纯客户端项目类似,但是我们建议将配置分为三个文件:*base*, *client* 和 *server*。基本配置(base config)包含在两个环境共享的配置,例如,输出路径(output path),别名(alias)和 loader。服务器配置(server config)和客户端配置(client config),可以通过使用 [webpack-merge](https://github.com/survivejs/webpack-merge) 来简单地扩展基本配置。 -## Server Config +## 服务器配置(Server Config) -The server config is meant for generating the server bundle that will be passed to `createBundleRenderer`. It should look like this: +服务器配置,是用于生成传递给 `createBundleRenderer` 的 server bundle。它应该是这样的: ``` js const merge = require('webpack-merge') -const nodeExternals = require('wepback-node-externals') +const nodeExternals = require('webpack-node-externals') const baseConfig = require('./webpack.base.config.js') const VueSSRServerPlugin = require('vue-server-renderer/server-plugin') module.exports = merge(baseConfig, { - // Point entry to your app's server entry file + // 将 entry 指向应用程序的 server entry 文件 entry: '/path/to/entry-server.js', - // This allows webpack to handle dynamic imports in a Node-appropriate - // fashion, and also tells `vue-loader` to emit server-oriented code when - // compiling Vue components. + // 这允许 webpack 以 Node 适用方式(Node-appropriate fashion)处理动态导入(dynamic import), + // 并且还会在编译 Vue 组件时, + // 告知 `vue-loader` 输送面向服务器代码(server-oriented code)。 target: 'node', - // For bundle renderer source map support + // 对 bundle renderer 提供 source map 支持 devtool: 'source-map', - // This tells the server bundle to use Node-style exports + // 此处告知 server bundle 使用 Node 风格导出模块(Node-style exports) output: { libraryTarget: 'commonjs2' }, // https://webpack.js.org/configuration/externals/#function // https://github.com/liady/webpack-node-externals - // Externalize app dependencies. This makes the server build much faster - // and generates a smaller bundle file. + // 外置化应用程序依赖模块。可以使服务器构建速度更快, + // 并生成较小的 bundle 文件。 externals: nodeExternals({ - // do not externalize dependencies that need to be processed by webpack. - // you can add more file types here e.g. raw *.vue files + // 不要外置化 webpack 需要处理的依赖模块。 + // 你可以在这里添加更多的文件类型。例如,未处理 *.vue 原始文件, + // 你还应该将修改 `global`(例如 polyfill)的依赖模块列入白名单 whitelist: /\.css$/ }), - // This is the plugin that turns the entire output of the server build - // into a single JSON file. The default file name will be - // `vue-ssr-server-bundle.json` + // 这是将服务器的整个输出 + // 构建为单个 JSON 文件的插件。 + // 默认文件名为 `vue-ssr-server-bundle.json` plugins: [ new VueSSRServerPlugin() ] }) ``` -After `vue-ssr-server-bundle.json` has been generated, simply pass the file path to `createBundleRenderer`: +在生成 `vue-ssr-server-bundle.json `之后,只需将文件路径传递给 `createBundleRenderer`: ``` js const { createBundleRenderer } = require('vue-server-renderer') const renderer = createBundleRenderer('/path/to/vue-ssr-server-bundle.json', { - // ...other renderer options + // ……renderer 的其他选项 }) ``` -Alternatively, you can also pass the bundle as an Object to `createBundleRenderer`. This is useful for hot-reload during development - see the HackerNews demo for a [reference setup](https://github.com/vuejs/vue-hackernews-2.0/blob/master/build/setup-dev-server.js). +又或者,你还可以将 bundle 作为对象传递给 `createBundleRenderer`。这对开发过程中的热重新是很有用的 - 具体请查看 HackerNews demo 的[参考设置](https://github.com/vuejs/vue-hackernews-2.0/blob/master/build/setup-dev-server.js)。 -## Client Config +### 扩展说明(Externals Caveats) -The client config can remain largely the same with the base config. Obviously you need to point `entry` to your client entry file. Aside from that, if you are using `CommonsChunkPlugin`, make sure to use it only in the client config because the server bundle requires a single entry chunk. +请注意,在 `externals` 选项中,我们将 CSS 文件列入白名单。这是因为从依赖模块导入的 CSS 还应该由 webpack 处理。如果你导入依赖于 webpack 的任何其他类型的文件(例如 `*.vue`, `*.sass`),那么你也应该将它们添加到白名单中。 -### Generating `clientManifest` +如果你使用 `runInNewContext: 'once'` 或 `runInNewContext: true`,那么你还应该将修改 `global` 的 polyfill 列入白名单,例如 `babel-polyfill`。这是因为当使用新的上下文模式时,**server bundle 中的代码具有自己的 `global` 对象。**由于在使用 Node 7.6+ 时,在服务器并不真正需要它,所以实际上只需在客户端 entry 导入它。 -> requires version 2.3.0+ +## 客户端配置(Client Config) -In addition to the server bundle, we can also generate a client build manifest. With the client manifest and the server bundle, the renderer now has information of both the server *and* client builds, so it can automatically infer and inject [preload / prefetch directives](https://css-tricks.com/prefetching-preloading-prebrowsing/) and css links / script tags into the rendered HTML. +客户端配置(client config)和基本配置(base config)大体上相同。显然你需要把 `entry` 指向你的客户端入口文件。除此之外,如果你使用 `CommonsChunkPlugin`,请确保仅在客户端配置(client config)中使用,因为服务器包需要单独的入口 chunk。 -The benefits is two-fold: +### 生成 `clientManifest` -1. It can replace `html-webpack-plugin` for injecting the correct asset URLs when there are hashes in your generated filenames. +> 需要版本 2.3.0+ -2. When rendering a bundle that leverages webpack's on-demand code splitting features, we can ensure the optimal chunks are preloaded / prefetched, and also intelligently inject ` - + ` ``` -### Manual Asset Injection +### 手动资源注入(Manual Asset Injection) -By default, asset injection is automatic when you provide the `template` render option. But sometimes you might want finer-grained control over how assets are injected into the template, or maybe you are not using a template at all. In such a case, you can pass `inject: false` when creating the renderer and manually perform asset injection. +默认情况下,当提供 `template` 渲染选项时,资源注入是自动执行的。但是有时候,你可能需要对资源注入的模板进行更细粒度(finer-grained)的控制,或者你根本不使用模板。在这种情况下,你可以在创建 renderer 并手动执行资源注入时,传入 `inject: false`。 -In the `renderToString` callback, the `context` object you passed in will expose the following methods: +在 `renderToString` 回调函数中,你传入的 `context` 对象会暴露以下方法: - `context.renderStyles()` - This will return inline `