webapck

webpack基本配置

vue-cli create-react-app
只需要簡單地配置就可以使用jsx和typescript等一些前端新語法

配置webpack.config.js文件

  • entry(項目入口)
    字符串芥备,如entry:"./src/index.js"
    數(shù)組形式: 如entry:[react, react-dom],可以把數(shù)組中的多個文件打包轉(zhuǎn)換為一個chunk
    對象形式荚板,如果需要配置的是多頁的應(yīng)用殴蹄,或者抽離出指定模塊作為指定公共代碼,需要采用這種形式屋灌,屬性名是占位符[name]的值
entry: {
  main:'./src/index2.js',
  second: './src/index2.js',
  vendor:['react', 'react-dom']
}
  • output(出口文件)
    會告訴webpack在哪里輸出所創(chuàng)建的bundle.js以及如何命名
out:{
    path:path.join(__dirname, './dist'),
    name: 'js/bundle-[name]-[hash].js,
    chunkFilename: 'js/[name].chunk.js',
    publicPath:'/dist/'

  }
  • module(模塊的處理)
    webpack只能處理js文件,所以要對傳入的模塊做一些預(yù)處理应狱,用webpack的“l(fā)oader”’去識別新的用法
    loader的作用和基本用法
    webpack中共郭,loader的配置主要在module.rules中進(jìn)行,這是一個數(shù)組疾呻,每一個rule做了兩件事
    識別文件類型除嘹,來確定具體處理該數(shù)據(jù)的loader(Rule.test屬性)
    使用相關(guān)的loader對文件進(jìn)行相關(guān)的操作轉(zhuǎn)換(Rule.use屬性)
    比如我們想要處理react中的jsx語法
module: {
  rules:[{
    test: /(\.jsx|\.js)/,  //表示匹配規(guī)則,是一個正則表達(dá)式
    use:{        //表示針對匹配文件將使用處理的loader
      loader: "babel-loader",  
      options: {
        presets: ["es2015", "react"]
      }
    }
  }]
}

常用的loade
module.rules識別各種新語法
轉(zhuǎn)換編譯:script-loader, babel-loader,ts-loader,coffee-loader
處理樣式:style-loader,css-loader,less-loader,sass-loader,postcss-loader
處理文件:raw--loader,url-loader,file-loader
處理數(shù)據(jù):csv-loader,xml-loader
處理模板語言:html-loader,pug-loader,jade-loader,markdown-loader
清理和測試:mocha-loader,eslint-loader

  • plugin(loader不能做的處理都能交給plugin來做)
const CleanWebpackPlugin = require("clean-webpack-plugin")

{

  ...

  plugin:[
    new webpack.DefinePlugin({
      "process.env" : {
        NODE_ENV: JSON.stringify("production")
      }
    }),
    new CleanWebpackPlugin(["js"], {

      root: __dirname + "/stu/",
      verbose: true,
      dry: false
    })
  ]
}

常見的plugins:
const HtmlWebpackPlugin = require('html-webpack-plugin')
HtmlWebpackPlugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
CleanWebpackPlugin

一些輔助開發(fā)的相關(guān)屬性
  devtool:打包后的代碼和原始代碼存在較大的差異岸蜗,此選項控制是否生成以及如何生成sourcemap
  devserver:通過配置devserver選項尉咕,可以開啟一個本地服務(wù)器
  watch:啟用watch模式后,webpack將持續(xù)監(jiān)聽熱河已經(jīng)解析文件的更改璃岳,開發(fā)是開啟會很方便
  watchoption:用來定制watch模式的選項
  performance:打包后命令行如何展示性能提示年缎,如果超過某個大小是警告還是報錯

  • 對于webpack配置悔捶,要區(qū)分開發(fā)環(huán)境還是產(chǎn)環(huán)境
    為了避免重復(fù)應(yīng)該提取公共代碼

-所以一般有這么幾個文件
webpack.config.js
webpacl.dev.js
webpack.prod.js
webpack.common.js

1、webpack.base.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'index.js'
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: [
                        ['@babel/preset-env', {
                            'useBuiltIns': 'entry'
                        }]
                    ],
                    plugins: ['@babel/plugin-transform-runtime']
                }
            }
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new CopyWebpackPlugin([{
            from: 'static',
            to: 'static'
        }, ])
    ],
    stats: {
        children: false
    }
}

2单芜、webpack.config.js

const merge = require('webpack-merge')
const baseConfig = require('./webpack.base.config')
const devConfig = require('./webpack.dev.config')
const proConfig = require('./webpack.pro.config')

