webpack和react實戰(zhàn)

webpack和react實戰(zhàn)

在我原來的文章webpack學習之旅中,我介紹了下關于webpack的用法结榄,我想大家應該通過這篇文章大概知道webpack是怎么使用的了。那么這篇文章將為通過一個小的例子帶領大家如何在項目中使用webpack

開始之前

在開始之前,大家必須知道webpack的使用方法,以及react框架的使用方法,在下文中,不會花費較多的篇幅去進行講解它們的細致的用法醒第。沒有接觸過它們的同學,可以看這兩篇文章webpack學習之旅React_Learn,也可以參考阮一峰老師的教程进鸠。

開啟實戰(zhàn)之旅吧~

首先我先說下我們要做啥稠曼,我們這次要做一個簡單版的留言板功能。需要用到的技術有 webpackreact客年。

  • 第一步霞幅,創(chuàng)建一個這樣的目錄結構
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最重要的是思想是組件化,所以我們現(xiàn)在要做的是把一個留言板拆成一個個的組件抵赢。一個留言板,至少要分成兩小塊:1.評論顯示區(qū),2.評論區(qū)。將這兩個小的組件組裝起來稱為一個大組件,一個留言板便做好了唧取。那么接下來,我們來構建這些組件划提。

  • 第四步枫弟,構成組件
    大家先在components文件里創(chuàng)建以下文件messageBoard.js messageForm messageList三個文件 ,分別代表 留言板鹏往,評論區(qū)淡诗,評論顯示區(qū)骇塘。

    • 評論顯示區(qū)組件代碼

        //  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;
      
    • 評論區(qū)組件代碼

        //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;           
      
    • 留言板組件
      因為留言板組件就是由上面的兩個小組件所構成的,因為我們沒有搭建服務器路由系統(tǒng),所以我在代碼中偽造了些ajax數(shù)據(jù)請求,在代碼中會通過注釋解釋

        var React = require('react');
        var MessageList = require('../components/messageList.js');
        var MessageForm = require('../components/messageForm.js');
        
        var data = [{
            name: '小華',
            message: '你好'
        }]; //模擬在數(shù)據(jù)庫中的留言
        
        var MessageBoard = React.createClass({
            getInitialState: function() {
                return {
                    data: []
            };
        },
        componentDidMount: function() {
            //模范一個ajax請求數(shù)據(jù)回客戶端的過程,在真實的應用場景中韩容,此處放ajax請求
            setTimeout(function() {
                this.setState({
                    data: data
                })
            }, 2000)
        },
        handleMessageSubmit: function(message) {
            //模擬將數(shù)據(jù)保存到數(shù)據(jù)庫的請求
            data.push(message);
            //模擬重新從數(shù)據(jù)庫拉取數(shù)據(jù)的過程,改變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文件夾中創(chuàng)建一個index.html

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

    js文件夾中創(chuàng)建一個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,會產(chǎn)生:

webpack.png

這就意味著我們成功了群凶,接下來插爹,用瀏覽器打開index.html

index.png

會是這樣的效果,但是看到一排的input標簽元素 是不是很難受请梢?那接下來我們簡單的調解下css樣式吧赠尾。

  • 第八步,編寫css重新利用webpack打包

    css文件夾下毅弧,創(chuàng)建一個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

本來到這里的時候我們就已經(jīng)結束了气嫁,但是大家有沒有想過,當你每次改變了cssjs文件都要重新webpack够坐,十分的麻煩寸宵,而webpack有個最強大的功能就是熱替換,也就是實時更新頁面,所以接下來我們就來試試這個功能吧元咙!

  • 第九步 實現(xiàn)熱替換(HMR)功能

    為了實現(xiàn)熱替換功能梯影,我們首先需要搭建一個服務器才行,在webpack里面有一個開發(fā)工具就是可以自動開啟一個服務器蛾坯,所以首先我們先安裝依賴

      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 - 為你的代碼創(chuàng)建源地址脉课。當有任何報錯的時候可以讓你更加精確地定位到文件和行號
    • --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哦),歡迎提出您的寶貴建議~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末聋迎,一起剝皮案震驚了整個濱河市脂矫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霉晕,老刑警劉巖庭再,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捞奕,死亡現(xiàn)場離奇詭異,居然都是意外死亡拄轻,警方通過查閱死者的電腦和手機颅围,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恨搓,“玉大人院促,你說我怎么就攤上這事∧套浚” “怎么了一疯?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長夺姑。 經(jīng)常有香客問我墩邀,道長,這世上最難降的妖魔是什么盏浙? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任眉睹,我火速辦了婚禮,結果婚禮上废膘,老公的妹妹穿的比我還像新娘竹海。我一直安慰自己,他們只是感情好丐黄,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布斋配。 她就那樣靜靜地躺著,像睡著了一般灌闺。 火紅的嫁衣襯著肌膚如雪艰争。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天桂对,我揣著相機與錄音甩卓,去河邊找鬼。 笑死蕉斜,一個胖子當著我的面吹牛逾柿,可吹牛的內容都是我干的。 我是一名探鬼主播宅此,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼机错,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了父腕?” 一聲冷哼從身側響起毡熏,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侣诵,沒想到半個月后痢法,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡杜顺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年财搁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躬络。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡尖奔,死狀恐怖,靈堂內的尸體忽然破棺而出穷当,到底是詐尸還是另有隱情提茁,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布馁菜,位于F島的核電站茴扁,受9級特大地震影響,放射性物質發(fā)生泄漏汪疮。R本人自食惡果不足惜峭火,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望智嚷。 院中可真熱鬧卖丸,春花似錦、人聲如沸盏道。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猜嘱。三九已至衅枫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泉坐,已是汗流浹背为鳄。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留腕让,地道東北人孤钦。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像纯丸,于是被迫代替她去往敵國和親偏形。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容