webpack和react实战

webpack和react实战

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

开始之前

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

开启实战之旅吧~

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

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

其中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,会产生:

webpack.png

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

index.png

会是这样的效果,但是看到一排的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

webpack_1.png

浏览器打开index.html

index_1.png

本来到这里的时候我们就已经结束了,但是大家有没有想过,当你每次改变了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

index_2.png

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

最后

看到这里,我想大家应该知道webpackreact如何匹配使用了,当然这只是一个引子,希望这篇博文对大家有所帮助,写到这里不得不提的是gulp这个前端自动化工具十分的好用,而且gulp-webpack这个插件可以完美的运用在gulp管理的项目中~

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容