webpack理解

什麼是webpack

webpack是一個打包模塊化javascript的工具,在webpack裏一切文件皆模塊,經過loader轉換文件,經過plugin注入鉤子,最後輸出由多個模塊組合成的文件,webpack專一構建模塊化項目。
WebPack能夠看作是模塊打包機:它作的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包爲合適的格式以供瀏覽器使用。
官網的圖片形象的展現了webpack的定義
javascript

幾個常見的loader

  • file-loader:把文件輸出到一個文件夾中,在代碼中經過相對 URL 去引用輸出的文件
  • url-loader:和 file-loader 相似,可是能在文件很小的狀況下以 base64 的方式把文件內容注入到代碼中去
  • source-map-loader:加載額外的 Source Map 文件,以方便斷點調試
  • image-loader:加載而且壓縮圖片文件
  • babel-loader:把 ES6 轉換成 ES5
  • css-loader:加載 CSS,支持模塊化、壓縮、文件導入等特性
  • style-loader:把 CSS 代碼注入到 JavaScript 中,經過 DOM 操做去加載 CSS。
  • eslint-loader:經過 ESLint 檢查 JavaScript 代碼

幾個常見的plugin

  • define-plugin:定義環境變量
  • terser-webpack-plugin:經過TerserPlugin壓縮ES6代碼
  • html-webpack-plugin 爲html文件中引入的外部資源,能夠生成建立html入口文件
  • mini-css-extract-plugin:分離css文件
  • clean-webpack-plugin:刪除打包文件
  • happypack:實現多線程加速編譯

webpack與grunt、gulp的不一樣?

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有哪些優勢

  • 專一於處理模塊化的項目,能作到開箱即用,一步到位
  • 可經過plugin擴展,完整好用又不失靈活
  • 使用場景不侷限於web開發
  • 社區龐大活躍,常常引入緊跟時代發展的新特性,能爲大多數場景找到已有的開源擴展
  • 良好的開發體驗

webpack的缺點

webpack的缺點是隻能用於採用模塊化開發的項目web

分別介紹bundle,chunk,module是什麼

bundle:是由webpack打包出來的文件,
chunk:代碼塊,一個chunk由多個模塊組合而成,用於代碼的合併和分割。
module:是開發中的單個模塊,在webpack的世界,一切皆模塊,一個模塊對應一個文件,webpack會從配置的entry中遞歸開始找出全部依賴的模塊。

分別介紹什麼是loader?什麼是plugin?

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

Tree-shaking能夠用來剔除javascript中不用的死代碼,它依賴靜態的es6模塊化語法,例如經過哦import 和export 導入導出,Tree-shaking最早在rollup中出現,webpack在2.0中將其引入,css中使用Tree-shaking須要引入Purify-CSS

經過webpack處理長緩存

瀏覽器在用戶訪問頁面的時候,爲了加快加載速度,會對用戶訪問的靜態資源進行存儲,可是每一次代碼升級或是更新,都須要瀏覽器去下載新的代碼,最方便和簡單的更新方式就是引入新的文件名稱。在webpack中能夠在output縱輸出的文件指定chunkhash,而且分離常常更新的代碼和框架代碼。經過NameModulesPlugin或是HashedModuleIdsPlugin使再次打包文件名不變。

如何提升webpack的構建速度

  1. 經過externals配置來提取經常使用庫
  2. 利用DllPlugin和DllReferencePlugin預編譯資源模塊 經過DllPlugin來對那些咱們引用可是絕對不會修改的npm包來進行預編譯,再經過DllReferencePlugin將預編譯的模塊加載進來。
  3. 使用Happypack 實現多線程加速編譯

要注意的第一點是,它對file-loader和url-loader支持很差,因此這兩個loader就不須要換成happypack了,其餘loader能夠相似地換一下

  1. 使用Tree-shaking和Scope Hoisting來剔除多餘代碼
  2. 使用fast-sass-loader代替sass-loader
  3. babel-loader開啓緩存

babel-loader在執行的時候,可能會產生一些運行期間重複的公共文件,形成代碼體積大冗餘,同時也會減慢編譯效率
能夠加上cacheDirectory參數或使用 transform-runtime 插件試試

// webpack.config.js
use: [{
    loader: 'babel-loader',
    options: {
        cacheDirectory: true
}]
// .bablerc
{
    "presets": [
        "env",
        "react"
    ],
    "plugins": ["transform-runtime"]
}
複製代碼
  1. 不須要打包編譯的插件庫換成全局"script"標籤引入的方式

好比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'
        }),
複製代碼
  1. 優化構建時的搜索路徑

在webpack打包時,會有各類各樣的路徑要去查詢搜索,咱們能夠加上一些配置,讓它搜索地更快好比說,方便改爲絕對路徑的模塊路徑就改一下,以純模塊名來引入的能夠加上一些目錄路徑還能夠善於用下resolve alias別名 這個字段來配置還有exclude等的配置,避免多餘查找的文件,好比使用babel別忘了剔除不須要遍歷的

相關文章
相關標籤/搜索