關於webpack問答記錄...

Question

談談你對webpack的見解

webpack是一個模塊打包工具,可使用它管理項目中的模塊依賴,並編譯輸出模塊所需的靜態文件。它能夠很好地管理、打包開發中所用到的HTML,CSS,JavaScript和靜態文件(圖片,字體)等,讓開發更高效。對於不一樣類型的依賴,webpack有對應的模塊加載器,並且會分析模塊間的依賴關係,最後合併生成優化的靜態資源。css

webpack的基本功能和工做原理?

一、代碼轉換:TypeScript 編譯成 JavaScript、SCSS 編譯成 CSS 等等html

二、文件優化:壓縮 JavaScript、CSS、HTML 代碼,壓縮合並圖片等前端

三、代碼分割:提取多個頁面的公共代碼、提取首屏不須要執行部分的代碼讓其異步加載vue

四、模塊合併:在採用模塊化的項目有不少模塊和文件,須要構建功能把模塊分類合併成一個文件node

五、自動刷新:監聽本地源代碼的變化,自動構建,刷新瀏覽器webpack

六、代碼校驗:在代碼被提交到倉庫前須要檢測代碼是否符合規範,以及單元測試是否經過web

七、自動發佈:更新完代碼後,自動構建出線上發佈代碼並傳輸給發佈系統。vue-cli

webpack打包原理

一、把一切都視爲模塊:不論是 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"         }     }*/
}
複製代碼

webpack的優點

(1) webpack 是以 commonJS 的形式來書寫腳本的,但對 AMD/CMD 的支持也很全面,方便舊項目進行代碼遷移。

(2)能被模塊化的不只僅是 JS 了。

(3) 開發便捷,能替代部分 grunt/gulp 的工做,好比打包、壓縮混淆、圖片轉base64等。

(4)擴展性強,插件機制完善

webpack的核心概念

Entry:入口,Webpack 執行構建的第一步將從 Entry 開始,可抽象成輸入。告訴webpack要使用哪一個模塊做爲構建項目的起點,默認爲./src/index.js

output :出口,告訴webpack在哪裏輸出它打包好的代碼以及如何命名,默認爲./dist

Module:模塊,在 Webpack 裏一切皆模塊,一個模塊對應着一個文件。Webpack 會從配置的 Entry 開始遞歸找出全部依賴的模塊。

Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用於代碼合併與分割。

Loader:模塊轉換器,用於把模塊原內容按照需求轉換成新內容。

Plugin:擴展插件,在 Webpack 構建流程中的特定時機會廣播出對應的事件,插件能夠監聽這些事件的發生,在特定時機作對應的事情。

什麼是loader,什麼是plugin

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,什麼是chunk,什麼是module

bundle:是由webpack打包出來的文件

chunk:是指webpack在進行模塊依賴分析的時候,代碼分割出來的代碼塊

module:是開發中的單個模塊

webpack 和 gulp 的區別?

webpack是一個模塊打包器,強調的是一個前端模塊化方案,更側重模塊打包,咱們能夠把開發中的全部資源都當作是模塊,經過loader和plugin對資源進行處理。

gulp是一個前端自動化構建工具,強調的是前端開發的工做流程,能夠經過配置一系列的task,第一task處理的事情(如代碼壓縮,合併,編譯以及瀏覽器實時更新等)。而後定義這些執行順序,來讓glup執行這些task,從而構建項目的整個開發流程。自動化構建工具並不能把全部的模塊打包到一塊兒,也不能構建不一樣模塊之間的依賴關係。

如何自動生成webpack配置文件?

webpack-cli、vue-cli

什麼是模熱更新?有什麼優勢?

模塊熱更新是webpack的一個功能,它可使得代碼修改以後,不用刷新瀏覽器就能夠更新。在應用過程當中替換添加刪出模塊,無需從新加載整個頁面,是高級版的自動刷新瀏覽器。         優勢:只更新變動內容,以節省寶貴的開發時間。調整樣式更加快速,幾乎至關於在瀏覽器中更改樣式

webpack-dev-server 和 http服務器的區別

webpack-dev-server使用內存來存儲webpack開發環境下的打包文件,而且可使用模塊熱更新,比傳統的http服務對開發更加有效。

什麼是長緩存?在webpack中如何作到長緩存優化?

瀏覽器在用戶訪問頁面的時候,爲了加快加載速度,會對用戶訪問的靜態資源進行存儲,可是每一次代碼升級或者更新,都須要瀏覽器去下載新的代碼,最方便和最簡單的更新方式就是引入新的文件名稱。

在webpack中,能夠在output給出輸出的文件制定chunkhash,而且分離常常更新的代碼和框架代碼,經過NameModulesPlugin或者HashedModulesPlugin使再次打包文件名不變。

什麼是Tree-sharking?

指打包中去除那些引入了但在代碼中沒用到的死代碼。在wepack中js treeshaking經過UglifyJsPlugin來進行,css中經過purify-CSS來進行.

webpack構建流程

  1. 初始化參數,從配置文件和shell語句中讀取與合併參數,得出最終的參數

  2. 開始編譯:用上一步獲得的參數初始化 Compiler 對象,加載全部配置的插件,執行對象的 run 方法開始執行編譯;

  3. 肯定入口,經過entry找到入口文件

  4. 編譯模塊:從入口文件出發,調用全部配置的 Loader 對模塊進行翻譯(按照loader的規則進行轉換),再找出該模塊依賴的模塊,再遞歸本步驟直到全部入口依賴的文件都通過了本步驟的處理;

  5. 完成模塊編譯,獲得每一個模塊被翻譯以後的最終的內容和依賴關係

  6. 輸出資源,根據入口和模塊之間的依賴關係,組裝成一個個包含多個模塊的chunk,在把每一個chunk轉換成一個單獨的文件加載到輸出列表,這步是能夠修改輸出內容的最後機會

  7. 輸出完成:在肯定好輸出內容後,根據配置肯定輸出的路徑和文件名,把文件內容寫入到文件系統。

  8. 在整個流程中webpack會在恰當的時機執行plugin裏定義的邏輯

如何提升webpack的構建速度?

多入口狀況下,使用CommonsChunkPlugin來提取公共代碼

經過externals配置來提取經常使用庫

利用DllPlugin和DllReferencePlugin預編譯資源模塊 經過DllPlugin來對那些咱們引用可是絕對不會修改的npm包來進行預編譯,再經過DllReferencePlugin將預編譯的模塊加載進來。

使用Happypack 實現多線程加速編譯

使用webpack-uglify-parallel來提高uglifyPlugin的壓縮速度。 原理上webpack-uglify-parallel採用了多核並行壓縮來提高壓縮速度

使用Tree-shaking和Scope Hoisting來剔除多餘代碼

如何利用webpack來優化前端性能

壓縮代碼。uglifyJsPlugin 壓縮js代碼, mini-css-extract-plugin 壓縮css代碼

刪除死代碼(tree shaking),css須要使用Purify-CSS

提取公共代碼。webpack4移除了CommonsChunkPlugin (提取公共代碼),用optimization.splitChunks和optimization.runtimeChunk來代替

相關文章
相關標籤/搜索