您的位置:首页 > Web前端 > React

react-hot-loader的使用方式

2018-04-01 12:18 337 查看
webpack中提供了热模块更新的功能,在不刷新整个页面的情况下来替换某些更变的组件,而这样做的最大的好处就在于状态的保存。比如我们前面在输入框中输入的内容,就不会在我们热模块替换以后被刷新掉,让我们要重新再输入一次了。
而react的构建现在一般还是基于webpack的,webpack也提供了对应的插件。react-hot-loader https://github.com/gaearon/react-hot-loader
跟着github上面的例子我们就可以很快进行搭建了。
这里要注意几点。
我们创建项目的时候是类似creat-react-app的方式创建项目的。
creat-react-app的创建方式是有两个js文件,一个是index.js,一个是App.js
App.js是根组件,而index.js才是来执行初始化以及渲染这些工作的。而我们有的时候是把这两个合二为一了。这样就跟官网的对不上会有点。
下面给出一个demo来进行配置



目录结构
App.jsximport React from 'react';
import { hot } from 'react-hot-loader';
import { Hello } from './components/hello.jsx';
require('./font.js');

class App extends React.Component {
constructor(){
super();
console.log("App");
}
render() {
return (
<div>
<h1>
<Hello />
Hello<br />
<input type="text" name="" id="" />
</h1>
<svg className="icon-svg" aria-hidden="true">
<use xlinkHref="#d-icon-gou-check"></use>
</svg>
</div>
)
}
}

export default hot(module)(App)
这里的svg可以进行删除

index.jsximport React from 'react'
import { render } from 'react-dom'
import App from './App.jsx'
import './scss/index.scss';
const root = document.createElement('div')
document.body.appendChild(root)

render(<App />, root)

这里我们可以发现,在index.jsx中是自行创建了一个div所以我们在模版文件中其实可以不用哪个我们经常使用的
<div id=root></div>

子组件
hello.jsximport React from 'react';
import { hot } from 'react-hot-loader';
export class Hello extends React.Component{
render(){
return (
<div>hello</div>
)
}
}

可以发现,我们的子组件并没有使用hot这个东西,代表只要我们给根组件设置hot就好了。
官网上给出的例子是使用--hot进行启动,如果我们只想在webpack中进行配置而不是使用npm script
我们可以这样配置webpack的config文件。
webpack.config.dev.jsconsole.log("dev");

const path = require('path');
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const HotModuleReplacePlgun = require('webpack/lib/HotModuleReplacementPlugin');
module.exports = {
entry: ['react-hot-loader/patch', './src/index.jsx'],
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/',
filename: 'js/[name].js'
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /(node_modules)/,
include: path.resolve(__dirname, 'src'),
use: {
loader: "babel-loader",
options: {
presets: ['env', 'react'],
plugins: ['react-hot-loader/babel'],
}
}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'),
use:[
"style-loader",
"css-loader"
]
},
{
test: /\.scss$/,
include: path.resolve(__dirname, 'src'),
use:[
"style-loader",
"css-loader",
"sass-loader"
]
},
{
test: /\.(gif|png|jpg)$/,
include: path.resolve(__dirname, 'src'),
use: [{
loader: "url-loader",
options: {
limit: 8192,
name: "assets/img/[name].[ext]"
}
}],
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
include: path.resolve(__dirname, 'src'),
use: [{
loader: "url-loader",
options: {
limit: 8192,
name: "assets/[name].[ext]"
}
}],
},
]
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
}),
// new ExtractTextWebpackPlugin("css/[name].css"),
// new ExtractTextWebpackPlugin("scss/[name].scss"),使用这个就无法开启热模块替换了
// 提取公共模块
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: "js/base.js",
}),
// 设置热更新
new HotModuleReplacePlgun(),
new webpack.NamedModulesPlugin(),
],
devServer: {
port: 8888,
// 使用热模块更新,必须安装插件
hot:true,
// 自动在启动后打开浏览器
open : true,
openPage:'dist/',
},
resolve: {
// 配置寻找第三方库的时候的位置
modules: [path.resolve(__dirname, 'node_modules')],
// extensions:['jsx','js','json']
},
watchOptions: {
// 不监听这些文件
ignored: /node_modules/
},
devtool: 'source-map'
};
这里最关键的是
jsx的配置以及入口文件的配置

entry: ['react-hot-loader/patch', './src/index.jsx'],

{ test: /\.jsx$/, exclude: /(node_modules)/, include: path.resolve(__dirname, 'src'), use: { loader: "babel-loader", options: { presets: ['env', 'react'], plugins: ['react-hot-loader/babel'], } } },

然后设置hot为true

devServer: { port: 8888, // 使用热模块更新,必须安装插件 hot:true, // 自动在启动后打开浏览器 open : true, openPage:'dist/', },

这里要注意的一点是,我们没有使用单独提取文件的功能把css进行单独抽出

const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');

这个原因是因为他不支持热模块更新的原型,一旦单独提取了css文件,那么我们修改了scss跟css都不会立即生效。
所以我们需要两个webpack.config.js文件来实现开发跟生产的区分。
最后是npm的执行文件

"dev": "node_modules\\.bin\\webpack-dev-server --config webpack.config.dev.js",

问题得以解决。
因为技术的更新其实很快。可能当你看到这篇博文的时候,里面的方法已经跟最新版的对不上了,这个时候我还是建议你去github上面把这个项目clone下来。然后执行一下里面的例子看看,这个样子应该会好一点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: