亚洲国产中文精品无码久久_亚洲妇女自偷自偷图片_亚洲第一国产毛片久久久_亚洲国产成人片在线观看无码_日本少妇被黑人粗大的猛激进

您當前的位置:首頁(yè) > 新聞資訊 > 產(chǎn)品動(dòng)態(tài) > 正文

【新東網(wǎng)技術(shù)大咖帶您走進(jìn)Webpack】談?wù)凴eact開(kāi)發(fā)神器webpack是什么鬼!

發(fā)布時(shí)間: 2016-09-23 15:13:35  
分享到:

 

文/謝海東 通信研發(fā)部

 

 

 
 
 
專(zhuān)欄介紹

新東網(wǎng)自2001年成立以來(lái),掌握大數據、云計算、通信、物聯(lián)網(wǎng)及區塊鏈等信息技術(shù),擁有一支逾16年經(jīng)驗的強大IT團隊。為沉淀企業(yè)技術(shù)實(shí)力,繼續發(fā)揮行業(yè)優(yōu)勢,《東網(wǎng)快訊》特邀新東網(wǎng)技術(shù)大咖帶您走進(jìn)這些領(lǐng)先進(jìn)信息技術(shù),揭秘新東網(wǎng)16年來(lái)的技術(shù)成果,每周五發(fā)布。

 

 

 

= ̄ω ̄=什么鬼?這么長(cháng)!不想看啦!

 

別急呀!讓哥告訴你這是什么鬼?。?!

 

?先看下面這個(gè)配置文件,如果每一項你都懂,那本文能帶給你的收獲也許就比較有限,你可以快速瀏覽或直接跳過(guò);如果你對很多選項存在著(zhù)疑惑,那花一段時(shí)間慢慢閱讀本文,你的疑惑一定一個(gè)一個(gè)都會(huì )消失;如果你以前沒(méi)怎么接觸過(guò)Webpack,而你又對Webpack感興趣,那么動(dòng)手跟著(zhù)本文中那個(gè)貫穿始終的例子寫(xiě)一次,以后你會(huì )發(fā)現你已明明白白地穿越Webpack的大門(mén)。

 

 

 

基于上一期華西的老閆→_→介紹了React的衍生技術(shù)React Native(多么無(wú)私啊,請猛戳我的姊妹篇吧?。?/span>,這期我們就來(lái)談?wù)動(dòng)糜赗eact開(kāi)發(fā)和模塊管理的主流工具Webpack。

 

雖然Webpack是一個(gè)通用的工具,并不只適合于React,但由于很多涉及React的項目都使用了Webpack,尤其是還有react-hot-loader這樣的神器存在,于是很自然地,Webpack成為了最主流的React開(kāi)發(fā)工具。

 

Webpack有點(diǎn)類(lèi)似browserify,出自Facebook的Instagram團隊,但功能比browserify更為強大。其主要特性如下:

 

1. 同時(shí)支持CommonJSAMD模塊(對于新項目,推薦直接使用CommonJS);

 

2. 串聯(lián)式模塊加載器以及插件機制,讓其具有更好的靈活性和擴展性,例如提供對CoffeeScript、ES6的支持;

 

3. 可以基于配置或者智能分析打包成多個(gè)文件,實(shí)現公共模塊或者按需加載;

 

4. 支持對CSS、圖片等資源進(jìn)行打包,從而無(wú)需借助Grunt或Gulp;

 

5. 開(kāi)發(fā)時(shí)在內存中完成打包,性能更快,完全可以支持開(kāi)發(fā)過(guò)程的實(shí)時(shí)打包需求;

 

6. 對sourcemap有很好的支持,易于調試。

 

Webpack將項目中用到的一切靜態(tài)資源都視之為模塊,模塊之間可以互相依賴(lài)。Webpack對它們進(jìn)行統一的管理以及打包發(fā)布,其官方主頁(yè)用下面這張圖來(lái)說(shuō)明Webpack的作用:

 


 

可以看到Webpack的目標就是對項目中的靜態(tài)資源進(jìn)行統一管理,為產(chǎn)品的最終發(fā)布提供優(yōu)秀的打包部署方案。

 

 

安裝webpack 加載一個(gè)簡(jiǎn)單的React組件
 

 

