Todo的代码已经更新到了React0.14,React0.14分为react和react-dom两部分。如果想查看之前的代码,可以在github上切换到分支react0.13。
最近在学习React,配合Webpack使用使得开发和调试变得方便多了。这几天抽空采用React和Webpack写了一个手机单页面应用,演示地址:http://lab.crazycoder.cc/todo。本文主要记录Webpack与React配合使用的过程(采用node.js来处理)。
1、React
React组件拥有比较灵活的结构,可采用JSX来编写,代码比较简洁。同时React实现一个虚拟DOM树,用于浏览器减少重绘和重排等等。
npm install react --save
2、Webpack
webpack是一个模块加载器,特别灵活,能够像node.js解析代码中的依赖,将代码进行打包等等。
npm install -g webpack
webpack安装完后,需要配置,默认配置文件为webpack.config.js,大概配置如下
var path = require('path');
module.exports = {
entry: [path.resolve(__dirname, 'app/main.js')],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
module: { //loaders
}
};
module中主要是配置一些加载器如css、babel等,后面会给出详细的配置。
这时候Webpack还不能解析JSX,需要安装babel加载器。
npm install babel --save-dev
在配置文件中,将babel配置上就可以解析JSX,同时也可以解析ES6语法了。用ES6来写React瞬间逼格提升。
以前为了动态刷新浏览器的页面,会采用browser-sync。现在有了webpack神器,也可以实现同样的功能,同时也可以实现react热替换,这只需要安装webpack-dev-server,默认开启的是8080端口,在Todo案例中开发环境下的配置如下:
var path = require('path');
var node_modules = path.resolve(__dirname, 'node_modules');
var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js');
module.exports = {
entry: ['webpack/hot/dev-server', path.resolve(__dirname, 'app/main.js')],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
module: {
loaders: [{
test: /\.jsx?$/,
loader: 'babel'
},{
test: /\.css$/,
loader: 'style!css' //同时加载style,css加载器
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&minetype=application/font-woff"
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader"
}],
noParse: [pathToReact] //主要是用于加载压缩后的react.js
}
};
在html文件中,还需要加入http://localhost:8080/webpack-dev-server.js这个js文件。
在package.json中scripts添加一个指令方便开发,具体如下:
"dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build"
在命令行下,执行npm run dev即可开启http://localhost:8080。
Webpack可以通过--config指定运行时的配置文件,所以可以配置一份webpack.production.config.js用于生产环境下,主要是打包css和js。配置如下:
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var node_modules_dir = path.resolve(__dirname, 'node_modules');
var config = {
entry: {
app: path.resolve(__dirname, 'app/main.js'),
vendors: ['react']
},
output: {
path: path.resolve(__dirname, 'prod', 'css'), //主要是为了使fonts在样式目录下
filename: '../js/[name].js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: [node_modules_dir],
loader: 'babel'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&minetype=application/font-woff"
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader"
}]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendors', '../js/vendors.js'), //合并react
new ExtractTextPlugin('all.css', {allChunks: true}) //合并css
]
};
module.exports = config;
以上就是Todo案例中Webpack与React的配置,剩下的就是逻辑代码的编写了。
Todo案例github地址:https://github.com/wengeek/TodoList
案例效果展示如下: