Webpack原理及常見問題總結
阿新 • • 發佈:2019-01-05
webpack是什麼
定義
webpack是一個JavaScript應用程式的靜態模組打包器。它會分析你的專案結構,找到JavaScript模組以及其它的一些瀏覽器不能直接執行的拓展語言(less,ES6等),將其轉換和打包為合適的格式供瀏覽器使用。
工作原理
把專案當作一個整體,通過一個給定的主檔案(如:main.js),Webpack將從這個檔案開始找到你的專案所有依賴檔案,使用loader處理它們。最後打包為一個(或多個)瀏覽器可識別的JS檔案。
為什麼要使用webpack
一、loader的轉換,預處理
- webpack通過使用loader將瀏覽器不能直接執行的拓展語言轉換為可識別的,例如:使用babel-loader轉換ES6語法,使用less-loader轉換less語法等。
二、模組化,按需載入
- 對於較大規模的Web 應用(特別是單頁應用),把所有程式碼合併到單個檔案是比較低效的做法,單個檔案體積過大會導致應用初始載入緩慢,尤其如果其中很多邏輯只在特定情況下需要執行,每次都完整地載入所有模組就變得很浪費。
- webpack 提供了程式碼拆分的方案,可以將應用程式碼拆分為多個塊(chunk),每個塊包含一個或多個模組,塊可以按需被非同步載入。
三、提高載入速度
將多個資源打包成一個檔案,可以合併程式碼,減少HTTP請求,再通過壓縮減少檔案體積,從而提高載入速度:
- 對於單頁應用程式中用到很多素材,如果每一個素材都通過在HTML中以src屬性或者link來引入,那麼請求一個頁面的時候,可能瀏覽器就要發起十多次請求。
- 往往請求的這些資源都是一些指令碼程式碼或者很小的圖片,這些資源本身才幾k,下載連1秒都不需要,但是由於HTTP是應用層協議,它的下層是TCP這個運輸層協議,TCP的握手和揮手過程消耗的時間可能比下載資源本身還要長,所以需要把這些小檔案全部打包成一個檔案,這樣只要一次TCP握手和揮手的過程,就把多個資源給下載下來了。
- 並且多個資源由於都是共享一個HTTP請求,所以head等部分也是共享的,相當於形成了規模效應,讓網頁展現更快,使用者體驗更好。
四、擴充套件性強,外掛機制完善
熱載入的使用方便搭建本地測試環境
在傳統的前端開發中,每次修改完程式碼都需要重新整理頁面才能讓改動生效,並驗證改動是否正確。雖然像LiveReload 這樣的功能可以幫助我們自動重新整理頁面,但當專案變大時,重新整理頁面往往要耗時好幾秒,只有等待頁面重新整理完成才能驗證改動。而且有些功能需要經過特定的操作、應用處於特定狀態時才能驗證,重新整理完頁面後還需要手動操作並恢復狀態,較為煩瑣。針對這一問題,webpack 提供了模組熱替換
的能力,它使得在修改完某一模組後無須重新整理頁面,即可動態將受影響的模組替換為新的模組,在後續的執行中使用新的模組邏輯。
– 摘自網際網路
核心
一、入口
- 定義:指示webpack應使用哪個模組,來作為構建內部依賴的主檔案。即通過入口檔案,找到引入的依賴檔案,處理這些檔案後,輸出到bunldes檔案中
module.exports = {
entry: './test/main.js'
}
二、輸出
- 定義:告訴webpack在哪裡輸出所建立的bundles,以及如何命名(一般習慣用build.js)
三、loader
- 定義:用來處理非JS檔案。將所有型別的檔案轉換為webpack能夠處理的有效模組。
- 引數:
test - 用於標識出應該被對應的 loader 進行轉換的某個或某些檔案
use - 表示進行轉換時,應該使用哪個 loader
四、外掛
- 定義:外掛的範圍包括,從打包優化和壓縮,一直到重新定義環境中的變數
Webpack常見問題彙總
1.dependencies與devDependencies之間的區別(即–save-dev 和 –save的區別)
- 兩者都是pakeage.json檔案中的物件。通過
npm install --save-dev
或npm install -D
安裝的外掛,被寫入到 devDependencies 物件裡面去;通過npm install --save
或npm install -S
安裝的外掛 ,則被寫入到 dependencies 物件裡面去。 - dependencies是釋出到線上需要打包或用到的檔案,即專案執行所依賴的模組,而devDependencies指本地開發所需要的模組,不需要被打包。
- pakeage.json檔案的配置只起提示作用,並不影響實際的安裝,npm安裝模組後自動記錄到pakeage.json中。使用
npm i
可以一鍵安裝配置好的內容。
2. loader的作用和寫法
- loader將瀏覽器不能識別的語言轉換成可識別的
- loader的使用方式有三種:
配置(推薦):在 webpack.config.js 檔案中指定 loader。
內聯:在每個 import 語句中顯式指定 loader。
CLI:在 shell 命令中指定它們。 - 語法格式見官網
示例一:
module.exports = {
module: {
rules: [
{test: /\.js$/, use: ['babel-loader'], exclude: /node_modules/},
]
}
};
//test:代表正則表示式
//use: 載入器
//exclude:用來排除一些不需要轉換的JS
示例二:
module.exports = {
module: {
rules: [
{test: /\.less$/, use: ['style-loader','css-loader?sourceMap','less-loader?sourceMap']}
]
}
};
//?sourceMap定義出錯位置
3.path和publicPath的區別
- path是JS檔案(如:main.js)打包後生成的檔案(如:build.js)輸出目錄的絕對路徑
- publicPath是各種靜態資源的引用路徑,為虛擬路徑
4.devServer.proxy
如果有單獨的後端開發伺服器 API,並且希望在同域名下發送 API 請求 ,使用devServer.proxy代理一些 URL
devServer: { //解決跨域,在同域名下發送 API 請求
port: 80,
disableHostCheck: true,
proxy: {
'/daikou/a': {
target: 'xxx', //目標域名
changeOrigin: true //本地虛擬一個服務端接收請求併發送該請求
}
}
}