Webpack一般作為全局的npm模塊安裝:

npm install -g webpack

之后便有了全局的webpack命令,直接執行此命令會(huì )默認使用當前目錄的webpack.config.js作為配置文件。如果要指定另外的配置文件,可以執行:

webpack —config webpack.custom.config.js

盡管Webpack可以通過(guò)命令行來(lái)指定參數,但我們通常會(huì )將所有相關(guān)參數定義在配置文件中。一般我們會(huì )定義兩個(gè)配置文件,一個(gè)用于開(kāi)發(fā)時(shí),另外一個(gè)用于產(chǎn)品發(fā)布。生產(chǎn)環(huán)境下的打包文件不需要包含sourcemap等用于開(kāi)發(fā)時(shí)的代碼。配置文件通常放在項目根目錄之下,其本身也是一個(gè)標準的CommonJS模塊。

 

一個(gè)最簡(jiǎn)單的Webpack配置文件webpack.config.js如下所示:

module.exports = {

  entry:[

    './app/main.js'

  ],

  output: {

    path: __dirname + '/assets/',

    publicPath: "/assets/",

    filename: 'bundle.js'

  }

};

其中entry參數定義了打包后的入口文件,數組中的所有文件會(huì )按順序打包。每個(gè)文件進(jìn)行依賴(lài)的遞歸查找,直到所有相關(guān)模塊都被打包。output參數定義了輸出文件的位置,其中常用的參數包括:

 

· path: 打包文件存放的絕對路徑

· publicPath: 網(wǎng)站運行時(shí)的訪(fǎng)問(wèn)路徑

· filename: 打包后的文件名

 

現在來(lái)看如何打包一個(gè)React組件。假設有如下項目文件夾結構:

- react-sample

  + assets/

   - js/

     Hello.js

     entry.js

   index.html

   webpack.config.js

其中Hello.js定義了一個(gè)簡(jiǎn)單的React組件,使用ES6語(yǔ)法:

var React = require('react');

class Hello extends React.Component {

  render() {

    return (

      <h1>Hello {this.props.name}!h1>

    );

  }

}

module.exports= Hello;

entry.js是入口文件,將一個(gè)Hello組件輸出到界面:

var ReactDOM = require('react-dom');

var React = require('react');

var Hello = require('./Hello');

ReactDOM.render(<Hello name="Nate" />, document.body);

index.html的內容如下:

<html>

<head>head>

<body>

<script src="/assets/bundle.js">script>

body>

html>

在這里Hello.js和entry.js都是JSX組件語(yǔ)法,需要對它們進(jìn)行預處理,這就要引入webpack的JSX加載器。因此在配置文件中加入如下配置:

module: {

  loaders: [

    { test: /\.jsx?$/, loaders: ['jsx?harmony']}

  ]

}

加載器的概念稍后還會(huì )詳細介紹,這里只需要知道它能將JSX編譯成JavaScript并加載為Webpack模塊。這樣在當前目錄執行webpack命令之后,在assets目錄將生成bundle.js,打包了entry.js的內容。當瀏覽器打開(kāi)當前服務(wù)器上的index.html,將顯示“Hello Nate!”。這是一個(gè)非常簡(jiǎn)單的例子,演示了如何使用Webpack來(lái)進(jìn)行簡(jiǎn)單的React組件打包。

 

加載AMD或CommonJS模塊
 

 

在實(shí)際項目中,代碼以模塊進(jìn)行組織,AMD是在CommonJS的基礎上考慮了瀏覽器的異步加載特性而產(chǎn)生的,可以讓模塊異步加載并保證執行順序。而CommonJS的require函數則是同步加載。在Webpack中更加推薦CommonJS方式去加載模塊,這種方式語(yǔ)法更加簡(jiǎn)潔直觀(guān)。即使在開(kāi)發(fā)時(shí),我們也是加載Webpack打包后的文件,通過(guò)sourcemap去進(jìn)行調試。

 

除了項目本身的模塊,我們也需要依賴(lài)第三方的模塊,現在比較常用的第三方模塊基本都通過(guò)npm進(jìn)行發(fā)布,使用它們已經(jīng)無(wú)需單獨下載管理,需要時(shí)執行npm install即可。例如,我們需要依賴(lài)jQuery,只需執行:

