1. 程式人生 > 實用技巧 >webpack常用配置

webpack常用配置

1.webpack入門概念

webpack是一個靜態模組打包工具

不是執行的時候打包,是程式碼打包好後在‘瀏覽器’執行,在程式碼執行前就進行一步處理,這中間的一步,也引出了webpack工程化的強大能力。

區別webpack和webpack-cli

在webpack4之前,這兩個東西是合二為一的,4開始,webpack相當於幹活的,而cli相當於發命令的

webpack不用全域性下載,只需要區域性下載即可

webpack正處於一個發展期,有很多不同的版本,如果都用一個版本,可能不能處理多個新舊不同的專案

npx webpack 使用區域性webpack進行打包(手動敲命令,使用佈局) , 也可以使用npm scripts執行的webpack命令預設先找區域性的webpack(使用配置,預設使用區域性)

webpack本身就能解析打包各種模組規範的js程式碼

包括es6 , CommonJs , AMD/requirejs , CMD/seajs

核心基本概念

1.模式mode   development/production(預設)
2.入口entry
3.輸出output
4.載入器loader
5.外掛plugin

10個常用配置

1.mode
2.entry
3.output
4.module
5.plugins
6.devtools
7.devSever
8.reslove
9.optimization
10.externals

相關依賴包

webpack
webpack-cli
webpack-dev-server
webpack-merge
cross-env
css-loader
style-loader
postcss-loader
less-loader
stylus-loader
sass-loader
file-loader
url-loader
image-webpack-loader
babel-loader
vue-loader
eslint-loader
MiniCssExtractPlugin.loader
thread-loader

html-webpack-plugin
[email protected]
mini-css-extract-plugin
optimize-css-assets-webpack-plugin
copy-webpack-plugin
terser-webpack-plugin
add-asset-html-webpack-plugin
webpack-bundle-analyzer
webpack.ProgressPlugin
webpack.HotModuleReplacementPlugin
webpack.HashedModuleldsPlugin
webpack.DllPlugin
webpack.DllReferencePlugin
new webpack.ProvidePlugin

基本使用

熱更行,打包指令,自動將打包檔案插入到頁面當中

webpack.config.js配置:

const path = require('path')
const HtmlWebpckPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
// 輸入目錄,輸出絕對路徑
function resolve(dir) {
    return path.resolve(__dirname,dir)
}
module.exports = {
    //模式
    mode:'production',
    //入口
    entry:resolve('src/index.js'),
    //出口
    output:{
        path:resolve('dist'),
        filename:'bundle.js'
    },
    //模組載入器
    module:{
        rules:[
        ]
    },
    //外掛
    plugins:[
        //向頁面中插入引入打包的js/css的程式碼
        new HtmlWebpckPlugin({
            template:'public/index.html'
        }),
        //清楚打包資料夾 (dist)
        new CleanWebpackPlugin(['dist'])
    ],
    //開發伺服器
    devServer:{
        open:true,//自動開啟瀏覽器訪問
    }
}

package.json口令配置:
  "scripts": {
    "build": "webpack --mode production",   //  yarn build / npm run build
    "dev":"webpack-dev-server --mode development"  //yarn dev  / npm run dev
  },

js打包

主要使用babel進行對js的打包

webpack文件 ⇒ loader ⇒ babel

//1.對babel的理解
webpack本身有用處理各種模組化規範的能力,但是,並不具備處理es6語法的能力,
真正處理es6的是:babel
但是babel本身在某種意義上也不具備編譯es6的能力,babel相當於提供了一個平臺,babel依賴的非常多單獨針對某個語法編譯的外掛,比如async就有一個babel的編譯外掛,const也有一個,箭頭函式又有一個,而babel把他們彙集在一起。
意義何在?:
如此眾多的外掛,不可能每個都去配置,所以用以一個大包來彙總和眾多小的外掛


檢視@babel/preset-env 下package.json 就可以檢視到babel的眾多依賴

