官网: gaearon.github.io/react-hot-l…
略显粗糙的翻译
Getting Started (快速开始)
React Hot Loader is a plugin that allows React components to be live reloaded without the loss of state. It works with Webpack and other bundlers that support both Hot Module Replacement (HMR) and Babel plugins.
React Hot Loader
是一个 webpack 插件, 它允许 React 组件在不丢失状态的情况下重新加载。它和 webpack 和其他支持模块热替换(HMR)的打包器 和 babel 插件 一起工作。
If you just want a quick start with a fresh, barebones boilerplate, where everything works out of the box (using Webpack), check out react-hot-boilerplate
, the official boilerplate: github.com/gaearon/rea…
or the new, minimal one:
github.com/wkwiatek/re…
如果你只是想从新的,简单的样板文件开始,在这里一切都是开箱即用的(使用 webpack),查看
react-hot-boilerplate
官方的样板 github.com/gaearon/rea…
Integrating into your app (集成到你的应用中)
What follows is a 3-step guide for integrating React Hot Loader into your current project.
下面是一个集成 React-hot-loader 到你的当前项目中的三步的指南
Step 1 (of 3): Enabling Hot Module Replacement (HMR) (第一步,启用HMR)
HMR allows us to replace modules in-place without restarting the server. Here’s how you can enable it for different bundlers:
HMR 允许我们在不重启服务器的情况下原地替换模块。下边展示了如何在不同的打包器中启用它。
webpack
Option 1: Webpack Dev Server CLI (client-side rendering only) (仅客户端渲染)
The easiest and fastest option to use React Hot Loader with Webpack is to use webpack-dev-server
with --hot
CLI option.
选项1,webpack-dev-server, 在webpack中使用 React Hot Loader 的最简单,最快捷的选项是使用
webpack-dev-server
的--hot
选项
"scripts": { "start": "webpack-dev-server --hot" },
复制代码
That’s it! You can go to the Step 2.
就是这样,你可可以进入步骤2
Option 2: Webpack Dev Server with custom server (client-side rendering only)
If you’re only rendering on the client side but you have to use some custom node server, this is still an easy option. You can simply copy server.js
from the official boilerplate into your project. The important part of the configuration is that when you create a new WebpackDevServer
, you need to specify hot: true
as an option.
如果你只在客户端渲染,但是你必须使用一些自定义的 node服务器,这仍然是简单的选项。你可以简单的从官方的样板文件中复制到你的项目中。配置中重要的部分是当你创建了一个
new WebpackDevServer
时,你需要指定hot: true
作为选项
Here is server.js
from the official boilerplate:
这是一个来自官方样板的
server.js
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true
}).listen(3000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://localhost:3000/');
});
复制代码
To launch it via npm start
, add the following script to your package.json
:
通过
npm start
启动它,在你的package.json
中添加如下脚本
"scripts": { "start": "node server.js" },
复制代码
In your webpack.config.js
, you’ll need to add the dev server and hot reload server to the entry
section. Put them in the entry
array, before your appʼs entry point:
在你的
webpack.config.js
里,你需要添加 dev server 和 hot reload 到entry
部分。把他们放到 entry 数组中,在你的应用入口点之前
entry: [
'webpack-dev-server/client?http://0.0.0.0:3000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./scripts/index' // Your appʼs entry point
]
复制代码
Finally, the Hot Replacement plugin from Webpack has to be included in the plugins
section of the config. Add var webpack = require('webpack')
at the top of your Webpack config, then add new webpack.HotModuleReplacementPlugin()
to the plugins
section:
最后,Webpack 中 的
Hot-Replacement-plugin
必须被包含在配置的 plugins 部分。在你的 webpack 配置顶部添加var webpack = require('webpack')
,然后添加new webpack.HotModuleReplacementPlugin()
到plugins
部分
plugins: [
new webpack.HotModuleReplacementPlugin()
]
复制代码
Note: If you are using the Webpack Dev Server command line interface instead of its Node API, do not add this plugin to your config if you use the --hot
flag. It is mutually exclusive from the --hot
option.
提示:如果你使用 webpack-dev-server 的命令行接口 而不是它的 node api,如果你使用了
--hot
标志,不需要添加这个 plugin 到 你的配置中。
它和 --hot
选项是互斥的
Check out the boilerplate’s webpack.config.js
to see it all together.
请查看样板文件的 webpack.config.js
来查看全部内容
Option 3: Express with webpack-dev-middleware (client & server)
If you are using server-side rendering, the WebpackDevServer above is not enough. Instead, we have to use an Express server with the webpack-dev-middleware
. This is a bit more work, but also gives us more control. We need to add this middleware and it’s entry point.
如果你使用 服务端渲染,上面的 webpackDevServer 是不够的。相反,我们必须使用带有
webpack-dev-middleware
的 Express 服务器。这稍微多了一点工作,但是也给了我们更多的控制。我们需要添加这个中间价 并且把它作为入口点
const express = require('express');
const webpack = require('webpack');
const webpackHotMiddleware = require('webpack-hot-middleware');
const webpackDevMiddleware = require('webpack-dev-middleware');
const config = {
/* webpack options, including: */
entry: [
'react-hot-loader/patch',
'webpack-hot-middleware/client',
'/path/to/your/app.js'
]
};
const compiler = webpack(config);
const app = express();
app.use(
webpackDevMiddleware(compiler, { /* webpack middleware options */ })
).use(
webpackHotMiddleware(compiler)
).listen(3000, () => {
console.log('Listening at http://localhost:3000/');
});
复制代码
**Meteor **(这个应该翻译成啥……)
- If you’re using webpack:webpack, you can follow the Webpack instructions, or ask for help in this forum post.
- Otherwise, for HMR in “native” Meteor, type:
meteor remove ecmascript && meteor add gadicc:ecmascript-hot
or see the README for more details. There are also some Meteor-specific RHLv3 install instructions here.
如果你使用wabpack,你可以按照webpack 的说明,或者在这个论坛帖子中寻求帮助
否则,…(不会翻译了)
Step 2 (of 3): Using HMR to replace the root component (第二,使用 hmr 替换根组件)
To update components when changes occur, you need to add some code to your main client entry point file.
If your entry point looks like this, where <RootContainer>
is your app’s top-level component:
要在变化发生的时候更新组件,你需要向你的主客户端入口文件点添加一些代码。
import React from 'react';
import { render } from 'react-dom';
import RootContainer from './containers/rootContainer.js';
render(<RootContainer />, document.getElementById('react-root'));
复制代码
Add the following code to accept changes to your RootContainer, or any of its descendants:
添加以下代码接受你的根组件更改,或者其他它的后代文件更改
if (module.hot) {
module.hot.accept('./containers/rootContainer.js', () => {
const NextRootContainer = require('./containers/rootContainer.js').default;
render(<NextRootContainer />, document.getElementById('react-root'));
})
}
复制代码
How it works: When the HMR runtime receives an updated module, it first checks to see if the module knows how to update itself. It then goes up the import/require chain, looking for a parent module that can accept the update. The added code allows our root component to accept an update from any child component.
如何工作:当 HMR 运行时接受到了一个更新的模块,它首先检查模块是否知道如何更新自己。然后它向上进入 import/require 链,寻找可以接受更新的父模块。添加的代码允许我们的根组件
Note that, with no further steps, this is enough to hot reload changes to React components, but their internal component state will not be preserved, since a new copy of the component is mounted, and its state is re-initialized. State that is kept externally in a state store, such as Redux, will obviously not be lost.
注意,不需要进一步的步骤,这就足够热加载对于react组件,但是他们的内部的组件的状态不会被保留,因为挂载了组件的新副本,并且它的状态被重新初始化。外部的在状态存储中的状态,例如 redux 显然不会丢失
Step 3 (of 3): Adding React Hot Loader to preserve component state(第三,添加React Hot Loader 保存组件状态)
To preserve internal component state, you now need to add react-hot-loader
to your project.
为了保存内部的组件状态,你需要添加
react-hot-loader
到你的项目中
1. Install the package:
```
$ npm install --save-dev react-hot-loader
```
复制代码
2. Add the package to your config:
a. If you use Babel, modify your `.babelrc` to ensure it includes at least:
> 如果你使用 Babel,修改的你 `.babelrc` ,确保它至少包括
```
{
"plugins": [ "react-hot-loader/babel" ]
}
```
b. Alternatively, in Webpack, add `react-hot-loader/webpack` to the `loaders` section of your `webpack.config.js`:
> 或者 在 webpack 中,添加 `react-hot-loader/webpack` 到你的 `webpack.config.js` 的 `loaders` 部分
```
module: {
loaders: [{
test: /.js$/,
loaders: ['react-hot-loader/webpack', 'babel'],
include: path.join(__dirname, 'src')
}]
}
```
复制代码
Note: react-hot-loader/webpack
only works on exported components, whereas react-hot-loader/babel
picks up all top-level variables in your files. As a workaround, with Webpack, you can export all the components whose state you want to maintain, even if they’re not imported anywhere else.
注意:
react-hot-loader/webpack
只对导出的组件有效,而react-hot-loader/babel
会在你的文件中选取所有的顶级变量。作为一个解决方案,你可以导出所有你想维护的组件状态,即使它们没有被导入到其他地方。
3. Update your main client entry point: (更新你的主客户端入口点)
a. Add following line to the top of your main client entry point: (添加下行在你的主客户端入口的顶部)
import 'react-hot-loader/patch';
复制代码
Alternatively, in Webpack, add react-hot-loader/patch to the entry section of your webpack.config.js
:
(或者,在webpack 中,添加
react-hot-loader/patch
到你的webpack.config.js
的entry
部分)
entry: [
'react-hot-loader/patch', // RHL patch
'./scripts/index' // Your appʼs entry point
]
复制代码
b. Wrap your app’s top-level component inside of an <AppContainer />
. (将你的 app 的顶级组件 包裹在 AppContainer 中)
AppContainer
is a component, provided by react-hot-loader
, that handles hot reloading, as well as error handling. It also internally handles disabling hot reloading/error handling when running in a production environment, so you no longer have to.
AppContainer 是一个由
react-hot-loader
提供的组件,它处理热重载,以及错误处理。当运行在生产环境中时,它也在内部处理禁用热重载和错误处理。
You need to wrap both instances, e.g. your original mount, and your mount code inside of the module.hot.accept()
function. Note that <AppContainer>
must only wrap a single React component.
你需要封装两个实例。注意:AppContainer 必须仅包裹单个 react 组件
Your main entry point should now look something like this:
你的主入口应该可看起来是这样
import 'react-hot-loader/patch';
import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import RootContainer from './containers/rootContainer';
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('root')
);
}
render(RootContainer);
if (module.hot) {
module.hot.accept('./containers/rootContainer.js', () => {
const NextRootContainer = require('./containers/rootContainer').default;
render(NextRootContainer);
});
}
复制代码
c. Webpack 2 has built-in support for ES2015 modules, and you won’t need to re-require your app root in module.hot.accept. The example above becomes: ( Webpack 2 内置了 ES2015 模块的支持,而且你不需要在 module.hot.accept
中重新引入你的应用的根目录, 上面的例子变成:)
Note: To make this work, you’ll need to opt out of Babel transpiling ES2015 modules by changing the Babel ES2015 preset to be
注意:为了使这个工作,你需要通过更改Babel ES2015预设来选择退出Babel transpiling ES2015模块
{ "presets": [["es2015", { "modules": false }]] }
复制代码
or when using latest
preset then: (或者当使用最新的预设时)
{
"presets": [
[
"latest", {
"es2015": {
"modules": false
}
}
]
]
}
复制代码
import 'react-hot-loader/patch';
import React from 'react';
import ReactDom from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import RootContainer from './containers/rootContainer';
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('root')
);
}
render(RootContainer);
if (module.hot) {
module.hot.accept('./containers/rootContainer', () => { render(RootContainer) });
}
复制代码
That’s it! Happy hot reloading!(就是这样!热重载快乐!)
Troubleshooting(问题解决)
If hot reloading doesnʼt work, itʼs usually due to a deviation from the configuration described above. Make sure to compare your setup to react-hot-boilerplate
or react-hot-loader-minimal-boilerplate
and verify that the boilerplate works for you. Look very closely for small typos.
If youʼre stuck, file an issue or ask for help in the Gitter room, and weʼll try to figure it out.
In order to improve our documentation, we need your feedback! Feel free to open an issue for that too!
如果你的 热重载不工作,通常是由于偏离的以上描述的配置。
如果你卡住了,请到 Gitter room 提交问题寻求帮助没我们将设法解决它
为了改进我们的文档,我们需要你的反馈!你也可以打开一个问题!