npm install jquery —save-dev

更多情況下我們是在項目的package.json中進(jìn)行依賴(lài)管理,然后通過(guò)直接執行npm install來(lái)安裝所有依賴(lài)。這樣在項目的代碼倉庫中并不需要存儲實(shí)際的第三方依賴(lài)庫的代碼。

 

安裝之后,在需要使用jquery的模塊中需要在頭部進(jìn)行引入:

var $ = require('jquery');

$('body').html('Hello Webpack!');

 

可以看到,這種以CommonJS的同步形式去引入其它模塊的方式代碼更加簡(jiǎn)潔。瀏覽器并不會(huì )實(shí)際的去同步加載這個(gè)模塊,require的處理是由Webpack進(jìn)行解析和打包的,瀏覽器只需要執行打包后的代碼。Webpack自身已經(jīng)可以完全處理JavaScript模塊的加載,但是對于React中的JSX語(yǔ)法,這就需要使用Webpack的擴展加載器來(lái)處理了。

 

 

Webpack開(kāi)發(fā)服務(wù)器
 

 

除了提供模塊打包功能,Webpack還提供了一個(gè)基于Node.js Express框架的開(kāi)發(fā)服務(wù)器,它是一個(gè)靜態(tài)資源Web服務(wù)器,對于簡(jiǎn)單靜態(tài)頁(yè)面或者僅依賴(lài)于獨立服務(wù)的前端頁(yè)面,都可以直接使用這個(gè)開(kāi)發(fā)服務(wù)器進(jìn)行開(kāi)發(fā)。在開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)服務(wù)器會(huì )監聽(tīng)每一個(gè)文件的變化,進(jìn)行實(shí)時(shí)打包,并且可以推送通知前端頁(yè)面代碼發(fā)生了變化,從而可以實(shí)現頁(yè)面的自動(dòng)刷新。

 

Webpack開(kāi)發(fā)服務(wù)器需要單獨安裝,同樣是通過(guò)npm進(jìn)行:

npm install -g webpack-dev-server

之后便可以運行webpack-dev-server命令來(lái)啟動(dòng)開(kāi)發(fā)服務(wù)器,然后通過(guò)localhost:8080/webpack-dev-server/訪(fǎng)問(wèn)到頁(yè)面了。默認情況下服務(wù)器以當前目錄作為服務(wù)器目錄。在React開(kāi)發(fā)中,我們通常會(huì )結合react-hot-loader來(lái)使用開(kāi)發(fā)服務(wù)器,因此這里不做太多介紹,只需要知道有這樣一個(gè)開(kāi)發(fā)服務(wù)器可以用于開(kāi)發(fā)時(shí)的內容實(shí)時(shí)打包和推送。

 

Webpack模塊加載器(Loaders)
 

 

Webpack將所有靜態(tài)資源都認為是模塊,比如JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,圖片等等,從而可以對其進(jìn)行統一管理。為此Webpack引入了加載器的概念,除了純JavaScript之外,每一種資源都可以通過(guò)對應的加載器處理成模塊。和大多數包管理器不一樣的是,Webpack的加載器之間可以進(jìn)行串聯(lián),一個(gè)加載器的輸出可以成為另一個(gè)加載器的輸入。比如LESS文件先通過(guò)less-load處理成css,然后再通過(guò)css-loader加載成css模塊,最后由style-loader加載器對其做最后的處理,從而運行時(shí)可以通過(guò)style標簽將其應用到最終的瀏覽器環(huán)境。

 

對于React的JSX也是如此,它通過(guò)jsx-loader來(lái)載入。jsx-loader專(zhuān)門(mén)用于載入React的JSX文件,Webpack的加載器支持參數,jsx-loader就可以添加?harmony參數使其支持ES6語(yǔ)法。為了讓W(xué)ebpack識別什么樣的資源應該用什么加載器去載入,需要在配置文件進(jìn)行配置:通過(guò)正則表達式對文件名進(jìn)行匹配。例如:

 

module: {

    preLoaders: [{

      test: /\.js$/,

      exclude: /node_modules/,

      loader: 'jsxhint'

    }],

    loaders: [{

      test: /\.js$/,

      exclude: /node_modules/,

      loader: 'react-hot!jsx-loader?harmony'

    }, {

      test: /\.less/,

      loader: 'style-loader!css-loader!less-loader'

    }, {

      test: /\.(css)$/,

      loader: 'style-loader!css-loader'

    }, {

      test: /\.(png|jpg)$/,

      loader: 'url-loader?limit=8192'

    }]

  }

 

可以看到,該使用什么加載器完全取決于這里的配置,即使對于JSX文件,我們也可以用js作為后綴,從而所有的JavaScript都可以通過(guò)jsx-loader載入,因為jsx本身就是完全兼容JavaScript的,所以即使沒(méi)有JSX語(yǔ)法,普通JavaScript模塊也可以使用jsx-loader來(lái)載入。

 

加載器之間的級聯(lián)是通過(guò)感嘆號來(lái)連接,例如對于LESS資源,寫(xiě)法為style-loader!css-loader!less-loader。對于小型的圖片資源,也可以將其進(jìn)行統一打包,由url-loader實(shí)現,代碼中url-loader?limit=8192含義就是對于所有小于8192字節的圖片資源也進(jìn)行打包。這在一定程度上可以替代Css Sprites方案,用于減少對于小圖片資源的HTTP請求數量。

 

除了已有加載器,也可以自己實(shí)現自己的加載器,從而可以讓W(xué)ebpack統一管理項目特定的靜態(tài)資源。

 

React開(kāi)發(fā)神器:react-hot-loader
 

 

Webpack本身具有運行時(shí)模塊替換功能,稱(chēng)之為Hot Module Replacement (HMR)。當某個(gè)模塊代碼發(fā)生變化時(shí),Webpack實(shí)時(shí)打包將其推送到頁(yè)面并進(jìn)行替換,從而無(wú)需刷新頁(yè)面就實(shí)現代碼替換。這個(gè)過(guò)程相對比較復雜,需要進(jìn)行多方面考慮和配置。而現在針對React出現了一個(gè)第三方react-hot-loader加載器,使用這個(gè)加載器就可以輕松實(shí)現React組件的熱替換,非常方便。其實(shí)正是因為React的每一次更新都是全局刷新的虛擬DOM機制,讓React組件的熱替換可以成為通用的加載器,從而極大提高開(kāi)發(fā)效率。

 

要使用react-hot-loader,首先通過(guò)npm進(jìn)行安裝:

npm install —save-dev react-hot-loader

之后,Webpack開(kāi)發(fā)服務(wù)器需要開(kāi)啟HMR參數hot,為了方便,我們創(chuàng )建一個(gè)名為server.js的文件用以啟動(dòng)Webpack開(kāi)發(fā)服務(wù)器:

 

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,

  noInfo: false,

  historyApiFallback: true

}).listen(3000, '127.0.0.1', function (err, result) {

  if (err) {

    console.log(err);

  }

  console.log('Listening at localhost:3000');

});

為了熱加載React組件,我們需要在前端頁(yè)面中加入相應的代碼,用以接收Webpack推送過(guò)來(lái)的代碼模塊,進(jìn)而可以通知所有相關(guān)React組件進(jìn)行重新Render。加入這個(gè)代碼很簡(jiǎn)單:

entry: [

  'webpack-dev-server/client?http://127.0.0.1:3000', // WebpackDevServer host and port

  'webpack/hot/only-dev-server',

  './scripts/entry' // Your app?s entry point

]

需要注意的是,這里的client?http://127.0.0.1:3000需要和在server.js中啟動(dòng)Webpack開(kāi)發(fā)服務(wù)器的地址匹配。這樣,打包生成的文件就知道該從哪里去獲取動(dòng)態(tài)的代碼更新。下一步,我們需要讓W(xué)ebpack用react-hot-loader去加載React組件,如前面所介紹,這通過(guò)加載器配置完成:

loaders: [{

    test: /\.js$/,

    exclude: /node_modules/,

    loader: 'react-hot!jsx-loader?harmony'

  },

  …

]

做完這些配置之后,使用Node.js運行server.js:

node server.js

即可啟動(dòng)開(kāi)發(fā)服務(wù)器并實(shí)現React組件的熱加載。為了方便,我們也可以在package.json中加入一節配置:

"scripts": {

  "start": "node ./js/server.js"

}

