webpack是一個打包模塊化javascript的工具,在webpack裏一切文件皆模塊,經過loader轉換文件,經過plugin注入鉤子,最後輸出由多個模塊組合成的文件,webpack專一構建模塊化項目。
WebPack能夠看作是模塊打包機:它作的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包爲合適的格式以供瀏覽器使用。
官網的圖片形象的展現了webpack的定義
javascript
Webpack與Gulp、Grunt沒有什麼可比性,它能夠看做模塊打包機,經過分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其轉換和打包爲合適的格式供瀏覽器使用。Gulp/Grunt是一種可以優化前端的開發流程的工具,而WebPack是一種模塊化的解決方案,不過Webpack的優勢使得Webpack在不少場景下能夠替代Gulp/Grunt類的工具。css
他們的工做方式也有較大區別:html
Grunt和Gulp的工做方式是:在一個配置文件中,指明對某些文件進行相似編譯,組合,壓縮等任務的具體步驟,工具以後能夠自動替你完成這些任務。前端
Webpack的工做方式是:把你的項目當作一個總體,經過一個給定的主文件(如:index.js),Webpack將從這個文件開始找到你的項目的全部依賴文件,使用loaders處理它們,最後打包爲一個(或多個)瀏覽器可識別的JavaScript文件。
三者都是前端構建工具,grunt和gulp在早期比較流行,如今webpack相對來講比較主流,不過一些輕量化的任務仍是會用gulp來處理,好比單獨打包CSS文件等。java
grunt和gulp是基於任務和流(Task、Stream)的。相似jQuery,找到一個(或一類)文件,對其作一系列鏈式操做,更新流上的數據, 整條鏈式操做構成了一個任務,多個任務就構成了整個web的構建流程。react
webpack是基於入口的。webpack會自動地遞歸解析入口所須要加載的全部資源文件,而後用不一樣的Loader來處理不一樣的文件,用Plugin來擴展webpack功能。jquery
從構建思路來講
gulp和grunt須要開發者將整個前端構建過程拆分紅多個Task
,併合理控制全部Task
的調用關係
webpack須要開發者找到入口,並須要清楚對於不一樣的資源應該使用什麼Loader作何種解析和加工webpack
對於知識背景來講
gulp更像後端開發者的思路,須要對於整個流程瞭如指掌 webpack更傾向於前端開發者的思路es6
webpack的缺點是隻能用於採用模塊化開發的項目web
bundle:是由webpack打包出來的文件,
chunk:代碼塊,一個chunk由多個模塊組合而成,用於代碼的合併和分割。
module:是開發中的單個模塊,在webpack的世界,一切皆模塊,一個模塊對應一個文件,webpack會從配置的entry中遞歸開始找出全部依賴的模塊。
loader:模塊轉換器,用於將模塊的原內容按照須要轉成你想要的內容
plugin:在webpack構建流程中的特定時機注入擴展邏輯,來改變構建結果,是用來自定義webpack打包過程的方式,一個插件是含有apply方法的一個對象,經過這個方法能夠參與到整個webpack打包的各個流程(生命週期)。
模塊熱更新是webpack的一個功能,他可使得代碼修改事後不用刷新瀏覽器就能夠更新,是高級版的自動刷新瀏覽器。
devServer中經過hot屬性能夠空時模塊的熱替換
1,經過配置文件
const webpack = require('webpack');
const path = require('path');
let env = process.env.NODE_ENV == "development" ? "development" : "production";
const config = {
mode: env,
devServer: {
hot:true
}
}
plugins: [
new webpack.HotModuleReplacementPlugin(), //熱加載插件
],
module.exports = config;
複製代碼
2,經過命令行
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "NODE_ENV=development webpack-dev-server --config webpack.develop.config.js --hot",
},
複製代碼
Tree-shaking能夠用來剔除javascript中不用的死代碼,它依賴靜態的es6模塊化語法,例如經過哦import 和export 導入導出,Tree-shaking最早在rollup中出現,webpack在2.0中將其引入,css中使用Tree-shaking須要引入Purify-CSS
瀏覽器在用戶訪問頁面的時候,爲了加快加載速度,會對用戶訪問的靜態資源進行存儲,可是每一次代碼升級或是更新,都須要瀏覽器去下載新的代碼,最方便和簡單的更新方式就是引入新的文件名稱。在webpack中能夠在output縱輸出的文件指定chunkhash,而且分離常常更新的代碼和框架代碼。經過NameModulesPlugin或是HashedModuleIdsPlugin使再次打包文件名不變。
要注意的第一點是,它對file-loader和url-loader支持很差,因此這兩個loader就不須要換成happypack了,其餘loader能夠相似地換一下
babel-loader在執行的時候,可能會產生一些運行期間重複的公共文件,形成代碼體積大冗餘,同時也會減慢編譯效率
能夠加上cacheDirectory參數或使用 transform-runtime 插件試試
// webpack.config.js
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
}]
// .bablerc
{
"presets": [
"env",
"react"
],
"plugins": ["transform-runtime"]
}
複製代碼
好比jQuery插件,react, react-dom等,代碼量是不少的,打包起來可能會很耗時
能夠直接用標籤引入,而後在webpack配置裏使用 expose-loader 或 externals 或 ProvidePlugin 提供給模塊內部使用相應的變量
// @1
use: [{
loader: 'expose-loader',
options: '$'
}, {
loader: 'expose-loader',
options: 'jQuery'
}]
// @2
externals: {
jquery: 'jQuery'
},
// @3
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
複製代碼
在webpack打包時,會有各類各樣的路徑要去查詢搜索,咱們能夠加上一些配置,讓它搜索地更快好比說,方便改爲絕對路徑的模塊路徑就改一下,以純模塊名來引入的能夠加上一些目錄路徑還能夠善於用下resolve alias別名 這個字段來配置還有exclude等的配置,避免多餘查找的文件,好比使用babel別忘了剔除不須要遍歷的