Skip to content

Latest commit

 

History

History
340 lines (264 loc) · 10.8 KB

react_webpack.md

File metadata and controls

340 lines (264 loc) · 10.8 KB

webpack和react实战

在我原来的文章webpack学习之旅中,我介绍了下关于webpack的用法,我想大家应该通过这篇文章大概知道webpack是怎么使用的了。那么这篇文章将为通过一个小的例子带领大家如何在项目中使用webpack

开始之前

在开始之前,大家必须知道webpack的使用方法,以及react框架的使用方法,在下文中,不会花费较多的篇幅去进行讲解它们的细致的用法。没有接触过它们的同学,可以看这两篇文章webpack学习之旅React_Learn,也可以参考阮一峰老师的教程

开启实战之旅吧~

首先我先说下我们要做啥,我们这次要做一个简单版的留言板功能。需要用到的技术有 webpackreact

  • 第一步,创建一个这样的目录结构

    其中components文件夹放的是react的组件,其他文件夹顾名思义 我想大家肯定知道是用来干啥的了。

  • 第二步,安装一些我们需要用到的包依赖,在该项目中我们要用到jsx loader 还有css loader还有reactreact-dom,除了这些我们还要用到其他的依赖,下文会提到.

     npm install jsx-loader css-loader style-loader --save-dev
     npm install react react-dom --save
    
  • 第三步,分析留言板的组成

    我们都知道react最重要的是思想是组件化,所以我们现在要做的是把一个留言板拆成一个个的组件。一个留言板,至少要分成两小块:1.评论显示区,2.评论区。将这两个小的组件组装起来称为一个大组件,一个留言板便做好了。那么接下来,我们来构建这些组件。

  • 第四步,构成组件 大家先在components文件里创建以下文件messageBoard.js messageForm messageList三个文件 ,分别代表 留言板,评论区,评论显示区。

    • 评论显示区组件代码

        //	messageList.js
        	var React = require('react');
      
        	var MessageList = React.createClass({
        		render: function() {
        			var messages = this.props.data.map(function(message, index) {
        				return (
        					<li key={index}>
        						{message.name} said:
        							<p>{message.message}</p>
        					</li>
        				)
        			});
        	
        			return (
        				<div className="message">
        					<ol id="messageList">
        						{messages}
        					</ol>
        				</div>
        			)
        		}
        	
        	})
        	
        	module.exports = MessageList;
      
    • 评论区组件代码

        //messageForm.js
        var React = require('react');
        
        var MessageForm = React.createClass({
        	getInitialState: function() {
        		return {
        			name: '',
        			message: ''
        		};
        	},
        	handleNameChange: function(e) {
        		this.setState({
        			name: e.target.value
        		})
        	},
        	handleMessageChange: function(e) {
        		this.setState({
        			message: e.target.value
        		})
        	},
        	handleSubmit: function(e) {
        		e.preventDefault();
        		var name = this.state.name.trim();
        		var message = this.state.message.trim();
        		if (!name || !message) {
        			return;
        		}
        		this.props.onMessageSubmit({
        			name: name,
        			message: message
        		});
        		this.setState({
        			name: '',
        			message: ''
        		});
        	},
        	componentDidMount: function() {
        
        	},
        	render: function() {
        		return (
        			<div className="row">
                            <form className="messageForm"
                                  onSubmit={this.handleSubmit}>
                                <input
                                type="text"
                                placeholder="Your name"
                                value={this.state.name}
                                onChange={this.handleNameChange}
                                id="textName"
                                className="form-control"/>
                                <input
        	                        type="text"
        	                        placeholder="Say something..."
        	                        value={this.state.message}
        	                        onChange={this.handleMessageChange}
        	                        id="textMessage"
        	                        className="form-control"/>
                                <input
        	                        type="submit"
        	                        className="btn btn-default"
        	                        value="Leave a message"/>
                            </form>
                        </div>
        		)
        	}
        });
        
        
        module.exports = MessageForm;			
      
    • 留言板组件

      因为留言板组件就是由上面的两个小组件所构成的,因为我们没有搭建服务器路由系统,所以我在代码中伪造了些ajax数据请求,在代码中会通过注释解释

        var React = require('react');
        var MessageList = require('../components/messageList.js');
        var MessageForm = require('../components/messageForm.js');
        
        var data = [{
        	name: '小华',
        	message: '你好'
        }]; //模拟在数据库中的留言
        
        var MessageBoard = React.createClass({
        	getInitialState: function() {
        		return {
        			data: []
        	};
        },
        componentDidMount: function() {
        	//模范一个ajax请求数据回客户端的过程,在真实的应用场景中,此处放ajax请求
        	setTimeout(function() {
        		this.setState({
        			data: data
        		})
        	}, 2000)
        },
        handleMessageSubmit: function(message) {
        	//模拟将数据保存到数据库的请求
        	data.push(message);
        	//模拟重新从数据库拉取数据的过程,改变state的值
        	this.setState({
        		data: data
        	});
        },
        render: function() {
        	return (
        		<div className="messageBoard">
        				<h3>{this.props.title}</h3>
        				<MessageList data={this.state.data} />
        				<MessageForm onMessageSubmit={this.handleMessageSubmit}/>
        			</div>
        	)
        }
        })
        
        module.exports = MessageBoard;	
      
  • 第五步,写webpack的入口文件和html文件 在html文件夹中创建一个index.html

      	<!DOCTYPE html>
      	<html lang="en">
      	<head>
      		<meta charset="UTF-8">
      		<title>webpack with react</title>
      	</head>
      	<body>
      		<div id="container"></div>
      		<!-- webpack执行后的输出文件 -->
      		<script src="../js/dist/bundle.js"></script>
      	</body>
      	</html>
    

    js文件夹中创建一个entry.js

      	var React = require('react');
      	var ReactDOM = require('react-dom');
      	var MessageBoard = require('../components/MessageBoard.js');
      	
      	ReactDOM.render(<MessageBoard title="留言板"/>,
      		document.getElementById('container')
      	)
    
  • 第六步, 写webpack配置文件

      	//webpack.config.js
      	var path = require('path');
    
      	module.exports = {
      		entry: './js/entry.js',
      		output: {
      			path: path.join(__dirname, 'js/dist'),
      			filename: 'bundle.js'
      		},
      		module: {
      			loaders: [{
      				test: /\.js|jsx$/,
      				loader: 'jsx?harmony'
      			}]
      		}
      	}
    
  • 第七步,运行webpack

    在终端输入webpack,会产生:

    这就意味着我们成功了,接下来,用浏览器打开index.html

    会是这样的效果,但是看到一排的input标签元素 是不是很难受?那接下来我们简单的调解下css样式吧。

  • 第八步,编写css重新利用webpack打包

    css文件夹下,创建一个style.css文件

      //style.css
      input{
      	display: block;
      	margin: 10px;
      }
    

    webpack.config.js中增加css加载器

      	//webpack.config.js
      	...
      	module: {
      	loaders: [{
      		test: /\.js|jsx$/,
      		loader: 'jsx?harmony'
      	}, {
      		test: /\.css$/,
      		loader: 'style-loader!css-loader'
      	}]
      }
    

    entry.js中增加

      	require('../css/style.css');
    

    重新在终端中输入webpack

    浏览器打开index.html

    本来到这里的时候我们就已经结束了,但是大家有没有想过,当你每次改变了cssjs文件都要重新webpack,十分的麻烦,而webpack有个最强大的功能就是热替换,也就是实时更新页面,所以接下来我们就来试试这个功能吧!

  • 第九步 实现热替换(HMR)功能

    为了实现热替换功能,我们首先需要搭建一个服务器才行,在webpack里面有一个开发工具就是可以自动开启一个服务器,所以首先我们先安装依赖

      npm install webpack-dev-server --save-dev
    

    然后改变webpack.config.js

      	//webpack.config.js
      	...
      	entry: [
      	'webpack/hot/dev-server',
      	'webpack-dev-server/client?http://localhost:8080/html',
      	'./js/entry.js'
      	]
      	...	
    

    然后我们就可以开始使用webpack开启一个服务器了,为了开启这个服务,你必须在终端输入很长一段shell

      webpack-dev-server --devtool eval --progress --colors --hot --content-base
    

    大概讲下它们代表的含义

    • webpack-dev-server - 在 localhost:8080 建立一个 Web 服务器
    • --devtool eval - 为你的代码创建源地址。当有任何报错的时候可以让你更加精确地定位到文件和行号
    • --progress - 显示合并代码进度
    • --colors - Yay,命令行中显示颜色!
    • --content-base - 指向设置的输出目录,后面可以写你想指向的输出目录 不写默认为空目录

    为了偷懒,我们在package.json文件里面,增加一些内容

      "scripts": {
          "build": "webpack",
          "dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base"
        }
    

    还要安装webpack的包依赖和react-hot 加载器

      npm install webpack --save
      npm install react-hot-loader --save-dev
    

    再改变下webpack.config.js里面的设置

      	//webpack.config.js
      	module: {
      	loaders: [{
      		test: /\.js|jsx$/,
      		loader: 'react-hot!jsx-loader?harmony'
      	}, {
      		test: /\.css$/,
      		loader: 'style-loader!css-loader'
      	}]
      }
    

    这样我们可以直接在终端输入npm run dev 然后效果和开始直接输入一大串shell一样

    接下来,我们直接在浏览器下访问localhost:8080

    再点击html就可以看到我们的页面了.

##最后

看到这里,我想大家应该知道webpackreact如何匹配使用了,当然这只是一个引子,希望这篇博文对大家有所帮助,写到这里不得不提的是gulp这个前端自动化工具十分的好用,而且gulp-webpack这个插件可以完美的运用在gulp管理的项目中~我用gulp实现了和这个项目一样的功能,没有教程但是大部分都是相似的,附上链接!

附上代码地址 最后,希望这篇博客对大家有所帮助(如果是,请尽情star哦,😄),欢迎提出您的宝贵建议~