從而通過(guò)npm start命令即可啟動(dòng)開(kāi)發(fā)服務(wù)器。

這樣,React的熱加載開(kāi)發(fā)環(huán)境即配置完成,任何修改只要以保存,就會(huì )在頁(yè)面上立刻體現出來(lái)。無(wú)論是對樣式修改,還是對界面渲染的修改,甚至事件綁定處理函數的修改,都可以立刻生效,不得不說(shuō)是提高開(kāi)發(fā)效率的神器。

 

將Webpack開(kāi)發(fā)服務(wù)器集成到已有服務(wù)器
 

 

盡管Webpack開(kāi)發(fā)服務(wù)器可以直接用于開(kāi)發(fā),但實(shí)際項目中我們基本都使用自己的Web服務(wù)器。這就需要我們能將Webpack的服務(wù)集成到已有服務(wù)器,來(lái)使用Webpack提供的模塊打包和加載功能。要實(shí)現這一點(diǎn)其實(shí)非常容易,只需要在載入打包文件時(shí)指定完整的URL地址,例如:

 

<script src="http://127.0.0.1:3000/assets/bundle.js">script>

 

這就告訴當前頁(yè)面應該去另外一個(gè)服務(wù)器獲得腳本資源文件,在之前我們已經(jīng)在配置文件中指定了開(kāi)發(fā)服務(wù)器的地址,因此打包后的文件也知道應該通過(guò)哪個(gè)地址去建立Socket IO來(lái)動(dòng)態(tài)加載模塊。整個(gè)資源架構如下圖所示: 

 

打包成多個(gè)資源文件
 

 

將項目中的模塊打包成多個(gè)資源文件有兩個(gè)目的:

 

1. 將多個(gè)頁(yè)面的公用模塊獨立打包,從而可以利用瀏覽器緩存機制來(lái)提高頁(yè)面加載效率;

2. 減少頁(yè)面初次加載時(shí)間,只有當某功能被用到時(shí),才去動(dòng)態(tài)的加載。

Webpack提供了非常強大的功能讓你能夠靈活的對打包方案進(jìn)行配置。首先來(lái)看如何創(chuàng )建多個(gè)入口文件:

{

  entry: { a: "./a", b: "./b" },

  output: { filename: "[name].js" },

  plugins: [ new webpack.CommonsChunkPlugin("init.js") ]

}

可以看到,配置文件中定義了兩個(gè)打包資源“a”和“b”,在輸出文件中使用方括號來(lái)獲得輸出文件名。而在插件設置中使用了CommonsChunkPlugin,Webpack中將打包后的文件都稱(chēng)之為“Chunk”。這個(gè)插件可以將多個(gè)打包后的資源中的公共部分打包成單獨的文件,這里指定公共文件輸出為“init.js”。這樣我們就獲得了三個(gè)打包后的文件,在html頁(yè)面中可以這樣引用:

<script src="init.js">script>

<script src="a.js">script>

<script src="b.js">script>

除了在配置文件中對打包文件進(jìn)行配置,還可以在代碼中進(jìn)行定義:require.ensure,例如:

require.ensure(["module-a", "module-b"], function(require) {

  var a = require("module-a");

  // ...

});

Webpack在編譯時(shí)會(huì )掃描到這樣的代碼,并對依賴(lài)模塊進(jìn)行自動(dòng)打包,運行過(guò)程中執行到這段代碼時(shí)會(huì )自動(dòng)找到打包后的文件進(jìn)行按需加載。

 

來(lái)小結一下
 

 

結合React介紹了Webpack的基本功能和用法,希望能讓大家對這個(gè)新興而強大的模塊管理工具有一個(gè)總體的認識,并能將其應用在實(shí)際的項目開(kāi)發(fā)中。

 

分享到:
地址:福建省福州市銅盤(pán)路軟件大道89號軟件園A區26號樓 電話(huà):0591-83519233 傳真:0591-87882335 E-mail:doone@doone.com.cn
版權所有 新東網(wǎng)科技有限公司 閩ICP備07052074號-1 閩公網(wǎng)安備 35010202001006號
亚洲国产中文精品无码久久_亚洲妇女自偷自偷图片_亚洲第一国产毛片久久久_亚洲国产成人片在线观看无码_日本少妇被黑人粗大的猛激进