webpack 配置從頭到腳

下面是webpack.conf.prod.js 部分內(nèi)容

const path = require("path");
const config = {
  mode: "production",
  resolve: webpackConfigResolve,
  stats: "minimal",
  entry: './app.js';
  output: {
    filename:'bundle.js',
  },
  module: {
    rules: webpackConfigmModuleRules,
  },
  optimization: {},
  plugins: [],
};

首先認(rèn)識下webpack每項配置項

entry

待更

output

待更

module

待更

resolve

webpack 在啟動后會從配置的入口模塊出發(fā)找出所有依賴的模塊户盯,resolve配置 webpack 如何尋找模塊所對應(yīng)的文件跨跨。 webpack 內(nèi)置 JavaScript 模塊化語法解析功能谋作,默認(rèn)會采用模塊化標(biāo)準(zhǔn)里約定好的規(guī)則去尋找,但你也可以根據(jù)自己的需要修改默認(rèn)的規(guī)則纽帖。如下配置

const path = require('path');
function resolve(dir) {
  return path.join(__dirname, '..', dir);
}
module.exports = {
  extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.less', '.css'],
  mainFields: ['module', 'jsnext:main', 'main'],
  symlinks: false,
  alias: {
    '@': resolve('src'),
  },
};
  • alias
    resolve.alias配置項通過別名來把原導(dǎo)入路徑映射成一個新的導(dǎo)入路徑隧土。例如使用以下配置:
 resolve:{
  alias:{
    components: './src/components/'
  }
}

當(dāng)你通過import Button from 'components/button導(dǎo)入時嚣镜,實際上被 alias 等價替換成了 import Button from './src/components/button'

以上 alias 配置的含義是把導(dǎo)入語句里的components關(guān)鍵字替換成./src/components/剩瓶。

這樣做可能會命中太多的導(dǎo)入語句,alias 還支持 $ 符號來縮小范圍到只命中以關(guān)鍵字結(jié)尾的導(dǎo)入語句:

resolve:{
  alias:{
    'react$': '/path/to/react.min.js'
  }
}

react$只會命中以react結(jié)尾的導(dǎo)入語句城丧,即只會把import 'react'關(guān)鍵字替換成import '/path/to/react.min.js'延曙。

  • mainFields
    有一些第三方模塊會針對不同環(huán)境提供幾分代碼。 例如分別提供采用 ES5 和 ES6 的2份代碼亡哄,這2份代碼的位置寫在package.json文件里枝缔,如下:
{
  "jsnext:main": "es/index.js",// 采用 ES6 語法的代碼入口文件
  "main": "lib/index.js" // 采用 ES5 語法的代碼入口文件
}

Webpack 會根據(jù) mainFields 的配置去決定優(yōu)先采用那份代碼, mainFields 默認(rèn)如下:

mainFields: ['browser', 'main']

Webpack 會按照數(shù)組里的順序去 package.json 文件里尋找磺平,只會使用找到的第一個
假如你想優(yōu)先采用 ES6 的那份代碼魂仍,可以這樣配置:

mainFields: ['jsnext:main', 'browser', 'main']
  • extensions
    在導(dǎo)入語句沒帶文件后綴時,Webpack 會自動帶上后綴后去嘗試訪問文件是否存在拣挪。resolve.extensions用于配置在嘗試過程中用到的后綴列表擦酌,默認(rèn)是:
extensions: ['.js', '.json']

也就是說當(dāng)遇到require('./data')這樣的導(dǎo)入語句時,Webpack 會先去尋找./data.js文件菠劝,如果該文件不存在就去尋找./data.json文件赊舶, 如果還是找不到就報錯。

假如你想讓 Webpack 優(yōu)先使用目錄下的 TypeScript 文件赶诊,可以這樣配置:

extensions: ['.ts', '.js', '.json']
  • modules
    resolve.modules 配置 Webpack 去哪些目錄下尋找第三方模塊笼平,默認(rèn)是只會去 node_modules 目錄下尋找。 有時你的項目里會有一些模塊會大量被其它模塊依賴和導(dǎo)入舔痪,由于其它模塊的位置分布不定寓调,針對不同的文件都要去計算被導(dǎo)入模塊文件的相對路徑, 這個路徑有時候會很長锄码,就像這樣 import ../../../components/button' 這時你可以利用modules配置項優(yōu)化夺英,假如那些被大量導(dǎo)入的模塊都在./src/components目錄下晌涕,把 modules 配置成
