#React Demo
React环境配置:Node+React+Webpack+es6+Less (清单),案例地址:https://github.com/betrs/ReactDemo.git
#安装依赖:
命令中 –save-dev 含义是安装时顺便把配置信息写入到package.json文件中
1.生成一个 package.json文件 :
//使用命令:
npm init //(一路默认即可)
2.安装 react 和 react-dom 依赖:
//使用命令:
npm install react react-dom --save-dev
3.安装 webpack 和 webpack-dev-server 依赖:
//使用命令:
npm install webpack webpack-dev-server --save-dev
4.安装 babel 依赖:
//使用命令:
npm install babel-loader babel-core babel-preset-react babel-preset-es2015 --save-dev
5.安装 less css 处理样式依赖:
//使用命令:
npm install less-loader css-loader style-loader --save-dev
6.安装 url-loader 处理资源依赖:
//使用命令:
npm install url-loader --save-dev
#最终目录结构:
--React
|--node_modules(程序所有依赖)
|--components(组件目录)
|--wujia(组件wujia)
|--images(图片夹子)
|--index.jsx
|--index.less
|--input(组件input)
|--images(图片夹子)
|-- js.jpg
|--input.jsx
|--input.less
|--blog(组件blog)
|--images(图片夹子)
|--index.jsx
|--index.less
|--index.js(入口文件)
|--build(输出目录)
|--index.html
|--bundle.js (输出文件,由webpack打包后生成的)
|--package.json
|--webpack.config.js
#Webpack 配置文件 webpack.config.js 的编写,代码如下(该文件需手动创建取名 webpack.config.js ):
var path = require('path');
var webpack = require('webpack');
var ROOT_PATH = path.resolve(__dirname);
var APP_PATH = path.resolve(__dirname, './components/index.js');
var BUILD_PATH = path.resolve(__dirname, './build');
module.exports = {
entry: APP_PATH, //入口文件路径
output: {
path: BUILD_PATH, //输出打包后的文件路径并生成 bundle.js文件
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.css$/, //正则匹配.css后缀文件,并做相关处理
loader: 'style!css'
}, {
test: /\.less$/, //正则匹配.less后缀文件,并做相关处理
loader: 'style!css!less'
}, {
test: /\.(png|jpg)$/, //正则匹配.png或者jpg后缀文件,并做相关处理
loader: 'url?limit=50000'
}, {
test: /\.(jsx|js)?$/, //正则匹配.jsx或js后缀文件,并做相关处理
loaders: ['babel-loader?presets[]=es2015,presets[]=react']
}]
},
entry: [ //自动更新入口配置
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:3000',
APP_PATH
]
}
#package.json 配置文件 的编写,代码如下:
{
"name": "reactdemo",
"version": "1.0.0",
"description": "this is my first react case.",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server --port 3000 --devtool eval --progress --colors --hot --content-base build",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "jasn",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.20.0",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"react": "^15.4.1",
"react-dom": "^15.4.1",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2"
}
}
#根据目录所示,我们需要创建两个组件,代码分别如下:
1.wujia组件代码:
"use strict"; //开启严格模式
import React from 'react'; //导入react依赖
import ReactDOM from "react-dom"; //导入react-dom依赖
/**
* 创建一个组件,取名 Wujia
* export default 把创建的组件 Wujia 暴露出去
* extends React.Component 让组件继承Component所有属性与方法
**/
export default class Wujia extends React.Component{
render(){
return <a className={this.props.color} href={this.props.src} title={this.props.mes}>{this.props.title}</a>
};
};
组件Wujia编写的less样式 :
@color:blue;
.hello{
color:@color;
text-decoration: none;
&:hover{
text-decoration:underline;
}
}
2.blog组件代码:
"use strict"; //开启严格模式
import React from "react"; //导入react依赖
import ReactDOM from "react-dom"; //导入react-dom依赖
/**
* 创建一个组件,取名 Blog
* export default 把创建的组件 Blog 暴露出去
* extends React.Component 让组件继承Component所有属性与方法
**/
export default class Blog extends React.Component {
render(){
return <a className={this.props.color} href={this.props.src} title={this.props.mes}>{this.props.name}</a>
};
};
组件blog编写的less样式 :
@color:red;
.react{
color:@color;
text-decoration: none;
&:hover{
text-decoration:underline;
}
}
3.input组件代码:
"use strict"; //开启严格模式
import React from "react"; //导入react依赖
import ReactDOM from "react-dom"; //导入react-dom依赖
/**
* 创建一个组件,取名 Input
* export default 把创建的组件 Input 暴露出去
* extends React.Component 让组件继承Component所有属性与方法
**/
export default class Input extends React.Component{
//初始化状态
constructor(props,context){
super(props,context);
this.state = {
value: this.props.value
};
};
//事件函数(输入框改变触发)
changeHandle(ev){
//设置状态
this.setState({
value: ev.target.value
});
};
render(){
return (
<div>
<input className={this.props.class1} type="text" value={this.state.value} onChange={this.changeHandle.bind(this)}/>
<p className={this.props.class2}>{this.state.value}</p>
<img className={this.props.class3} src={this.props.src}/>
</div>
);
};
};
组件input编写的less样式 :
.input{width: 180px;height: 30px;line-height: 30px;padding:0 10px;border:1px solid #ddd;font-size:14px;color:#333;}
.tishi{display: inline-block;font-size:16px;color:green;margin-left:20px;}
.img{display:block;margin-top:20px;}
#创建页面 index.html ( build目录下 )来使用前面创建的两个组件,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello React</title>
</head>
<body>
<div class="wrap"><div>
<script type="text/javascript" src="./bundle.js"></script>
</body>
</html>
#使用webpack打包
Webpack 是一个前端模块加载兼打包工具,可以对 JS、CSS 和 图片 等都作为模块来使用和处理。对不同类型的需要编译的文件,需要使用相应的加载器(比如用 babel 转译 ES6)。
另外,由于 Webpack 需要一个入口文件来进行分析和处理,需要先将 React 组件引入到一个主文件。
从前文的目录结构可以看出, components/index.js 就是这个主文件,它的代码如下:
"use strict";
import React from "react"; //导入react依赖
import ReactDOM from "react-dom"; //导入react-dom依赖
import Wujia from "./wujia/index.jsx";//导入wujia组件
import Blog from "./blog/index.jsx";//导入blog组件
import Input from "./input/input.jsx";//导入input组件
import url from "./input/images/js.jpg";//导入图片资源
import "./wujia/index.less";//导入wujia组件样式
import "./blog/index.less";//导入blog组件样式
import "./input/input.less";//导入input组件样式
//创建一个input组件数据对象
const obj2 = {
value:"吴佳",
class1:"input",
class2:"tishi",
class3:"img",
src:url
};
//开始渲染DOM结构
ReactDOM.render(
(
<div>
<h1>
<Wujia color="hello" title="吴佳" src="https://www.github.com/betrs" mes="吴佳Github"/>
<Blog color="react" name="博客" src="http://www.wujiabk.com" mes="吴佳博客"/>
</h1>
<Input {...obj2}/>
</div>
), document.querySelector(".wrap")
);
最后,需要将编译打包后的文件 bundle.js 引入到 index.html 中:
<body>
...
<script src="./bundle.js"></script>
</body>
#构建和启动
#构建
前面的开发完成后,需要执行 webpack.config.js 中的构建任务,生成 bundle.js ,可以看到在 package.json 中我们在scripts内配置了”build”:”webpack”:
"scripts": {
"build": "webpack"
}
然后执行命令 npm run build 完成构建,此时打开 index.html ,即可看到效果。
#启动服务器
但这种方式显得略 low,一是它是双击以文件的形式打开 HTML 页面,二是每次有更改都要手动执行 npm run build 重新打包。
一种更好的方式是启动一个静态资源服务器,监听文件内容修改并自动打包。在这里用的是前面安装好的 webpack-dev-server ,在 package.json 配置中可以看到如下代码:
"scripts": {
"dev": "webpack-dev-server --port 3000 --devtool eval --progress --colors --hot --content-base build"
}
简单解释一下 dev 中各个参数的含义: webpack-dev-server 在 localhost:3000(不设置端口默认是8080) 建立一个 Web 服务器;
–devtool eval 映射编译好的源码,用于调试;
–progress 显示代码打包进度;
–colors 表示在命令行中显示颜色;
–content-base 来指定 server 启动后的内容目录。
执行命令 npm run dev 启动 server,此时打开浏览器输入 http://localhost:3000 ,即可看到效果。修改一下 Hello 或者 World 组件中的内容,刷新页面,你会发现浏览器中内容也相应改变了。
#自动刷新
前面实现了对文件修改的监听和自动打包,但浏览器还需要手动刷新。其实可以在 Webpack 的配置文件中增加一个入口点,实现自动刷新。
在webpack.config.js中我们可以看到如下代码:
···
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:3000',
APP_PATH
],
···
这样,应用在修改后,浏览器就会实时监听进行自动刷新了。
#说明:
如果设置了自动更新入口,我们需要在package.json配置文件中scripts中设置dev,代码如下:
...
"scripts": {
"dev": "webpack-dev-server --port 3000 --devtool eval --progress --colors --hot --content-base build",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
}
...
最后执行命令:
npm run dev //就可以跑起来了,然后可以试试是不是自动更新。
如果你是直接从github拉下来的demo,首先cd到ReactDemo目录,然后执行:npm install (自动安装依赖),然后输入上方npm run dev 就行了。