入门
React Hot Loader是一个插件,允许React组件在不丢失状态的情况下进行实时重新加载。它适用于Webpack和其他支持热模块替换(HMR)和Babel插件的捆绑器。
如果你只是想快速启动一个新鲜的准系统样板,一切都可以开箱即用(使用Webpack),请查看react-hot-boilerplate
官方样板:
https://github.com/gaearon/react-hot-boilerplate
或新的,最小的一个:
https://github.com/wkwiatek/react-hot-loader-minimal-boilerplate
集成到您的应用程序中
以下是将React Hot Loader集成到当前项目中的三步指南。
步骤1(共3步):启用热模块更换(HMR)
HMR允许我们在不重新启动服务器的情况下就地替换模块。以下是如何为不同的捆绑包启用它:
的WebPack
选项1:Webpack Dev Server CLI(仅限客户端呈现)
使用阵营热装载机的WebPack最简单,最快捷的选择是使用webpack-dev-server
与--hot
CLI选项。
"scripts": {
"start": "webpack-dev-server --hot"
},
而已!你可以去第2步。
选项2:具有自定义服务器的Webpack Dev Server(仅限客户端呈现)
如果您只在客户端进行渲染,但必须使用某些自定义节点服务器,这仍然是一个简单的选择。您只需server.js
从官方样板复制到您的项目中即可。配置的重要部分是,在创建a时new WebpackDevServer
,需要指定hot: true
为选项。
这是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/');
});
要通过它启动它npm start
,请将以下脚本添加到package.json
:
"scripts": {
"start": "node server.js"
},
在您的工作中webpack.config.js
,您需要将dev服务器和热重装服务器添加到该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
]
最后,Webpack的Hot Replacement插件必须包含在plugins
配置部分中。添加var webpack = require('webpack')
到Webpack配置的顶部,然后添加new webpack.HotModuleReplacementPlugin()
到以下plugins
部分:
plugins: [
new webpack.HotModuleReplacementPlugin()
]
注意:如果您使用的是Webpack Dev Server命令行界面而不是其Node API,请不要在使用该--hot
标志时将此插件添加到配置中。它与--hot
选项互斥。
查看样板文件webpack.config.js
,一起查看。
选项3:使用webpack-dev-middleware(客户端和服务器)快速
如果您使用的是服务器端呈现,则上面的WebpackDevServer是不够的。相反,我们必须使用Express服务器webpack-dev-middleware
。这是一项更多的工作,但也给了我们更多的控制权。我们需要添加这个中间件,这是它的切入点。
XXX TODO
流星
步骤2(共3步):使用HMR替换根组件
要在发生更改时更新组件,您需要向主客户端入口点文件添加一些代码。
如果您的入口点如下所示,<RootContainer>
您应用的顶级组件在哪里:
import React from 'react';
import { render } from 'react-dom';
import RootContainer from './containers/rootContainer.js';
render(<RootContainer />, document.getElementById('react-root'));
添加以下代码以接受对RootContainer 或其任何后代的更改:
if (module.hot) {
module.hot.accept('./containers/rootContainer.js', () => {
const NextRootContainer = require('./containers/rootContainer.js').default;
render(<NextRootContainer />, document.getElementById('react-root'));
})
}
工作原理:当HMR运行时收到更新的模块时,它首先检查模块是否知道如何更新自身。然后它上传导入/需求链,寻找可以接受更新的父模块。添加的代码允许我们的根组件接受来自任何子组件的更新。
请注意,如果没有进一步的步骤,这足以将更改热重新加载到React组件,但是不会保留其内部组件状态,因为安装了组件的新副本,并重新初始化其状态。外部保存在状态存储中的状态(例如Redux)显然不会丢失。
步骤3(共3步):添加React Hot Loader以保留组件状态
要保留内部组件状态,现在需要添加react-hot-loader
到项目中。
安装包:
$ npm install --save-dev react-hot-loader@next
将包添加到您的配置:
一个。如果您使用Babel,请修改您的.babelrc
至少包括:
{
"plugins": [ "react-hot-loader/babel" ]
}
湾 或者,在Webpack中,添加react-hot-loader/webpack
到以下loaders
部分webpack.config.js
:
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot-loader/webpack', 'babel'],
include: path.join(__dirname, 'src')
}]
}
注意:react-hot-loader/webpack
仅适用于导出的组件,而react-hot-loader/babel
拾取文件中的所有顶级变量。作为一种解决方法,使用Webpack,您可以导出要维护其状态的所有组件,即使它们未在其他任何位置导入也是如此。
更新主客户端入口点:
一个。将以下行添加到主客户端入口点的顶部:
import 'react-hot-loader/patch';
或者,在Webpack中,添加react-hot-loader/patch
到以下entry
部分webpack.config.js
:
entry: [
'react-hot-loader/patch', // RHL patch
'./scripts/index' // Your appʼs entry point
]
湾 将应用程序的顶级组件包装在一个内部<AppContainer>
。
AppContainer
是由react-hot-loader
处理热重新加载以及错误处理的组件提供的。它还在内部处理在生产环境中运行时禁用热重新加载/错误处理,因此您不再需要。
您需要将两个实例(例如原始安装)和安装代码包装在module.hot.accept()
函数内部。请注意,<AppContainer>
必须只包装一个React组件。
您的主要入口点现在看起来应该是这样的:
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内置了对ES2015模块的支持,您无需在module.hot.accept中重新使用您的应用程序根目录。上面的例子变成:
注意:要使其工作,您需要通过将Babel ES2015预设更改为选择退出Babel转换ES2015模块
{
"presets": [["es2015", { "modules": false }]]
}
或者在使用latest
预设时:
{
"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) });
}
而已!快乐热重装!
故障排除
如果热重新加载不起作用,通常是由于偏离上述配置。确保将您的设置与react-hot-boilerplate
或进行比较,react-hot-loader-minimal-boilerplate
并验证样板是否适合您。仔细观察小错字。
如果您遇到困难,请在Gitter会议室提出问题或寻求帮助,我们会尽力解决问题。
为了改进我们的文档,我们需要您的反馈!随意为此开一个问题!