webpack是一個模塊打包工具,可使用它管理項目中的模塊依賴,並編譯輸出模塊所需的靜態文件。它能夠很好地管理、打包開發中所用到的HTML,CSS,JavaScript和靜態文件(圖片,字體)等,讓開發更高效。對於不一樣類型的依賴,webpack有對應的模塊加載器,並且會分析模塊間的依賴關係,最後合併生成優化的靜態資源。css
一、代碼轉換:TypeScript 編譯成 JavaScript、SCSS 編譯成 CSS 等等html
二、文件優化:壓縮 JavaScript、CSS、HTML 代碼,壓縮合並圖片等前端
三、代碼分割:提取多個頁面的公共代碼、提取首屏不須要執行部分的代碼讓其異步加載vue
四、模塊合併:在採用模塊化的項目有不少模塊和文件,須要構建功能把模塊分類合併成一個文件node
五、自動刷新:監聽本地源代碼的變化,自動構建,刷新瀏覽器webpack
六、代碼校驗:在代碼被提交到倉庫前須要檢測代碼是否符合規範,以及單元測試是否經過web
七、自動發佈:更新完代碼後,自動構建出線上發佈代碼並傳輸給發佈系統。vue-cli
一、把一切都視爲模塊:不論是 CSS、JS、Image 仍是 HTML 均可以互相引用,經過定義 entry.js,對全部依賴的文件進行跟蹤,將各個模塊經過 loader 和 plugins 處理,而後打包在一塊兒。shell
二、按需加載:打包過程當中 Webpack 經過 Code Splitting 功能將文件分爲多個 chunks,還能夠將重複的部分單獨提取出來做爲 commonChunk,從而實現按需加載。把全部依賴打包成一個 bundle.js 文件,經過代碼分割成單元片斷並按需加載npm
三、webpack.config.js的配置
// webpack的配置文件 因爲webpack是基於Node構建的,webpack配置文件中全部的合法node語法均可以用
var path = require('path')
// 若是要配置插件,須要在導出的對象上添加plugins節點
var htmlWebpackPlugin = require('html-webpack-plugin')
// 配置導出對象
module.exports = {
// 入口文件
entry: path.join(__dirname, './src/main.js'),
/* // 入口文件的配置項,配置兩個 entry:{ entry:'./src/entry.js', //這裏咱們又引入了一個入口文件 entry2:'./src/entry2.js' }, */
// 指定輸出選項
output: {
path: path.join(__dirname, './dist'), // 指定輸出路徑
/* path:path.resolve(__dirname,'dist'), // 輸出的路徑,用了Node語法 */
filename: 'bundle.js' // 指定輸出文件的名字
},
// 插件對象節點
plugins: [
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'), // 指定模板文件路徑
filename: 'index.html' // 設置生成內存頁面的的名字
}),
],
// 配置全部第三方loader(載入程序)模塊 例如解讀CSS,圖片如何轉換,壓縮
module: {
// 第三方模塊的匹配規則
rules: [
// 這裏的test於正則的test同樣
// 處理css文件的loader
{test: /\.(css|scss)$/, use: ['style-loader', 'css-loader', 'sass-loader']},
// 處理圖片路徑的loader 這裏的limit爲圖片的大小(單位是字節)
{test: /\.(jpg|png|gif|jpeg|bmp)$/, use: 'url-loader?limit=349950&name=[hash:8]-[name].[ext]'},
// 處理字體圖標的loader
{test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader'},
// 把Es6的高級語法轉換成瀏覽器能夠識別的低級語言
{test: /\.js$/, use: 'babel-loader', exclude: /node_modules/},
// 處理vue文件的loader
{test: /\.vue$/, use: 'vue-loader'}
]
},
// 配置導入包的路徑
/* resolve : { alias : { // alias別名 修改vue導入的路徑 "vue$" : "vue/dist/vue.js" } }*/
}
複製代碼
(1) webpack 是以 commonJS 的形式來書寫腳本的,但對 AMD/CMD 的支持也很全面,方便舊項目進行代碼遷移。
(2)能被模塊化的不只僅是 JS 了。
(3) 開發便捷,能替代部分 grunt/gulp 的工做,好比打包、壓縮混淆、圖片轉base64等。
(4)擴展性強,插件機制完善
Entry:入口,Webpack 執行構建的第一步將從 Entry 開始,可抽象成輸入。告訴webpack要使用哪一個模塊做爲構建項目的起點,默認爲./src/index.js
output :出口,告訴webpack在哪裏輸出它打包好的代碼以及如何命名,默認爲./dist
Module:模塊,在 Webpack 裏一切皆模塊,一個模塊對應着一個文件。Webpack 會從配置的 Entry 開始遞歸找出全部依賴的模塊。
Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用於代碼合併與分割。
Loader:模塊轉換器,用於把模塊原內容按照需求轉換成新內容。
Plugin:擴展插件,在 Webpack 構建流程中的特定時機會廣播出對應的事件,插件能夠監聽這些事件的發生,在特定時機作對應的事情。
loader用於加載某些資源文件。由於webpack自己只能打包common.js規範的js文件,對於其餘資源如css,img等,是沒有辦法加載的,這時就須要對應的loader將資源轉化,從而進行加載。使wenbpack擁有加載和解析非js文件的能力 常見的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用於擴展webpack的功能。不一樣於loader,plugin的功能更加豐富,好比壓縮打包,優化,不僅侷限於資源的加載。
一、UglifyJsPlugin: 壓縮代碼 二、HotModuleReplacementPlugin 自動刷新 三、HtmlWebpackPlugin 依據一個簡單的index.html模版,生成一個自動引用你打包後的js文件的新index.html 四、ExtractTextWebpackPlugin 它會將入口中引用css文件,都打包都獨立的css文件中,而不是內嵌在js打包文件中 五、Tree-shaking 指在打包中去除那些引入了,可是在代碼中沒有被用到的那些死代碼 六、在webpack中Tree-shaking是經過uglifySPlugin來Tree-shaking,Css須要使用Purify-CSS
常見的plugin以及做用
define-plugin:定義環境變量 commons-chunk-plugin:提取公共代碼 uglifyjs-webpack-plugin:經過UglifyES壓縮ES6代碼
bundle:是由webpack打包出來的文件
chunk:是指webpack在進行模塊依賴分析的時候,代碼分割出來的代碼塊
module:是開發中的單個模塊
webpack是一個模塊打包器,強調的是一個前端模塊化方案,更側重模塊打包,咱們能夠把開發中的全部資源都當作是模塊,經過loader和plugin對資源進行處理。
gulp是一個前端自動化構建工具,強調的是前端開發的工做流程,能夠經過配置一系列的task,第一task處理的事情(如代碼壓縮,合併,編譯以及瀏覽器實時更新等)。而後定義這些執行順序,來讓glup執行這些task,從而構建項目的整個開發流程。自動化構建工具並不能把全部的模塊打包到一塊兒,也不能構建不一樣模塊之間的依賴關係。
webpack-cli、vue-cli
模塊熱更新是webpack的一個功能,它可使得代碼修改以後,不用刷新瀏覽器就能夠更新。在應用過程當中替換添加刪出模塊,無需從新加載整個頁面,是高級版的自動刷新瀏覽器。 優勢:只更新變動內容,以節省寶貴的開發時間。調整樣式更加快速,幾乎至關於在瀏覽器中更改樣式
webpack-dev-server使用內存來存儲webpack開發環境下的打包文件,而且可使用模塊熱更新,比傳統的http服務對開發更加有效。
瀏覽器在用戶訪問頁面的時候,爲了加快加載速度,會對用戶訪問的靜態資源進行存儲,可是每一次代碼升級或者更新,都須要瀏覽器去下載新的代碼,最方便和最簡單的更新方式就是引入新的文件名稱。
在webpack中,能夠在output給出輸出的文件制定chunkhash,而且分離常常更新的代碼和框架代碼,經過NameModulesPlugin或者HashedModulesPlugin使再次打包文件名不變。
指打包中去除那些引入了但在代碼中沒用到的死代碼。在wepack中js treeshaking經過UglifyJsPlugin來進行,css中經過purify-CSS來進行.
初始化參數,從配置文件和shell語句中讀取與合併參數,得出最終的參數
開始編譯:用上一步獲得的參數初始化 Compiler 對象,加載全部配置的插件,執行對象的 run 方法開始執行編譯;
肯定入口,經過entry找到入口文件
編譯模塊:從入口文件出發,調用全部配置的 Loader 對模塊進行翻譯(按照loader的規則進行轉換),再找出該模塊依賴的模塊,再遞歸本步驟直到全部入口依賴的文件都通過了本步驟的處理;
完成模塊編譯,獲得每一個模塊被翻譯以後的最終的內容和依賴關係
輸出資源,根據入口和模塊之間的依賴關係,組裝成一個個包含多個模塊的chunk,在把每一個chunk轉換成一個單獨的文件加載到輸出列表,這步是能夠修改輸出內容的最後機會
輸出完成:在肯定好輸出內容後,根據配置肯定輸出的路徑和文件名,把文件內容寫入到文件系統。
在整個流程中webpack會在恰當的時機執行plugin裏定義的邏輯
多入口狀況下,使用CommonsChunkPlugin來提取公共代碼
經過externals配置來提取經常使用庫
利用DllPlugin和DllReferencePlugin預編譯資源模塊 經過DllPlugin來對那些咱們引用可是絕對不會修改的npm包來進行預編譯,再經過DllReferencePlugin將預編譯的模塊加載進來。
使用Happypack 實現多線程加速編譯
使用webpack-uglify-parallel來提高uglifyPlugin的壓縮速度。 原理上webpack-uglify-parallel採用了多核並行壓縮來提高壓縮速度
使用Tree-shaking和Scope Hoisting來剔除多餘代碼
壓縮代碼。uglifyJsPlugin 壓縮js代碼, mini-css-extract-plugin 壓縮css代碼
刪除死代碼(tree shaking),css須要使用Purify-CSS
提取公共代碼。webpack4移除了CommonsChunkPlugin (提取公共代碼),用optimization.splitChunks和optimization.runtimeChunk來代替