# react-demo **Repository Path**: codershine/react-demo ## Basic Information - **Project Name**: react-demo - **Description**: 一步一步讲解react+webpack的配置;阮一峰React入门案例改造成使用ES6语法形式;React-router的一个完整例子 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2020-02-26 - **Last Updated**: 2024-11-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 文件夹说明 + demo01 是下面博文的主要demo,介绍下怎么配置 + demo02 [阮一峰React入门案例](http://www.ruanyifeng.com/blog/2015/03/react.html)改造成使用ES6语法形式 + demo03 React-router的一个完整例子,我的[另外一篇博客](http://blog.csdn.net/future_todo/article/details/53036638)的demo >http://blog.csdn.net/future_todo/article/details/53036638 + demo04 redux的一个简单的例子 ## 一步一步讲解react+webpack的配置(demo01) 看了很多博客,大都是把配置文件一笔带过,或者干脆不给出配置文件,然而环境搭建对于新手来说是既困难又重要,显然网络上的博客不利于新手开始学习。 BZ打算从从头开始,一步一步配置webpack,能够使用ES6+React组合开发,废话少说让我们一起来开始Webpack+ES6+React之旅。 > 可以在我的[github](https://github.com/zrysmt/react-demo) 中clone或者fork https://github.com/zrysmt/react-demo 当然你也可以使用本博文最后总结的部分或者从我的[github](https://github.com/zrysmt/react-demo)中获得,全部安装插件`npm install`,然后执行`webpack`就可以编译了。 - 使用命令`npm init`新建包管理文件 - 安装webpack ,`npm i --save-dev webpack@1.13.3`,注意:这里用的版本是1.x(@1.13.3)版本的。忽略(@1.13.3)直接下载的会是新版本的,写法会有些改变; - 在项目根目录下新增`webpack.config.js`文件,它的基本结构是: ```javascript var webpack = require('webpack'); module.exports = { entry:{ page: "./src/app.js" }, output: { path: './build', filename: "bundle.js" }, module: { loaders: [ {test:/\.js$/,exclude: /node_modules/,loader:''},//加载器在这里 //下面我们会在这里增加 ] } }; ``` # 1.支持es6 ```bash npm i --save-dev babel-core babel-loader babel-preset-es2015 ``` webpack.config.js ```javascript { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' } ``` .babelrc ```javascript { "presets": [ "es2015" ] } ``` 入口app.js,es6语法 ```javascript var p = require("./es6test/es6test1.js") ``` ```javascript //es6test1.js import Point from './es6test2'; let p = new Point(1,2); console.log(p.toString()); //es6test2.js class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } export default Point; ``` # 2. 支持React语法 ```javascript {test:/\.jsx$/,exclude: /node_modules/,loader:'jsx-loader?harmony'} ``` 入口文件app.js ```javascript var React = require('react'); var ReactDOM = require('react-dom'); var HelloMessage = React.createClass({ render: function() { return

Hello {this.props.name}

; } }); ReactDOM.render( , document.getElementById('example') ); ``` # 3. React和es6同时支持 - 安装 ```bash npm i --save-dev babel-preset-react ``` 注意:.babelrc文件和上面的是一样也是必须的。 webpack.config.js ```javascript {test:/\.jsx?$/,exclude: /node_modules/,loader: 'babel', query: {presets: ['es2015', 'react']}}, //同时支持es6 react 或者下面的写法都可以 {test:/\.jsx?$/,exclude: /node_modules/,loader:'babel?presets[]=react,presets[]=es2015'}, //同时支持es6 react ``` 使用React,es6语法 ```javascript import React from 'react'; import ReactDOM from 'react-dom'; class HelloMessage extends React.Component { render() { return

Hello { this.props.name }