module.exports = (env, argv) => {
    let config = argv.mode === 'development' ? devConfig : proConfig;
    return merge(baseConfig, config);
};

3蜕该、webpack.dev.config.js

module.exports = {
    devtool: 'cheap-module-eval-source-map'
}

4、webpack.pro.config.js

const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = {
    plugins: [
        new CleanWebpackPlugin()
    ]
}

基本配置

拆分配置和merge
處理樣式
啟動本地服務(wù)
處理圖片
處理ES6
模塊化

  • 拆分配置和merge
    webpack-merge,用于將配置文件進(jìn)行合并
npm install webpack-merge

配置(手動指定config)
package.json

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config ./build/prod.config.js",
    "dev": "webpack-dev-server --open --config ./build/dev.config.js"
  },
  • 處理樣式
    樣式預(yù)處理洲鸠,指的是在開發(fā)中使用到的一些預(yù)編譯語言堂淡,如SCSS. LESS等,在項目打包過程中再將這些預(yù)編譯語言轉(zhuǎn)換為CSS
    在module.rules
 {
       test: /\.css$/,
       // loader 的執(zhí)行順序是:從后往前
       use: ['style-loader', 'css-loader', 'postcss-loader'] // 加了 postcss
},{
       test: /\.less$/,
         // 增加 'less-loader' 坛怪,注意順序
         use: ['style-loader', 'css-loader', 'less-loader']
   }
  • 啟動本地服務(wù)
    安裝
npm install --save-dev webpack-dev-server

運行

npx webpack-dev-server
 devServer: {
        port: 8080,
        progress: true,  // 顯示打包的進(jìn)度條
        contentBase: distPath,  // 根目錄
        open: true,  // 自動打開瀏覽器
        compress: true,  // 啟動 gzip 壓縮

        // 設(shè)置代理
        proxy: {
            // 將本地 /api/xxx 代理到 localhost:3000/api/xxx
            '/api': 'http://localhost:3000',

            // 將本地 /api2/xxx 代理到 localhost:3000/xxx
            '/api2': {
                target: 'http://localhost:3000',
                pathRewrite: {
                    '/api2': ''
                }
            }
        }
    }

為了方便淤齐,我們通常會在package.json文件中寫入一項命令配置本地服務(wù)啟動。

"scripts": {
    "dev": "webpack-dev-server",
}

通過命令npm run dev就可以掛載我們指定的目錄袜匿,從而啟動本地服務(wù)了更啄。

  • 處理圖片
    安裝依賴
npm i -D file-loader

在module.rules

{
    test: /\.(png|svg|jpg|gif)$/,
    use: {
        loader: 'file-loader',
        options: {
            name:'assets/[name].[ext]',
        }
    }
},
  • 處理ES6
    使用babel處理es6語法
    安裝
npm install –save-dev babel-loader @babel/core

webpack.cofig.js配置

module: {
rules: [
{
test: /.js$/,
exclude: /node_modules,
//node_modules的js文件不用ES6轉(zhuǎn)化為ES5
loader: "babel-loader"
}
]
}

webpack配置多入口

const path = require('path');
module.exports={
    //入口文件的配置項
    entry:{
        entry:'./src/entry.js',
        //這里我們又引入了一個入口文件
        entry2:'./src/entry2.js'
    },
    //出口文件的配置項
    output:{
        //輸出的路徑,用了Node語法
        path:path.resolve(__dirname,'dist'),
        //輸出的文件名稱
        filename:'[name].js'
    },
    //模塊:例如解讀CSS,圖片如何轉(zhuǎn)換居灯,壓縮
    module:{},
    //插件祭务,用于生產(chǎn)模版和各項功能
    plugins:[],
    //配置webpack開發(fā)服務(wù)功能
    devServer:{}
}

webpack抽離壓縮css文件

需要安裝以下插件

mini-css-extract-plugin //把css抽離成單獨的文件
optimize-css-assets-webpack-plugin  //把抽離出來的css代碼壓縮
terser-webpack-plugin   //壓縮js代碼

uglifyjs-webpack-plugin作用: 壓縮is代碼,不支持壓縮es6
terser-webpack-plugin作用:壓縮is代碼怪嫌,支持壓縮es6

需要安裝的loader
MiniCssExtractPlugin.loader 把css抽離成單獨的文件

