Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(cn): translate content/docs/code-splitting.md into Chinese #11

Merged
merged 10 commits into from
Feb 18, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 40 additions & 74 deletions content/docs/code-splitting.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
---
id: code-splitting
title: Code-Splitting
title: 代码分割
permalink: docs/code-splitting.html
---

## Bundling
## 打包

Most React apps will have their files "bundled" using tools like
[Webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/).
Bundling is the process of following imported files and merging them into a
single file: a "bundle". This bundle can then be included on a webpage to load
an entire app at once.
大多数 React 应用都会使用 [Webpack](https://webpack.docschina.org) 或 [Browserify](http://browserify.org/) 这类的构建工具来打包文件。打包是一个将文件引入并合并到一个单独文件的过程,最终形成一个 “bundle”。接着在页面上引入该 bundle,整个应用即可一次性加载。

#### Example
#### 示例

**App:**
**App文件:**

```js
// app.js
Expand All @@ -30,7 +26,7 @@ export function add(a, b) {
}
```

**Bundle:**
**打包后文件:**

```js
function add(a, b) {
Expand All @@ -40,86 +36,62 @@ function add(a, b) {
console.log(add(16, 26)); // 42
```

> Note:
> 注意:
>
> Your bundles will end up looking a lot different than this.
> 最终你的打包文件看起来会和上面的例子区别很大。

If you're using [Create React App](https://github.com/facebookincubator/create-react-app), [Next.js](https://github.com/zeit/next.js/), [Gatsby](https://www.gatsbyjs.org/), or a similar tool, you will have a Webpack setup out of the box to bundle your
app.
如果你正在使用 [Create React App](https://github.com/facebookincubator/create-react-app),[Next.js](https://github.com/zeit/next.js/),[Gatsby](https://www.gatsbyjs.org/),或者类似的工具,你会拥有一个可以直接使用的 Webpack 配置来进行打包工作。

If you aren't, you'll need to setup bundling yourself. For example, see the
[Installation](https://webpack.js.org/guides/installation/) and
[Getting Started](https://webpack.js.org/guides/getting-started/) guides on the
Webpack docs.
如果你没有使用这类工具,你就需要自己来进行配置。例如,查看 Webpack 文档上的[安装](https://webpack.docschina.org/guides/installation/)和[入门教程](https://webpack.docschina.org/guides/getting-started/)。

## Code Splitting
## 代码分割

Bundling is great, but as your app grows, your bundle will grow too. Especially
if you are including large third-party libraries. You need to keep an eye on
the code you are including in your bundle so that you don't accidentally make
it so large that your app takes a long time to load.
打包是个非常棒的技术,但随着你的应用增长,你的代码包也将随之增长。尤其是在整合了体积巨大的第三方库的情况下。你需要关注你代码包中所包含的代码,以避免因体积过大而导致加载时间过长。

To avoid winding up with a large bundle, it's good to get ahead of the problem
and start "splitting" your bundle.
[Code-Splitting](https://webpack.js.org/guides/code-splitting/) is a feature
supported by bundlers like Webpack and Browserify (via
[factor-bundle](https://github.com/browserify/factor-bundle)) which can create
multiple bundles that can be dynamically loaded at runtime.
为了避免搞出大体积的代码包,在前期就思考该问题并对代码包进行分割是个不错的选择。代码分割是由诸如 Webpack([代码分割](https://webpack.docschina.org/guides/code-splitting/))和 Browserify([factor-bundle](https://github.com/browserify/factor-bundle))这类打包器支持的一项技术,能够创建多个包并在运行时动态加载。

Code-splitting your app can help you "lazy-load" just the things that are
currently needed by the user, which can dramatically improve the performance of
your app. While you haven't reduced the overall amount of code in your app,
you've avoided loading code that the user may never need, and reduced the amount
of code needed during the initial load.
对你的应用进行代码分割能够帮助你“懒加载”当前用户所需要的内容,能够显著地提高你的应用性能。尽管并没有减少应用整体的代码体积,但你可以避免加载用户永远不需要的代码,并在初始加载的时候减少所需加载的代码量。

## `import()`

The best way to introduce code-splitting into your app is through the dynamic
`import()` syntax.
在你的应用中引入代码分割的最佳方式是通过动态 `import()` 语法。

**Before:**
**使用之前:**

```js
import { add } from './math';

console.log(add(16, 26));
```

**After:**
**使用之后:**

```js
import("./math").then(math => {
console.log(math.add(16, 26));
});
```

> Note:
> 注意:
>
> The dynamic `import()` syntax is a ECMAScript (JavaScript)
> [proposal](https://github.com/tc39/proposal-dynamic-import) not currently
> part of the language standard. It is expected to be accepted in the
> near future.
> 动态 `import()` 语法目前只是一个 ECMAScript (JavaScript) [提案](https://github.com/tc39/proposal-dynamic-import),
> 而不是正式的语法标准。预计在不远的将来就会被正式接受。

When Webpack comes across this syntax, it automatically starts code-splitting
your app. If you're using Create React App, this is already configured for you
and you can [start using it](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#code-splitting) immediately. It's also supported
out of the box in [Next.js](https://github.com/zeit/next.js/#dynamic-import).
当 Webpack 解析到该语法时,它会自动地开始进行代码分割。如果你使用 Create React App,该功能已配置好,你能[立刻使用](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#code-splitting)这个特性。[Next.js](https://github.com/zeit/next.js/#dynamic-import) 也已支持该特性而无需再配置。

If you're setting up Webpack yourself, you'll probably want to read Webpack's
[guide on code splitting](https://webpack.js.org/guides/code-splitting/). Your Webpack config should look vaguely [like this](https://gist.github.com/gaearon/ca6e803f5c604d37468b0091d9959269).
如果你自己配置 Webpack,你可能要阅读下 Webpack 关于[代码分割](https://webpack.docschina.org/guides/code-splitting/)的指南。你的 Webpack 配置应该[类似于此](https://gist.github.com/gaearon/ca6e803f5c604d37468b0091d9959269)。

When using [Babel](http://babeljs.io/), you'll need to make sure that Babel can
parse the dynamic import syntax but is not transforming it. For that you will need [babel-plugin-syntax-dynamic-import](https://yarnpkg.com/en/package/babel-plugin-syntax-dynamic-import).
当使用 [Babel](https://babel.docschina.org/) 时,你要确保 Babel 能够解析动态 import 语法而不是将其进行转换。对于这一要求你需要 [babel-plugin-syntax-dynamic-import](https://yarnpkg.com/en/package/babel-plugin-syntax-dynamic-import) 插件。

## `React.lazy`

> Note:
> 注意:
>
> `React.lazy` and Suspense is not yet available for server-side rendering. If you want to do code-splitting in a server rendered app, we recommend [Loadable Components](https://github.com/smooth-code/loadable-components). It has a nice [guide for bundle splitting with server-side rendering](https://github.com/smooth-code/loadable-components/blob/master/packages/server/README.md).
> `React.lazy` Suspense 技术还不支持服务端渲染。如果你想要在使用服务端渲染的应用中使用,我们推荐 [Loadable Components](https://github.com/smooth-code/loadable-components) 这个库。它有一个很棒的[服务端渲染打包指南](https://github.com/smooth-code/loadable-components/blob/master/packages/server/README.md)

The `React.lazy` function lets you render a dynamic import as a regular component.
`React.lazy` 函数能让你像渲染常规组件一样处理动态引入(的组件)。

**Before:**
**使用之前:**

```js
import OtherComponent from './OtherComponent';
Expand All @@ -133,7 +105,7 @@ function MyComponent() {
}
```

**After:**
**使用之后:**

```js
const OtherComponent = React.lazy(() => import('./OtherComponent'));
Expand All @@ -147,13 +119,13 @@ function MyComponent() {
}
```

This will automatically load the bundle containing the `OtherComponent` when this component gets rendered.
这个代码将会在渲染组件时,自动导入包含 `OtherComponent` 组件的包。

`React.lazy` takes a function that must call a dynamic `import()`. This must return a `Promise` which resolves to a module with a `default` export containing a React component.
`React.lazy` 接受一个函数,这个函数需要动态调用 `import()`。它必须返回一个 `Promise`,该 Promise 需要 resolve 一个 `defalut` export React 组件。

### Suspense

If the module containing the `OtherComponent` is not yet loaded by the time `MyComponent` renders, we must show some fallback content while we're waiting for it to load - such as a loading indicator. This is done using the `Suspense` component.
如果在 `MyComponent` 渲染完成后,包含 `OtherComponent` 的模块还没有被加载完成,我们可以使用加载指示器为此组件做优雅降级。这里我们使用 `Suspense` 组件来解决。

```js
const OtherComponent = React.lazy(() => import('./OtherComponent'));
Expand All @@ -169,7 +141,7 @@ function MyComponent() {
}
```

The `fallback` prop accepts any React elements that you want to render while waiting for the component to load. You can place the `Suspense` component anywhere above the lazy component. You can even wrap multiple lazy components with a single `Suspense` component.
`fallback` 属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 `Suspense` 组件置于懒加载组件之上的任何位置。你甚至可以用一个 `Suspense` 组件包裹多个懒加载组件。

```js
const OtherComponent = React.lazy(() => import('./OtherComponent'));
Expand All @@ -189,9 +161,9 @@ function MyComponent() {
}
```

### Error boundaries
### 异常捕获边界(Error boundaries

If the other module fails to load (for example, due to network failure), it will trigger an error. You can handle these errors to show a nice user experience and manage recovery with [Error Boundaries](/docs/error-boundaries.html). Once you've created your Error Boundary, you can use it anywhere above your lazy components to display an error state when there's a network error.
如果模块加载失败(如网络问题),它会触发一个错误。你可以通过[异常捕获边界(Error boundaries)](/docs/error-boundaries.html)技术来处理这些情况,以显示良好的用户体验并管理恢复事宜。

```js
import MyErrorBoundary from './MyErrorBoundary';
Expand All @@ -212,19 +184,13 @@ const MyComponent = () => (
);
```

## Route-based code splitting
## 基于路由的代码分割

Deciding where in your app to introduce code splitting can be a bit tricky. You
want to make sure you choose places that will split bundles evenly, but won't
disrupt the user experience.
决定在哪引入代码分割需要一些技巧。你需要确保选择的位置能够均匀地分割代码包而不会影响用户体验。

A good place to start is with routes. Most people on the web are used to
page transitions taking some amount of time to load. You also tend to be
re-rendering the entire page at once so your users are unlikely to be
interacting with other elements on the page at the same time.
一个不错的选择是从路由开始。大多数网络用户习惯于页面之间能有个加载切换过程。你也可以选择重新渲染整个页面,这样您的用户就不必在渲染的同时再和页面上的其他元素进行交互。

Here's an example of how to setup route-based code splitting into your app using
libraries like [React Router](https://reacttraining.com/react-router/) with `React.lazy`.
这里是一个例子,展示如何在你的应用中使用 `React.lazy` 和 [React Router](https://react-router.docschina.org/) 这类的第三方库,来配置基于路由的代码分割。

```js
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
Expand All @@ -245,9 +211,9 @@ const App = () => (
);
```

## Named Exports
## 命名导出(Named Exports

`React.lazy` currently only supports default exports. If the module you want to import uses named exports, you can create an intermediate module that reexports it as the default. This ensures that treeshaking keeps working and that you don't pull in unused components.
`React.lazy` 目前只支持默认导出(default exports)。如果你想被引入的模块使用命名导出(named exports),你可以创建一个中间模块,来重新导出为默认模块。这能保证 treeshaking 不会出错,并且不必引入不需要的组件。

```js
// ManyComponents.js
Expand Down