; } } ReactDOM.render( , document.getElementById('example') ); ``` # 4. 其余配置 ## css/sass - 安装 ```bash npm i --save-dev style-loader css-loader sass-loader node-sass ``` - webpack.config.js ```javascript { test: /\.css$/, loader: "style!css" }, { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器 ``` 使用很简单 ```javascript import "./home/home.css"; import "./home/home.scss"; ``` ## css文件可以独立出来 ``` npm i --save-dev extract-text-webpack-plugin ``` 配置 ``` /*下面两行的作用是分离css*/ { test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") }, { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass ``` ## 图片加载 ```bash npm i --save-dev url-loader ``` 配置webpack.config.js ``` {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'} ``` 意思是大于8192kb的图片会以base64的形式加载 使用: ``` //或者在css中直接使用 background: url(imgs/toolbar.png) no-repeat; ``` ## path路径管理 有时候在配置文件中经常会用到路径管理 ``` npm i --save-dev path ``` 在配置文件中 ``` var path = require('path'); output: { path: path.resolve(__dirname, 'output'), }, ``` # 5. 基本功能配置总结: package.json ```javascript { "name": "react-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server --hot --progress --colors", "build": "webpack --progress --colors" }, "repository": { "type": "git", "url": "zry" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.18.0", "babel-loader": "^6.2.7", "babel-preset-es2015": "^6.18.0", "babel-preset-react": "^6.16.0", "css-loader": "^0.25.0", "jsx-loader": "^0.13.2", "node-sass": "^3.10.1", "react": "^15.3.2", "react-dom": "^15.3.2", "sass-loader": "^4.0.2", "style-loader": "^0.13.1", "webpack": "^1.13.3" } } ``` webpack.config.js ```javascript var webpack = require('webpack'); module.exports = { entry:{ page: "./src/app.js" }, output: { path: './build', filename: "bundle.js" }, module: { loaders: [ // { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },//支持es6 // {test:/\.jsx?$/,exclude: /node_modules/,loader:'jsx-loader?harmony'},//支持react // {test:/\.jsx?$/,exclude: /node_modules/,loader:'babel?presets[]=react,presets[]=es2015'},//同时支持es6 react或者 {test:/\.jsx?$/,exclude: /node_modules/,loader: 'babel', query: {presets: ['es2015', 'react']}},//同时支持es6 react {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'}, /*下面两行的作用是分离css*/ /*{ test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") }, { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass加载器*/ { test: /\.css$/, loader: "style!css" }, { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器 ] }, resolve: { extensions: ['', '.js', '.json'] }, plugins: [ // new ExtractTextPlugin("output/[name].css"),//独立css文件 new webpack.NoErrorsPlugin() ], devtool: 'source-map' }; ``` 别忘了.babelrc文件 ```javascript { "presets": [ "es2015" ] } ``` # 6. React支持热插拔 webpack-dev-server支持热插拔(热替换 HRM),使用HRM功能也有两种方式:命令行方式(推荐)和Node.js API 方式。 ## 6.1 Node.js API方式 Node.js API方式需要做三个配置: 1) 把`webpack/hot/dev-server`加入到webpack配置文件的entry项; 2) 把`new webpack.HotModuleReplacementPlugin()`加入到webpack配置文件的plugins项; 3) 把`hot:true`加入到webpack-dev-server的配置项里面。 使用 react 编写代码时,能让修改的部分自动刷新。但这和自动刷新网页是不同的,因为 hot-loader 并不会刷新网页,而仅仅是替换你修改的部分 - 安装 ```bash npm i --save-dev react-hot-loader webpack-dev-server ``` - 修改.babelrc ```javascript { "presets": [ "es2015" ], "plugins":["react-hot-loader/babel"] } ``` - 修改webpack.config.js ```javascript var webpack = require('webpack'); module.exports = { //修改:entry entry: [ "webpack-dev-server/client?http://127.0.0.1:3000", "webpack/hot/only-dev-server", "./src/app.js" ], //修改:output output: { path: __dirname, filename: "build/bundle.js", publicPath: "/build" }, module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } }, //同时支持es6 react {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'}, /*下面两行的作用是分离css*/ /*{ test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") }, { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass加载器*/ { test: /\.css$/, loader: "style!css" }, { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器 ] }, resolve: { extensions: ['', '.js', '.json'] }, plugins: [ // new ExtractTextPlugin("output/[name].css"),//独立css文件 new webpack.NoErrorsPlugin(), //允许错误不打断程序 new webpack.HotModuleReplacementPlugin() //增加:webpack热替换插件 ], devtool: 'source-map' }; ``` - 增加server.js文件 ```javascript 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/') }); ``` 如何使用?--在命令行中 ```bash webpack & node server.js //启动node服务 ``` 在浏览器输入`localhost:3000`即可查看结果,我们修改css文件,保存之后网页会自动刷新显示在浏览器上。js文件修改需要手动刷新一次。 ## 6.2 命令行方式 命令行方式比较简单,需要加入`--inline --hot`。 例子位置在我的[github](https://github.com/zrysmt/react-demo/tree/master/demo03)。 > https://github.com/zrysmt/react-demo/tree/master/demo03 这个例子中执行的命令是: ```bash SET DEBUG=true && webpack-dev-server --history-api-fallback --progress --profile --inline --colors --hot --port 8080 --open ``` 指定端口8080,可以是其它的没有被占用过的任意端口。 具体配置项也有所改变 ```js var webpack = require('webpack'); var path = require('path'); var HtmlwebpackPlugin = require('html-webpack-plugin'); // 定义当前是否处于开发debug阶段 var isDebug = JSON.stringify(JSON.parse(process.env.DEBUG || 'false')); // 根据isDebug变量定义相关config变量 var configVarObj = {}; if(isDebug === 'true') { console.log('I am in debuging............'); configVarObj = { htmlPath: 'index.html', // 定义输出html文件路径 // devtool: 'cheap-source-map' // 生成sourcemap,便于开发调试 devtool: 'eval' // 生成sourcemap,便于开发调试 }; } else { console.log('I am in releasing............'); configVarObj = { htmlPath: /*cjebTemplateFolder + */'/index.html', // 定义输出html文件路径 devtool: '' }; } module.exports = { context: path.join(__dirname, 'src'), entry: { app:"./app.js", vendors: [ 'jquery' ] }, output: { path: path.resolve(__dirname, 'output'), // 输出文件名 filename: 'js'+'/[name].min.js?[hash]', // cmd、amd异步加载脚本配置名称 chunkFilename: 'js'+'/[name].chunk.js?[hash]', publicPath: '' }, module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } }, //同时支持es6 react { test: /\.css$/, loader: "style!css" }, { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器 ] }, resolve: { extensions: ['', '.js', '.jsx','.json'] }, devtool: configVarObj.devtool, plugins: [ new HtmlwebpackPlugin({ title: 'test', template: path.join(__dirname, './index.html'), filename: 'index.html', minify: { minifyJS: true, removeComments: true, minifyCSS: true }, }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), //定义全局变量 new webpack.DefinePlugin({ __DEV__: isDebug }) ] }; ``` > 可以在我的[github](https://github.com/zrysmt/react-demo) https://github.com/zrysmt/react-demo中clone或者fork 参考阅读: - [react-facebook官网](https://facebook.github.io/react/docs/hello-world.html) - [react中文版-极客学院](http://wiki.jikexueyuan.com/project/react/) - [React 入门实例教程--阮一峰](http://www.ruanyifeng.com/blog/2015/03/react.html) - [【译】 在 React.js 中使用 ES6+](http://www.open-open.com/lib/view/open1442217632805.html) - [React.js中常用的ES6写法总结](http://blog.csdn.net/haoshidai/article/details/52244620) - [使用 react-hot-loader](https://segmentfault.com/a/1190000004660311) - [WEBPACK DEV SERVER说明](http://www.jianshu.com/p/941bfaf13be1)