const path = require('path');
const HtmlWebpackPlugin  = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const Webpackbar = require('webpackbar');
module.exports = {
    // production模式自動壓縮html,js,css,不用額外使用terser-webpack-plugin來壓縮js
    // 但是如果要分離css,不管是dev還是prod都需要使用mini-css-extract-plugin
    // 但是如果要壓縮分離出來的css,不管是dev還是prod都需要使用optimize-css-assets-webpack-plugin
    mode: 'development',
    entry: {
        main: './src/index.js'
    },
    output: {
        filename: '[name]_[hash:8].js',
        path: path.resolve(__dirname,'../build'),
        publicPath: './'
    },
    plugins:[
        // 打包之后自動生成index.html文件
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './src/index.html'
        }),
        // 打包之前自動刪上一次的打包結(jié)果
        new CleanWebpackPlugin(),
        // 打包時候的進(jìn)度條
        new Webpackbar({color: 'purple'}),
        // 抽離css
        new MiniCssExtractPlugin({
            filename: "css/[name]_[hash:8].css",
            chunkFilename: "[id].css"
        }),
        // 壓縮css
        new OptimizeCssAssetsPlugin(),
        // 壓縮js
        new TerserJSPlugin(),
    ],
    module: {
        rules:[
            {
                test:/\.css$/,
                use: [
                    // 這里一定要使用MiniCssExtractPlugin.loader才能達(dá)到抽離css的效果
                    {
                        loader: MiniCssExtractPlugin.loader,
                    },
                    'css-loader',
                    'postcss-loader',
                    'less-loader'
                ]
            }
        ]
    }
}

webpac抽離公共代碼和第三方代碼

CDN內(nèi)容分發(fā)網(wǎng)絡(luò)

項目中分別有a.js, b.js, page1.js, page2.js這四個JS文件义锥, page1.js 和 page2.js中同時都引用了a.js, b.js, 這時候想把a.js, b.js抽離出來合并成一個公共的js岩灭,然后在page1, page2中自動引入這個公共的js拌倍,怎么配置如下:
optimization(優(yōu)化),與module噪径,output(出口)柱恤,plugins(插件)同級
optimization下面minimizer是壓縮css,splitChunks的common配置
optimization下面vendor配置抽離第三方代碼

module.exports = {
  //...
 
  //優(yōu)化項配置
  optimization: {
    // 分割代碼塊
    splitChunks: {
      cacheGroups: {
 
        //公用模塊抽離
        common: {
          chunks: 'initial',
          minSize: 0, //大于0個字節(jié)
          minChunks: 2, //在分割之前,這個代碼塊最小應(yīng)該被引用的次數(shù)
        },
        
        //第三方庫抽離
        vendor: {
          priority: 1, //權(quán)重
          test: /node_modules/,
          chunks: 'initial',
          minSize: 0, //大于0個字節(jié)
          minChunks: 2, //在分割之前找爱,這個代碼塊最小應(yīng)該被引用的次數(shù)
        }
      }
    }
  }
}

webpack實現(xiàn)異步加載JS

module chunk bundle 的區(qū)別

module -各個源碼文件梗顺,webapck中一切皆模塊
chunk -多個模塊組件的,如entry import() splitChunk
bundle最終的輸出文件

webpack優(yōu)化構(gòu)建速度

優(yōu)化babel-loder
InnorePlugin
noParse
happyPack
ParallelUglifyPlugin
自動刷新

happyPack

  1. happyPack多線程打包
  • JS單線程车摄,開啟多線程打包
  • 提高構(gòu)建速度寺谤,特別是多核CPU
  1. ParallelUglifyPlugin多進(jìn)程壓縮JS
  • webapck內(nèi)置Uglify工具壓縮js
  • js單線程,開啟多進(jìn)程壓縮更快
  • 和happyPack同理
  1. 關(guān)于開啟多進(jìn)程
    項目較大吮播,打包較慢变屁,開啟多進(jìn)程能提高速度
    項目較小,開啟多進(jìn)程會降低速度(進(jìn)程開銷)
    按需使用

webpack配置熱更新