//2.babel的解析
1.babel只轉換不相容的“新語法”(可以理解為語法糖,本質上還是底層的一些語法實現的)
=>const/let/箭頭函式/解構賦值/class語法.... 

2.babel不轉換新的api (理解為新的方法,瀏覽器本身就不存在,所以無法編譯)
=>Promise/Map/Set/Object.assign()/Generator/Proxy ....

//3.引出@babel/polyfill : 可以理解為一個補丁包
既然babel不能編譯新的api,那麼就需要一個包將這些方法都實現,然後打入專案之中,供人使用
=>而@babel/polyfill主要依賴兩個包
1.core-js:一個俄羅斯的小哥所寫,主要重寫了很多es6,es7..的語法
2.regenerator-runtime: 彌補core-js沒有實現的async await的缺陷

更進一步的處理:

1.我們使用基礎配置的babel進行es6語法的編譯

2.使用 @babel/polyfill 進行es6新api進行編譯
=》低版本瀏覽器語法,打包支援es6語法,通常是polyfill通過類似打補丁的方式將包引入到專案當中
=》既然有包打入專案,就可以進行優化
	1.使用配置的方式,實現按需引入,用了什麼語法就打入什麼補丁
    2.當使用有很多模組使用了類語法的時候,每個模組都會獨立產生一個輔助函式=>_classCallCheck
	可以提取出來生成一次即可,就需要使用plugins:[@babel/plugin-transform-runtime] 

打包圖片

主要用到的loader有:

  • file-loader
  • url-loader( 依賴於file-loader,針對小圖片可以進行base64處理,減少請求)

有時候會出現url-loader的包依賴於file-loader但是卻沒有下載的情況,需要自行下載

webpack.config.js下module屬性配置:
   //模組載入器
    module:{
        rules:[
            //處理圖片
            {
                test:/\.(png|jpg|gif|svg)$/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:1024*10, //把小於 5kb的檔案轉成Base64的格式
                        name:'img/[name].[ext]',
                    }
                }
            }
        ]
    }

還有圖片壓縮,自行搜尋使用

出了圖片,還有字型,音訊同樣使用的都是url-loader

使用方法和圖片一樣,直接新增一個物件配置即可,修改test屬性和use的options屬性

css處理

對於處理不同的css檔案,需要不同的loader:
css:  1.css-loader  2.style-loader 
less:  1.less  2.less-loader
stylus:  1.stylus  2.stylus-loader 
sass:  1.node-sass  2.sass-loader //注意:node-sass下載可能失敗,yarn < npm < cnpm

使用配置:

css全部被打包進bundle.js當中,css的樣式都是通過js來寫入的

webpack.config.js下module屬性配置:
   //模組載入器
    module:{
        rules:[
            //處理css
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'] //從下往上,從右往左
            },
            //處理less
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader'] 
            },
            //處理stylus
            {
                test: /\.(styl|stylus)$/,
                use: ['style-loader', 'css-loader', 'stylus-loader'] 
            }
        ]
    }

PostCss

利用PostCss可以:1.自動新增程式碼的廠商字首 2.準換現代的css程式碼

主要包:autoprefixer  postcss-loader
配置:
webpack.config.js下module屬性配置:
   //模組載入器
    module:{
        rules:[
            //處理css
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader'] //從下往上,從右往左
            },
            //處理less
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] 
            },
            //處理stylus
            {
                test: /\.(styl|stylus)$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] 
            }
        ]
    }

再建立postcss.config.js:
module.exports = {
    plugins:[
        require('autoprefiexer')(),
        require('postcss-px2rem')({
            unitRem:37.5
        })
    ]
}

單獨打包css

要用上mini-css-extract-plugin    MiniCssExtractPlugin.loader

webpack.congfig.js:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    module:{
        rules:[
            //處理css
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, //代替style-css
                      'css-loader', 
                      'postcss-loader'] //從下往上,從右往左
            },
            //處理less
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader'] 
            },
            //處理stylus
            {
                test: /\.(styl|stylus)$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'stylus-loader'] 
            }
        ]
    },
    plugins:[
        //從js中抽取css單獨打包
        new MiniCssExtractPlugin({
            filename:'css/[name].css'
        })
    ]

