使用 Webpack 建立 React 开发环境
Webpack 包含了许多好用的 loader 可以协助开发者在开发过程中省去不少麻烦。而 LiveReload 更是节省时间不可或缺的功能。本篇将通过一个简单的例子介绍如何使用 webpack-dev-server 与 react-hot-loader 来让开发 React 更为快速方便。如果你是刚开始使用 Webpack 的开发者,建议先读完 Webpack howto 或 如何使用 Webpack 模组整合工具 熟悉 Webpack 后再来使用各式各样的 loader。
webpack-dev-server 与 react-hot-loader 是什么
webpack-dev-server 是个小型的 node.js express server,主要用来跑内的文件,同时提供 LiveReload 的功能。react-hot-loader 则是可以在不改变 React 组件的 state 下,将更改过代码的组件直接更新到画面上。
准备
在目录内先使用 npm init 产生 package.json 再通过 npm install webpack@1.12.14 webpack-dev-server@1.14.1 react-hot-loader@1.3.0 babel-loader@5.4.0 react@0.13.3 –save-dev 指令安装 webpack,webpack-dev-server,react-hot-loader,react 和 babel-loader,并在目录下加入文件与文件夹并整理如以下结构:
app
main.js
TestOne.js
TestTwo.js
/build
bundle.js (会通过 webpack 自动生成)
index.html
package.json
webpack.config.js
顺带一提,babel-loader 是用来解译 jsx 与 ES6 语法的 loader。
接着,将以下代码贴到对应的文件内容内:
main.js
/* main.js */
'use strict';
var React = require('react');
var TestOne = require('./TestOne.js');
var TestTwo = require('./TestTwo.js');
var Main = React.createClass({
getInitialState: function() {
return {
switch: true
};
},
_toggle() {
this.setState({
switch: !this.state.switch
});
},
render() {
return (
<div>
<input type="button" onClick={this._toggle} value="Press Me!"/>
{this.state.switch ? <TestOne /> : <TestTwo />}
div>
);
}
});
React.render(<Main />, document.body);
TestOne.js
/* TestOne.js */
'use strict';
var React = require('react');
var TestOne = React.createClass({
render() {
return (
/* jshint ignore: start*/
Hello I am TestOne Component
/* jshint ignore: end*/
);
}
});
module.exports = TestOne;
TestTwo.js
/* TestTwo.js */
'use strict';
var React = require('react');
var TestTwo = React.createClass({
render() {
return (
/* jshint ignore: start*/
Hello I am TestTwo Component
/* jshint ignore: end*/
);
}
});
module.exports = TestTwo;
index.html
<html>
<head>
<meta charset="UTF-8" />
head>
<body>
<script src="bundle.js">script>
body>
html>
webpack.config.js
var path = require('path');
var config = {
entry: [path.resolve(__dirname, 'app/main.js')],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel']
}]
}
};
module.exports = config;
最后在 package.json 内做修改:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack" //新加入这行
},
当执行 npm run build 后,系统会执行 webpack 的指令并打包,开启 index.html 后就能看到代码正确执行。
使用 webpack-dev-server 实现 LiveReload
现阶段每当我们更改代码并想要看到结果时,就必须要输入 npm run build 一次,还要到浏览器点重新整理才能看到变动后的成果。还好,webpack-dev-server 为我们省去了这个麻烦。
首先,先到 package.json 内加入一个新 dev 的指令:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build"
}
dev内的指令解释如下:
webpack-dev-server 会在 localhost:8080 建立起的 server
–devtool eval 会显示出发生错误的行数与文件名称
–progress 会显示出打包的过程
–colors 会帮 webpack 显示的信息加入颜色
–content-based build 指向最终输出的文件夹
接着更新 index.html :
<html>
<head>
<meta charset="UTF-8" />
head>
<body>
<script src="http://localhost:8080/webpack-dev-server.js">script>
<script src="bundle.js">script>
body>
html>
再来到 webpack.config.js 的 entry 属性内加入 ‘webpack/hot/dev-server’如下:
var path = require('path');
var config = {
entry: ['webpack/hot/dev-server', path.resolve(__dirname, 'app/main.js')],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel']
}]
}
};
module.exports = config;
这样就完成 LiveReload 的功能,各位可以在执行 npm run dev 后到 http://localhost:8080/ 检查是否有正确跑起来,也可以试着在代码内做些改变,并观察画面是否有跟着变动。
加入 react-hot-loader
如果你有跟着以上每一步做的话,代码跑起来后应该会有一个按钮和 “Hello, I’m TestOne Component” 的字出现在画面上。 重复点击按钮,”Hello, I’m TestOne Component” 和 “Hello, I’m TestTwo Component” 会轮流出现在画面上。
现在请将画面切到显示 “Hello, I’m TestTwo Component” ,并到 TestTwo.js 将 “Hello, I’m TestTwo Component” 改为 “Hello” 后储存。完成后,会发现浏览器画面会回到最初的 “Hello, I’m TestOne Component”,这是因为 LiveReload 会重新整理画面并将 React 组件的 state 重设回到初始值。
react-hot-loader 的功用就是在不清除 state 的状态下更新画面,让我们赶快来看看该如何达成这个效果吧。
首先,修改 webpack.config.js 内的 entry 属性如下:
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
path.resolve(__dirname, 'app/main.js')
]
再来修改 module 属性如下:
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'app')
}]
},
这部分要特别注意的地方是一定要加入 include: path.join(__dirname, ‘app’),不然 webpack 会把 node_modules 内的 js 档都通过 react-hot-loader 跑一遍,会因此导致 Cannot read property ‘NODE_ENV’ of undefined 错误造成代码无法正常运作。
最后一步,在 webpack.config.js
内加入以下属性,别忘了要先声明 var webpack = require('webpack');:
plugins: [
//new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
这边的 webpack.NoErrorsPlugin()
是选择性的,主要的功能是当更改完的代码有语法错误时不要重新整理。 当错误修好后,画面会自动重新整理。
new webpack.HotModuleReplacementPlugin() 则是当不使用 webpack-dev-server 的 inline-mode 时才需要加入。本例是使用 inline-mode,你可以试着把注释掉的部分加回代码里,当组件在做更新时,会出现 Uncaught RangeError: Maximum call stack size exceeded 的错误信息。inline-mode 详情请参考 webpack-dev-server 说明。
现在执行 npm run dev 后再一次做本段落最开始的实验,就会发现更改代码后,画面不会再回到首页了。
总结
最近使用 webpack 的开发者越来越多,如果想深入了解的话不妨多搜寻一下网络上的教学,会发现它能够完成的事情其实很多。如果在实作以上例子有碰到问题或有更好的建议的话,欢迎各位留言讨论。
转载请注明: Vue教程中文网 - 打造国内领先的vue学习网站-vue视频,vue教程,vue学习,vue培训 » 使用 Webpack 建立 React 开发环境