modules:['./src/components','node_modules']

后,你可以簡單通過import 'button'導(dǎo)入痛悯。

  • descriptionFiles
    resolve.descriptionFiles配置描述第三方模塊的文件名稱余黎,也就是 package.json 文件。默認(rèn)如下:
descriptionFiles: ['package.json']
  • enforceExtension
    resolve.enforceExtension如果配置為true所有導(dǎo)入語句都必須要帶文件后綴载萌,例如開啟前import './foo'能正常工作惧财,開啟后就必須寫成import './foo.js'

  • enforceModuleExtension
    enforceModuleExtensionenforceExtension 作用類似扭仁,但 enforceModuleExtension 只對 node_modules 下的模塊生效垮衷。 enforceModuleExtension 通常搭配 enforceExtension 使用,在 enforceExtension:true 時斋枢,因為安裝的第三方模塊中大多數(shù)導(dǎo)入語句沒帶文件后綴帘靡, 所以這時通過配置 enforceModuleExtension:false 來兼容第三方模塊

plugins

常用的plugins如下

const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const cssnano = require("cssnano");
const TerserPlugin = require("terser-webpack-plugin");
const HappyPack = require("happypack");
  • html-webpack-plugin
    作用:生成html
const htmlPlugin = new HtmlWebpackPlugin({
    filename: `${entry}.html`,
    title: `${titles[entry]}`,
    template: path.resolve(__dirname, '../../src/index.js'),
    chunks: [
      'vendors.core',
      'vendors.commons',
    ],
    minify: HtmlWebpackPluginMinifyOptions,
  });

html-webpack-plugin插件詳細(xì)用法參見:
http://www.reibang.com/p/08a60756ffda

  • HotModuleReplacementPlugin
    作用:頁面熱更新(模塊熱替換)
    首先我們要確保項目是基于webpack-dev-serverwebpack-dev-middle進(jìn)行開發(fā)的,webpack本身的命令行并不支持HMR瓤帚。webpack.conf.dev.js文件部分內(nèi)容如下:
const webpack = require('webpack');
module.exports = {
  // ...
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ],
  devServer:{
    hot:true,
  }
}

也可以在頁面中開啟HMR描姚,比如下面這個例子:

import { add } from 'util.js';
add(2,3);
if(module.hot){
  module.hot.accept();
}

熱更新原理:
css-loader、vue-loader已經(jīng)幫我們寫了這部分代碼戈次,所以不需要手寫了轩勘,但是如果是HTML,需要自己手動執(zhí)行下面的代碼

if (module.hot) {
  module.hot.accept('文件地址', () => {
    // 重新執(zhí)行文件
  })
}
  • mini-css-extract-plugin(webpack 4及以上版本)
    mini-css-extract-plugin可以理解成extract-text-webpack-plugin的升級版怯邪,它擁有更豐富的特性和更好的性能绊寻,從Webpack 4開始官方推薦使用該插件進(jìn)行樣式提取(Webpack 4以前的版本是用不了的)悬秉。
    說到mini-css-extract-plugin的特性澄步,最重要的就是它支持按需加載CSS,以前在使用extract-text-webpack-plugin的時候我們是做不到這一點的和泌。舉個例子村缸,a.js通過import()函數(shù)異步加載了b.js,b.js里面加載了style.css武氓,那么style.css最終只能被同步加載(通過HTML的link標(biāo)簽)梯皿。但是現(xiàn)在mini-css-extract-plugin會單獨打包出一個0.css(假設(shè)使用默認(rèn)配置),這個CSS文件將由a.js通過動態(tài)插入link標(biāo)簽的方式加載县恕。

在webpack.conf.prod.js中引入:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry: './app.js',
    output: {
        filename:'[name].js',
    },
    mode: 'development',
    module: {
        rules: [{
            test: /\.css$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath:'../',
                    },
                },
                'css-loader'
            ],
        }],
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename:'[name].css',
        })
    ]
}
  • extract-text-webpack-plugin(webpack 4之前版本)
    作用:提取樣式到css文件
    在webpack.conf.prod.js中引入:
const ExtractTextplugin = require('extract-text-webpack-plugin');
module.exports = {
  entry: './app.js';
  output: {
    filename:'bundle.js',
  },
  mode:'development',
  module: {
    rules:[
      {
        test:/\.css$/,
        use:ExtractTextplugin.extract({
          fallback:'style-loader',
          use:'css-loader',
        })
      }
    ]
  },
  plugins:[
    new ExtractTextPlugin('bundle.css')
  ]
} 
  • optimize-css-assets-webpack-plugin
    作用:壓縮css
    壓縮CSS文件的前提是使用extract-text-webpack-plugin或mini-css-extract-plugin將樣式提取出來东羹,接著使用optimize-css-assets-webpack-plugin來進(jìn)行壓縮,這個插件本質(zhì)上使用的是壓縮器cssnano忠烛,當(dāng)然我們也可以通過其配置進(jìn)行切換属提。具體請看下面的例子:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
    // ...
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader',
                }),
            }
        ],
    },
    plugins: [new ExtractTextPlugin('style.css')],
    optimization: {
        minimizer: [new OptimizeCSSAssetsPlugin({
            // 生效范圍,只壓縮匹配到的資源
            assetNameRegExp: /\.optimize\.css$/g,
            // 壓縮處理器美尸,默認(rèn)為 cssnano
            cssProcessor: require('cssnano'),
            // 壓縮處理器的配置
            cssProcessorOptions: { discardComments: { removeAll: true } },
            // 是否展示 log
            canPrint: true,
        })],
    },
};
  • terser-webpack-plugin (webpack 4 集成)
    作用:壓縮Javascript
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
    //...
    optimization: {
        // 覆蓋默認(rèn)的 minimizer
        minimizer: [
            new TerserPlugin({
                /* your config */
                test: /\.js(\?.*)?$/i,
                exclude: /\/excludes/,
            })
        ],
    },
};
  • webpack-bundle-analyzer
    作用:分析打包后輸出的bundle體積大小垒拢。
    配置如下:
const Analyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
  ...
  plugins: [
    new Analyzer()
    ],
}
  • clean-webpack-plugin
    作用:在每次構(gòu)建前清理 /dist 文件夾旬迹。
    配置如下:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
  ...
  plugins:[
        new CleanWebpackPlugin()
  ],
}

參考博客:
https://www.cnblogs.com/joyco773/p/9049760.html
http://www.reibang.com/p/755aad97d810
http://www.reibang.com/p/2df87e8f4d3e
http://www.reibang.com/p/d08d5bc85ad2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市求类,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屹耐,老刑警劉巖尸疆,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惶岭,居然都是意外死亡寿弱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門按灶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來症革,“玉大人,你說我怎么就攤上這事鸯旁≡朊” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵铺罢,是天一觀的道長艇挨。 經(jīng)常有香客問我,道長韭赘,這世上最難降的妖魔是什么缩滨? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮泉瞻,結(jié)果婚禮上脉漏,老公的妹妹穿的比我還像新娘。我一直安慰自己袖牙,他們只是感情好侧巨,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贼陶,像睡著了一般刃泡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碉怔,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天烘贴,我揣著相機與錄音,去河邊找鬼撮胧。 笑死桨踪,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的芹啥。 我是一名探鬼主播锻离,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼铺峭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了汽纠?” 一聲冷哼從身側(cè)響起卫键,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虱朵,沒想到半個月后莉炉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡碴犬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年絮宁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片服协。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡绍昂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出偿荷,到底是詐尸還是另有隱情窘游,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布遭顶,位于F島的核電站张峰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏棒旗。R本人自食惡果不足惜喘批,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铣揉。 院中可真熱鬧饶深,春花似錦、人聲如沸逛拱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朽合。三九已至俱两,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曹步,已是汗流浹背宪彩。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留讲婚,地道東北人尿孔。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親活合。 傳聞我的和親對象是個殘疾皇子雏婶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354