注意:抽取檔案單獨打包的時候需要主要一些路徑問題,此處會出現一個絕對路徑的問題

解決:

    output:{
        path:resolve('dist'),
        filename:'bundle.js'
        publicPath:'/'      //給出口檔案的路徑設新增為/,設定為相對路徑
    },

系列問題

1.區別webpack的兩個工具包:webpack和webpack-cli
=>在webpack 3中,webpack本身和它的CLI以前都是在同一個包中,但在第4版中,他們已經將兩者分開來更好地管理它們。cli相對來說是一個命令工具

2.為什麼建議不要全域性下載webpack工具包?
=>因為webpack不同版本的配置常常是不一樣的,為了不同的專案,最好都單獨啟用一個webpack

3.如何解決webpack命令不能識別的問題?
=>有一些舊版本的webpack安裝後還需要配置環境變數才能使用

4.webpack的10大配置選項
5.webpack常用的10個loader
6.webpack中常用的5個plugin
=>見上

7.為什麼要使用html-webpack-plugin?
=>自動引入打包好後的bundle.js ,為html檔案中引入的外部資源如script、link動態新增每次compile後的hash,防止引用快取的外部檔案問題

8.為什麼要使用clean-webpack-plugin?
=>有時候我們打包生成的檔案通常是隨即名,而使用clean-webpack-plugin可用來清除舊檔案,產生新的檔案,避免相同檔案不同名的問題

9.區別css-loader和style-loader
=>webpack是用JS寫的,執行在node環境,所以預設webpack打包的時候只會處理JS之間的依賴關係
=>如果在JS中匯入了css,那麼就需要使用 css-loader 來識別這個模組,通過特定的語法規則進行轉換內容最後匯出
css-loader:會處理 import / require() @import / url 引入的內容.將css檔案生成一個js陣列資料,包括路徑,css字串
style-loader:這個資料頁面並不能直接使用。而是使用通過style-loader再頁面中建立一個style標籤,將css字串屬性寫入到頁面當中


10.區別url-loader和file-loader
=>1.檔案大小小於limit引數,url-loader將會把檔案轉為DataURL;2.檔案大小大於limit,url-loader會呼叫file-loader進行處理,引數也會直接傳給file-loader。因此我們只需要安裝url-loader即可。。

11.webpack-dev-server用來做什麼
=>1.webpack-dev-server是一個小型的Node.js Express伺服器

12.說說熱模替換(HMR)的理解
=>模組熱替換(HMR)的作用是,在應用執行時,無需重新整理頁面,便能替換、增加、刪除必要的模組。
=>具體實現思路可以看官方文件: https://www.webpackjs.com/concepts/hot-module-replacement/

13.說說代理伺服器的理解
?

14.說說history路由404問題
?
15.@babel/preset-env能幹什麼?不能幹什麼?如何解決?
=>包含了各種可能用到的轉譯工具。用來降級和轉義es語法
=>不能轉換瀏覽器不存在的api

16.直接使用@babel/polyfill有什麼問題,如何解決?
=>包過大,最好是按需引入

18.如何對css進行單獨打包和壓縮
=>普通的打包通過css-loader將css檔案轉化為js陣列資料,然後通過style-css再頁面建立style標籤,將屬性和值插入其中
=>如果要單獨打包,就要用到extract-text-webpack-plugin@next,將css從js中抽取出來,將style-css的功能替換為單獨建立檔案


19.postcss是什麼?
=>將css轉換成css抽象語法樹,可以簡單的理解為將css轉換成js,呼叫外掛來處理抽象語法樹,通過外掛實現對css的處理。

20.autoprefixer用來做什麼?
=>自動加上一些屬性的廠商字首

21.postcss-px2rem用來做什麼的?
=>這些css檔案打包前,將檔案裡面的px計算成rem,然後在進行解析,這樣就可以直接在頁面中使用px了。