webpack在PC專案中的應用

發表於2016-03-22

好東西,總是要使用的。

webpack是什麼工具

webpack is a module bundler

正如官網對webpack的描述,它是一種模組化載入器,當然也不僅僅限於此。某種程度上來說,可以代替某些gulp的功能,至少有些還是無法替代的。在webpack中所有的資源都會被視作模組來處理,為了應對這樣的情況,webpack有對應的loader機制來處理,另外shim,plugins,和其他構建工具,一樣一樣的,更多的細節,需要你在實際的應用中慢慢去體會了。

webpack的使用方法

安裝:npm install webpack –verbose –save-dev

webpack認為一個專案(或者一個頁面),總有一個入口檔案,就像C語言中總有一個main函式一樣。假設,我們建立兩個檔案./mian.js./query.js,並且將main.js做為我們專案的入口檔案。

query.js

main.js

建立一個webpack.config.js檔案

在你的終端上執行webpack即可。

webpack配置詳解

entry

entry屬性做為可配置的入口,比如上面所寫的./main.js。entry有三種寫法,每一個入口可以稱之為一個chunk。

  • 如果為字串,只會打包一個順序依賴的模組,輸出則根據output配置而定。
  • 如果為陣列,只會打包一個順序依賴的模組,合併到最後一個模組時匯出,輸出則根據output配置而定。
  • 如果為物件,則會根據入口打包多個順序依賴的模組,key名會根據在output的配置輸出。

output

輸出規則,在此物件中設定。

  • path 設定輸出的檔案路徑
  • filename 設定輸出檔名,filename可以有多種配置,比如main.js[id].js[name].js[hash].js
  • publicPath 設定資源的訪問路徑
  • library 設定模組匯出的類名
  • libraryTarget:’umd’ 設定模組相容模式
  • umdNamedDefine:true 同上

devtool

將devtool設定為source-map,在開發除錯階段非常有用,它的模式非常多,我有搞的比較暈。

loader

loader機制應該是webpack中非常重要的部分了,它是一系列資源的最終執行者。一般情況下,你可以訪問:webpack loader來訪問可用loader列表。

比如現在我想將.html型別的檔案,當做一個模組來載入。

 

每一個loader都可以用一個物件來描述,test是你的匹配規則,loader是你要載入的loader,exclude是你在執行規則是想忽略的目錄。

plugins

webpack的外掛機制也非常的重要,其內建了多種外掛,比如混淆,壓縮等等。外掛列表可以訪問:list of plugins

正常情況下可以使用官方自帶的外掛:

當然,我們也可以引入第三方外掛,使用你的npm install吧。

resolve

此配置可以對一些常用模組設定別名,比如a.js放置在./src/module/address/中,每次載入模組需要var a = require(‘./src/module/address/a’);名字非長,如果設定別名了,只需要var a = require(‘a’);

還可以設定訪問路徑,以及模組載入字尾。

externals

此項配置可以將某些庫設定為外部引用,內部不會打包合併進去。

在我們PC專案中的應用

我們公司內部的專案,也開始應用npm scripts來做執行鉤子,webpack來做構建,首先設計三個命令:

  • npm run start
  • npm run dev
  • npm run build

配置npm run start

本地伺服器的啟動,我們沒有使用webpack官方提供的webpack-dev-server,而是採用了 browser-sync。

利用gulp寫了一個指令碼任務,在package.json檔案中設定:

瞭解我們專案的實際需求

我們的專案是一個多頁面專案,並不像單頁應用一樣(業務程式設計可以打包成一個),首先我們需要設計一個良好的目錄結構,如下:

  • web 目錄放置*.html頁面
  • style 目錄放置*.css檔案,另外在此目錄中放置了less原始檔
  • src 目錄放置了我們的所有*.js檔案
  • mock 內建的模擬資料,放置在此
  • img 圖片放置目錄
  • link npm下載不了的第三方庫放置在此
  • YYT_PC_Modules 內部編寫的模組,放置在此
  • YYT_PC_Component 內部編寫的元件,放置在此

編寫一個map.json檔案,用來維護多入口的關係。當然我們的webpack.dev.config.js檔案,放置在根目錄。最後的build階段應該輸出一個新的目錄dist這個目錄中放置的應該是所有build完成的資源,包括*.html檔案。

它應該才是我們最終的釋出目錄。

配置npm run dev

對於CSS我們的期望是一個新的link而不是style內嵌,所以還需要做一些額外的事情,先下載loader和外掛。

列表:

raw-loader主要用來解決模板載入的問題,模組當做一個變數直接載入到業務程式設計中。

配置我們的CSS:

ExtractTextPlugin的作用就是將CSS單獨輸出一個檔案,這個檔名依賴於entry寫的入口檔名。

配置我們的多頁面JS:

提取JS檔案中的公共部分:

webpack自帶的一個外掛,可以提取合併打包時的公共部分,只要在頁面載入時,放置在合併打包後檔案的前面。

完整的dev構建指令碼

問題

問題一:在windows機器上如果你要設定環境變數(也許是我沒有找到問題的所在,但是提出來,主要是Mac用習慣了。)

在webpack.dev.config.js檔案中不能正確的獲取環境變數,所以重新寫了一個build檔案,webpack.build.config.js來做最後的構建。

問題二:構建之後的檔案hash化後如何更新HTML中的路徑

這個問題,最後沒有采用webpack來做,而是使用gulp來解決的。(不知道大家有沒有什麼好的方式)

感謝@sharkrice告知 HtmlWebpackPlugin 外掛

問題三:構建系統的shim

我們的PC專案(相容IE8+),依然使用著以前的庫,jQuery.js,underscore.js,backbone.js,以及其他第三方不支援commonjs語法的外掛,有很多相容不是很好,最後還是寫了另外一個入口檔案(包裝),然後在webpack合併打包的檔案之前引入這些外掛,掛載在一個全域性的名稱空間下,利用新寫的一個包裝入口匯出模組。

問題四:CSS依賴重複

感謝@sharkrice 告知 嘗試webpack.optimize.DedupePlugin,問題解決。

相關文章