自動刷新

  watchOptions: {
        ignored: /node_modules/, // 忽略哪些
        // 監(jiān)聽到變化發(fā)生后會等300ms再去執(zhí)行動作薄料,防止文件更新太快導(dǎo)致重新編譯頻率太高
        // 默認(rèn)為 300ms
        aggregateTimeout: 300,
        // 判斷文件是否發(fā)生變化是通過不停的去詢問系統(tǒng)指定文件有沒有變化實現(xiàn)的
        // 默認(rèn)每隔1000毫秒詢問一次
        poll: 1000
    }
  1. 熱更新
    自動刷新:整個網(wǎng)頁全部刷新敞贡,速度較慢
    自動刷新:整個網(wǎng)頁全部刷新,狀態(tài)會丟失
    熱更新:新代碼生效摄职,網(wǎng)頁不刷新誊役,狀態(tài)不丟失
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin');
 plugins: [
        new webpack.DefinePlugin({
            // window.ENV = 'production'
            ENV: JSON.stringify('development')
        }),
        new HotModuleReplacementPlugin()
    ],
    devServer: {
        port: 8080,
        progress: true,  // 顯示打包的進(jìn)度條
        contentBase: distPath,  // 根目錄
        open: true,  // 自動打開瀏覽器
        compress: true,  // 啟動 gzip 壓縮

        hot: true,

        // 設(shè)置代理
        proxy: {
            // 將本地 /api/xxx 代理到 localhost:3000/api/xxx
            '/api': 'http://localhost:3000',

            // 將本地 /api2/xxx 代理到 localhost:3000/xxx
            '/api2': {
                target: 'http://localhost:3000',
                pathRewrite: {
                    '/api2': ''
                }
            }
        }
    },

何時使用DllPlugin

前端框架如Vue React获列,體積大,構(gòu)建慢
較穩(wěn)定蛔垢,不常升級版本
同一個版本只構(gòu)建一次即可击孩,不用每次都重新構(gòu)建
webpack已內(nèi)置DllPlugin支持
DllPlugin-打包出dll文件
DllReferencePlugin

webpack優(yōu)化構(gòu)建速度

webpack優(yōu)化構(gòu)建速度(可用于生產(chǎn)環(huán)境)
優(yōu)化babel-loader
IgnorePlugin
noParse
happyPack
ParellelUqlifyPlugin

webpack優(yōu)化構(gòu)建速度(不用于生產(chǎn)環(huán)境)

自動刷新
熱更新
DllPlugin

webpack性能優(yōu)化-產(chǎn)出代碼

體積更小
合理分包,不重復(fù)加載
速度更快鹏漆,內(nèi)存使用更少

  {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        // 小于 5kb 的圖片用 base64 格式產(chǎn)出
                        // 否則巩梢,依然延用 file-loader 的形式,產(chǎn)出 url 格式
                        limit: 5 * 1024,

                        // 打包到 img 目錄下
                        outputPath: '/img1/',

                        // 設(shè)置圖片的 cdn 地址(也可以統(tǒng)一在外面的 output 中設(shè)置艺玲,那將作用于所有靜態(tài)資源)
                        // publicPath: 'http://cdn.abc.com'
                    }
                }
            },

webapck性能優(yōu)化-產(chǎn)出代碼

小圖片base64 編碼
bundle加hash
懶加載
使用prodction
Scope Hosting
提取公共代碼
IngorePlugin
使用CDN加速

Tree-Shaking

自動開啟代碼壓縮
Vue React等會自動刪掉調(diào)試代碼括蝠,(如開發(fā)環(huán)境的warning)
啟動Tree-Shaking

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市饭聚,隨后出現(xiàn)的幾起案子忌警,更是在濱河造成了極大的恐慌,老刑警劉巖秒梳,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件法绵,死亡現(xiàn)場離奇詭異,居然都是意外死亡酪碘,警方通過查閱死者的電腦和手機朋譬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兴垦,“玉大人徙赢,你說我怎么就攤上這事√皆剑” “怎么了犀忱?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長扶关。 經(jīng)常有香客問我,道長数冬,這世上最難降的妖魔是什么节槐? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮拐纱,結(jié)果婚禮上铜异,老公的妹妹穿的比我還像新娘。我一直安慰自己秸架,他們只是感情好揍庄,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著东抹,像睡著了一般蚂子。 火紅的嫁衣襯著肌膚如雪沃测。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天食茎,我揣著相機與錄音蒂破,去河邊找鬼。 笑死别渔,一個胖子當(dāng)著我的面吹牛附迷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哎媚,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼喇伯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拨与?” 一聲冷哼從身側(cè)響起稻据,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎截珍,沒想到半個月后攀甚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡岗喉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年秋度,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钱床。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡荚斯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出查牌,到底是詐尸還是另有隱情事期,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布纸颜,位于F島的核電站兽泣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胁孙。R本人自食惡果不足惜唠倦,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涮较。 院中可真熱鬧稠鼻,春花似錦、人聲如沸狂票。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至慌盯,卻和暖如春周霉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背润匙。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工诗眨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人孕讳。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓匠楚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親厂财。 傳聞我的和親對象是個殘疾皇子芋簿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容