萬字總結webpack入門進階知識

這是我參與8月更文挑戰的第3天,活動詳情查看:8月更文挑戰css

🤾‍♀️序言

上一篇文章中咱們講到了 webpack 的一些基礎特性,可是呢,單單會基礎特性仍是遠遠不夠的。所以,在今天的文章中,將給你們帶來 webpack 的高級特性,包括但不限於 dev 環境和 prod 環境的區分打包,以及使用 webpack 對項目進行代碼分割等等技巧。html

廢話很少說,下面開始進入今天的學習吧~🎳vue

🏓1、Tree Shaking

1. 引例闡述

假設如今咱們有一個需求,寫一段程序來對兩個數作加法和減法。如今,咱們來實現這個功能。具體代碼以下:node

export const add = (a, b) => {
    console.log(a + b);
}

export const minus = (a, b) => {
    console.log(a - b);
}

複製代碼

接下來,咱們在入口文件引入它。具體代碼以下:jquery

import { add } from './math.js';

add(1, 2);
複製代碼

在這種狀態下,咱們用 npx webpack 命令來對項目進行打包。查看打包後的文件代碼:webpack

/***/ "./src/math.js":
/*!*********************!*\ !*** ./src/math.js ***! \*********************/
/*! exports provided: add, minus */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
 "use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "add", function() { return add; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "minus", function() { return minus; });
const add = (a, b) => {
  console.log(a + b);
};
const minus = (a, b) => {
  console.log(a - b);
};

/***/ })
複製代碼

咱們能夠發現,在入口文件咱們只引入了加法的操做,由於咱們當下只想用到加法功能,而暫時還不須要用減法。可是呢,打包後的文件,把減法部分的內容,也一塊兒,給打包進去了。這無形之中,多多少少給咱們添加了很多麻煩。git

所以呢,咱們就須要引入 webpack 中的 Tree Shaking ,來解決這個問題。github

2. Tree Shaking配置

首先咱們須要在 webpack.common.js 裏面進行配置。若是是在 Development 的模式下,那麼默認是不擁有 Tree Shaking 的。所以須要進行如下配置,具體代碼以下:web

//node的核心模塊
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');

module.exports = {
	mode:'development',
	optimization: {
		usedExports: true
	}
}
複製代碼

在開發環境下,咱們須要加上 optimization 模塊來對項目開啓 Tree Shakingnpm


接下來,咱們繼續對 package.json 進行配置。在這個文件下,咱們須要添加如下代碼:

{
	"sideEffects": false
}
複製代碼

sideEffects:false 指的是什麼意思呢?當設置爲 false 時,代表對全部的 ES Module 開啓 Tree Shaking 操做。

值得注意的是, Tree Shakig 只支持 ES Module 這種類型的引入,並不支持 commonJS 等類型的引入。這是由於, ES Module 的底層實現是靜態的,而 commonJS 的實現則是動態的。


還有另一種狀況就是,若是你想要使得某些模塊不開啓 Tree Shaking ,那麼能夠將 sideEffects 進行如下配置。具體代碼以下:

{
	"sideEffects": [
		"*.css""@babel/poly-fill" 
	]
}
複製代碼

以上代碼的意思爲,對全部的 css 文件以及 @babel/poly-fill 不開啓 Tree-shaking 功能。


接下來咱們來看一下配置完成以後,在開發環境下的效果。具體代碼以下:

/***/ "./src/math.js":
/*!*********************!*\ !*** ./src/math.js ***! \*********************/
/*! exports provided: add, minus */
/*! exports used: add */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
 "use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return add; });
/* unused harmony export minus */
const add = (a, b) => {
  console.log(a + b);
};
const minus = (a, b) => {
  console.log(a - b);
};

/***/ })

/******/ });
//# sourceMappingURL=main.js.map
複製代碼

你們能夠看到,若是是在開發模式下,減法功能依然是存在的,只是多個一句 /*! exports used: add */ 來代表只使用 add 這個功能。

這是爲何呢?由於在開發模式下, webpack 怕這個地方若是引入了其餘模塊,那麼刪除就很容易致使報錯,因此它沒有進行刪除。


但若是 mode 是在生產環境下時, Tree Shaking 的做用就比較明顯了。咱們修改完 mode 後來看下打包後的結果。具體代碼以下:

function (e, n, r) { "use strict"; r.r(n); var t, o; t = 1, o = 2, console.log(t + o) }
複製代碼

生產環境下打包後只有一行,小編摘取了最終要的部分出來。

你們能夠看到,當處於生產環境下時,打包後的結果只顯示了加法功能。而咱們沒有使用到減法,因此這個時候就不會連帶着打包出來了。

順帶着這個話題,接下來咱們就來說一下, webpackdevelopmentProduction 模式下的區分打包。

🏸2、Development和Prodiction模式的區分打包

1. 項目打包結構

一般狀況下,咱們的項目會有三個 webpack 的配置文件。一個是 webpack.common.js ,一個是 webpack.dev.js ,另一個是webpack.prod.js 。第一個文件用來放開發環境和生產環境下共同的配置,第二個文件用來放開發環境下的配置,第三個文件用來放生產環境下的配置。

接下來咱們來了解下,這三個配置文件的代碼。

2. 共有配置webpack.common.js

若是咱們不編寫 common 文件的話,那麼 devprod 這兩個文件的代碼重合度就會比較高,因此咱們把相同的部分抽離出來。具體代碼以下:

//node核心模塊
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    // 放置入口文件,明確怎麼打包
	entry:{
		main: './src/index.js'
	},
    module:{
		rules:[{
			test: /\.m?js$/,
			//exclude,顧名思義即排除在外。若是js文件在node_modules文件夾下面,那麼咱們就排除在外
			// 由於node_module通常都是來自於第三方庫,它已經自動的處理好此部分工做,因此咱們不必再去作重複操做
			exclude: /node_modules/,
			use: {
			  loader: "babel-loader",
			}
		  },{
			test:/\.(jpg|png|gif)$/,
			use:{
				loader:'file-loader',
				options: {
					//placeholder 佔位符
					name: '[name]_[hash].[ext]',
					outputPath: 'images/',
					limit: 10240
				}
			}
		},{
			test:/\.scss$/,
			use:[
				'style-loader', 
				{
					loader: 'css-loader',
					options: {
						//代表前面要先走sass-loader和postcss-loader
						importLoaders: 2,
						modules: true
					}
				}, 
				'sass-loader',
				'postcss-loader'
			]
		},{
			test:/\.css$/,
			use:[
				'style-loader',
				'css-loader',
				'postcss-loader'
			]
		},{
			test: /\.(eot|ttf|svg)$/,
			use: {
				loader: 'file-loader',
			}
		}]
	},
    plugins: [new HtmlWebpackPlugin({
		//代表要引用哪個模板
		template: 'src/index.html'
	}),new CleanWebpackPlugin(['dist'])
	],
    // 輸出,代表webpack應該怎麼輸出
	output: {
		publicPath: '/',
		//用[]能夠生成多個文件
		filename: '[name].js',
		// 指打包後的文件要放在哪一個文件下
		path: path.resolve(__dirname, 'dist')
	}
}
複製代碼

3. 開發環境webpack.dev.js

抽離完 common 代碼以後,如今咱們來編寫 webpack.dev.js 文件。具體代碼以下:

const webpack = require('webpack');
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const devConfig = {
	mode:'production',
	devtool: 'cheap-module-eval-source-map',
	devServer: {
		contentBase: './dist',
		// 當運行完npm run start時,會自動的幫咱們打開瀏覽器
		open: true,
		port: 8080,
		// 讓咱們的webpackDevServer開啓hotModuleReplacement這樣子的功能
		hot: true,
		// 即使HMR沒有生效,也不讓瀏覽器自動刷新
		hotOnly: true
	},
	plugins: [
        //熱模塊更新
		new webpack.HotModuleReplacementPlugin()
	],
	optimization: {
		usedExports: true
	}
}

module.exports = merge(commonConfig, devConfig)
複製代碼

4. 生產環境webpack.prod.js

繼續,咱們來編寫抽離後的 prod 代碼。具體代碼以下:

const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const prodConfig = {
	mode:'development',
	devtool: 'cheap-module-source-map'
}

module.exports = merge(commonConfig, prodConfig)
複製代碼

到這裏,你們對比上面三個文件的代碼能夠發現,這樣的代碼抽離使得咱們的項目結構變得更爲清晰了。

5. 運行項目package.json

上面配置完成以後,咱們如今要來想一下,想要運行開發環境和生產環境不用的配置,是否是應該把運行命令也給區分開來。所以,咱們package.json 文件作出如下配置:

{
    "scripts": {
    	"dev": "webpack-dev-server --config webpack.dev.js",
    	"build": "webpack --config webpack.prod.js"
  }
}
複製代碼

經過以上配置,那麼咱們就能夠經過命令 npm run devnpm run build 來運行項目,以此來區分項目是開發環境仍是生產環境


同時,若是咱們想要在控制檯更直觀的看到報錯信息,那麼在開發環境的狀況下,咱們能夠不用 webpack-dev-server 來運行,能夠直接用用 webpack 來運行。具體代碼以下:

{
    "scripts": {
    	"dev-server": "webpack --config webpac.dev.js",
    	"dev": "webpack-dev-server --config webpack.dev.js",
    	"build": "webpack --config webpack.prod.js"
  }
}
複製代碼

這樣,咱們就能夠經過 npm run dev-build ,來使用 webpack 來運行項目。

⚽3、Webpack和Code Splitting、SplitChunksPlugin

1. 代碼分割-Code Splitting

有時候,咱們可能會遇到一個業務邏輯裏面有上萬行代碼,那麼這上萬行代碼打包後,所有就丟到 main.js 文件裏面了,這樣大的文件,會使得整個項目的加載速度會變得非常緩慢。所以,咱們就須要用到代碼分割Code Splitting來解決這件事情。

咱們在 webpack.common.js 中進行配置。具體代碼以下:

module.exports = {
	optimization: {
		splitChunks: {
			chunks: 'all'
		}
	}
}
複製代碼

經過以上代碼咱們能夠得知,經過使用 optimization 中的 splitChunks ,達到了代碼分割的效果。

那使用這個配置以後, webpack 想要作的事情是什麼呢?

事實上,使用 splitChunks 以後,那麼當 webpack 遇到公用的類庫時,會幫咱們自動地打包生成一個新的文件,以後再把其他的業務邏輯拆分到另一個文件中去。

值得注意的是,公用類庫無論是以同步的方式仍是以異步的方式進行加載, webpack 都可以幫咱們進行代碼分割。

2. 引例闡述-SplitChunksPlugin

上面咱們講到了 webpack 的代碼分割,那麼實際上, webpack 的代碼分割,其底層實現原理所使用的是 splitChunksPlugin 這個插件。接下來咱們來說一下這個插件。

在沒有用 SplitChunksPlugin 這個插件以前,若是咱們異步引入一個庫,那麼 webpack 給其打包後的文件名將會命名爲 0.js1.js......

咱們如今但願在作代碼分割時, webpack 能給咱們的第三方庫進行自定義命名,這又該怎麼處理呢?

3. 實現方式-SplitChunksPlugin

首先咱們對引入的庫前面,添加 webpackChunkName 配置。具體代碼以下:

function getComponent() {
    return import(/*webpackChunkName:"lodash"*/'lodash').then(({ default: _ }) => {
        var element = document.createElement('div');
        element.innerHTML = _.join(['Monday', 'Tuesday'], '_');
        return element;
    })
}

getComponent().then(element => {
    document.body.appendChild(element);
})
複製代碼

/*webpackChunkName:"lodash"*/ 這句話想要代表的意思爲:當咱們異步的引入 lodash 這個庫而且想要作代碼分割時,即當咱們給 webpack 進行打包時,給其起名爲 lodash


上面這個配置知識第一步,接下來咱們要來安裝並使用一個動態引入的插件。具體代碼以下:

安裝插件:

npm install --save-dev @babel/plugin-syntax-dynamic-import
複製代碼

.babelrc 下引入:

{
	// plugins: ["dynamic-import-webpack"] 非官方支持插件
	plugins: ["@babel/plugin-syntax-dynamic-import"]
}
複製代碼

配置 webpack.common.js

module.exports = {
	optimization: {
		splitChunks: {
			chunks: 'all',
			cacheGroups: {
				vendors: false,
				default: false
			}
		}
	},
}
複製代碼

4. SplitChunksPlugin配置參數

接下來咱們再來看關於 SplitChunksPlugin 的一些經常使用配置。具體代碼以下:

module.exports = {
	optimization: {
		splitChunks: {
		  /*使用async時,只對異步代碼進行代碼分割; 使用all時,對同步和異步代碼同時進行代碼分割; 使用initial時,表示對同步代碼進行代碼分割*/
		  chunks: 'all',
          //大於30kb時,作代碼分割
		  minSize: 30000,
          //代表代碼分割後文件最大的大小,若是超過了則會繼續進行拆分;有一些文件若是拆分不了則此配置想基本就沒啥用了
		  maxSize: 0,
		  minRemainingSize: 0,
          //至少有兩個塊被使用了纔會被提取
		  minChunks: 2,
          //表示同時加載的模塊數,最可能是5個
          /*好比咱們引入了10個類庫,那麼咱們會作10次代碼分割。 而這個時候咱們將此參數填爲5,那麼webpack在打包時會將前10個庫給咱們生成5個js文件, 以後的就不會再作代碼分割了,所有丟到一個文件裏面去*/
		  maxAsyncRequests: 5,
          //入口文件作代碼分割最多隻能分割成3個js文件,超過3個就不會再作代碼分割了
		  maxInitialRequests: 3,
          //文件生成時的中間符號
		  automaticNameDelimiter: '~',
          //讓defaultVendors和default中的文件名有效
		  name: true,
		  enforceSizeThreshold: 50000,
          //當打包同步代碼時,cacheGroups
		  cacheGroups: {
			defaultVendors: {
			  //檢測你引入的庫,查詢是不是在node_module下的
			  test: /[\\/]node_modules[\\/]/,
			  priority: -10,
			  //肯定是在node_modules下後,將其進行打包,並命名爲vendors.js
			  filename: 'vendors.js'
			},
            //對非第三方庫的代碼作代碼分割
			default: {
				priority: -20,
				reuseExistingChunk: true,
                filename: 'common.js'
			}
		  },
		}
	}
}
複製代碼

🏐4、打包分析,Preloading,Prefetching

1. 打包分析

打包分析指的是,當咱們使用 webpack 來進行代碼打包以後,咱們能夠藉助打包分析的一些工具,來對咱們打包生成的文件進行必定的分析,以後來看其打包的是否合理。那麼如何進行打包分析呢?

咱們要用到一個 github 的第三方倉庫,戳此連接進入~

瞭解完文檔該庫的內容後,接下來咱們要對 package.json 進行配置。具體代碼以下:

{
    "scripts": {
        "dev-build": "webpack --profile --json > stats.json --config ./build/webpack.dev.js",
        "dev": "webpack-dev-server --config ./build/webpack.dev.js",
        "build": "webpack --config ./build/webpack.prod.js"
  	}
}
複製代碼

經過上面的代碼,咱們能夠分析:在 --config 前面加上配置 --profile --json > stats.json ,意思爲 webpack 打包後會生成打包分析文件,這個文件叫作 stats.json ,同時, --json 表示的意思爲 stats.json 文件的格式是一個 json 格式的。


在生成完 stats.json 文件之後,咱們就能夠把它放到打包工具裏進行分析。你們能夠定位到官方文檔中的 bundle-analysis ,裏面提供了 webpack-chartwebpack-visualizer 等可視化工具供咱們使用,這個能夠依據我的需求,選擇對應的工具,對 stats.json 文件進行分析。

2. Preloading、Prefetching

(1)引例闡述

事實上,當咱們配置 splitChunks 時,裏面的 chunks 默認值是 async 。也就是說,若是咱們不對它進行配置,那 webpack 默認只對異步代碼進行代碼分割。 webpack 爲何要這麼作呢?

webpack認爲把同步代碼打包在一個文件就行了,同時呢,它但願咱們要多寫點異步加載代碼,這樣才能讓咱們的網站性能獲得真正的提高。

如今,咱們來講一個生活中一個很是常見的場景。假設如今咱們在登陸知乎網站,那麼剛進去的時候咱們是尚未登陸的。咱們如今但願的是點擊登陸這個按鈕,登陸對應的模態框就能顯示出來,而不是點擊完還要等到它加載,這無形這種就可使得頁面加載速度變快了許多。

那這該怎麼處理呢?這就要談到 webpack 中的 preloadingprefetching 了。

(2)preloading和prefetching

假設咱們如今要引入一個 click.js 文件,那麼咱們能夠這麼處理。具體代碼以下:

document.addEventListener('click', () => {
    // 這句話的意思爲:當主要的js文件都加載完成以後,以後就是網絡帶寬有空閒的時候,它就會偷偷的把 ./click.js 文件給加載好
    import(/* webpackPrefetch: true */ './click.js').then(({default: func}) => {
        func();
    })
});
複製代碼

經過以上代碼咱們能夠知道,在所引入的文件前面,即 ./click.js前面,加入 /* webpackPrefetch: true */ 便可達到咱們想要的效果。這句話的意思爲,當主要的 js 文件都加載完成以後,這時就是網絡帶寬有空閒的時候,那麼 webpack 機會偷偷的在這個時間段,把 ./click.js 文件給加載好。

這裏說到的是 prefetch ,但其實咱們也能夠把 webpackPrefetch 改爲 webpackPreloadpreloadprefetch 的區別在於: preload 是跟主文件同時進行加載,而不是在主文件加載完才加載的。通常來講,咱們都用 prefetch , 只有等主文件把活幹完了,再來加載剩餘的咱們想要的文件,這樣的邏輯和對頁面的優化纔是比較完美的。

綜上,原先咱們打包像 jQuerylodash 之類的庫時,只須要在第一次訪問的時候加載,而等到第二次訪問的時候,咱們就能夠藉助緩存,提升訪問的速度。但這種方式也只是提升第二次訪問的速度,而咱們想要實現的是,當第一次訪問的時候, webpack 就可使得頁面的加載速度是最快的。

因此最終咱們使用了 preloadprefetch 這兩種實現方式來解決這個問題。

🏏5、CSS文件的代碼分割

1. css文件代碼分割

上面咱們講到了 js 文件如何進行代碼分割,如今,咱們來說 css 文件,如何進行代碼分割。對於 css 文件的代碼分割來講,咱們要引用到官方文檔中提到的一個插件: MiniCssExtractPlugin 。接下來咱們來看一下這個插件如何使用。

第一步: 安裝插件。具體命令以下:

npm install --save-dev mini-css-extract-plugin
複製代碼

第二步: 在開發環境和線上環境中使用。咱們打開 webpack.common.js 文件,引入該插件並使用。具體代碼以下:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
	entry:{
		main: './src/index.js'
	},
    module:{
		rules:[{
			test:/\.scss$/,
			use:[
				MiniCssExtractPlugin.loader, 
				{
					loader: 'css-loader',
					options: {
						//代表前面要先走sass-loader和postcss-loader
						importLoaders: 2,
						modules: true
					}
				}, 
				'sass-loader',
				'postcss-loader'
			]
		},{
			test:/\.css$/,
			use:[
				MiniCssExtractPlugin.loader,
				'css-loader',
				'postcss-loader'
			]
		}]
	},
    plugins: [
		new MiniCssExtractPlugin({
			// 若是文件被直接引用,走filename
			filename: '[name].css',
			// 若是文件被間接的引用,那麼走chunkFilename
			chunkFilename: '[name].chunk.js'
		})
	],
	optimization: {
		//使用treeShaking
		usedExports: true,
		splitChunks: {
			chunks: 'all',
			cacheGroups: {
				vendors: false,
				default: false
			}
		}
	  }
}
複製代碼

第三步: 配置 package.json 文件。具體代碼以下:

{
  "sideEffects": [
    //表示不對css文件開啓treeShaking
    "*.css"
  ]
}
複製代碼

2. 壓縮css文件

對於打包後的css文件,其大小仍是比較大的,因此咱們須要對文件大小進行壓縮。這該怎麼處理呢?

**第一步:**安裝插件。具體命令以下:

npm install optimize-css-assets-webpack-plugin -D
複製代碼

第二步: 在開發環境和線上環境中使用。咱們打開 webpack.common.js 文件,引入該插件並使用。具體代碼以下:

const CssMinimizerPlugin = require("optimize-css-assets-webpack-plugin");

module.exports = {
    optimization: {
        minimizer: [new OptimizeCSSAssetsPlugin({})]
    }
}
複製代碼

3. 合併打包css文件

有時候,咱們可能會有不少個入口文件,每一個入口文件又都有其對應的若干個 css 文件。那麼這個時候咱們想把全部的 css 文件,都打包到同一個文件下,該怎麼處理呢?

咱們須要在 webpack.common.js 進行配置,具體代碼以下:

module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        styles: {
          name: "styles",
          test: /\.css$/,
          chunks: "all",
          enforce: true,
        },
      },
    },
  }
}
複製代碼

經過以上代碼,咱們能夠了解到,咱們須要在 splitChunks 中額外配置一個 stylescacheGroups ,將全部的 css 文件打包到一個 命名爲 styles 的文件夾下。

🏑6、webpack與瀏覽器緩存

1. 瀏覽器緩存配置

當咱們剛訪問網站時,第一次加載老是須要從零開始加載各類文件的,而假設咱們的代碼沒有更新時,咱們但願再次加載時能夠從瀏覽器中直接拉取緩存,而不是從新進行加載。而等到咱們的代碼發生更新時,再從新加載網頁。那這該怎麼處理呢?

第一步: 配置開發環境 webpack.dev.js 文件。具體代碼以下:

const devConfig = {
    output: {
		filename: '[name].js',
		chunkFilename: '[name].chunk.js',
	}
}
複製代碼

第二步: 配置生產環境 webpack.prod.js 文件。具體代碼以下:

const prodConfig = {
    output: {
		filename: '[name].[contenthash].js',
		chunkFilename: '[name].[contenthash].js',
	}
}
複製代碼

以上的代碼旨在解決的問題是,當在線上環境時,對輸出的文件加一個哈希值。這個時候,若是咱們的代碼有發生改變時,webpack就會生成一個新的哈希值,網頁就會進行更新。若是咱們的代碼沒有發生改變,那麼這個哈希值仍是同樣的不會改變,網頁就會從瀏覽器中拉取內存信息,進行加載。

2. 解決舊版本問題

以上內容呢,若是發生在一些比較低的 webpack 版本,是不能生效的。因此咱們須要進行一個配置,來兼容低版本問題。咱們在 webpack.common.js 下進行配置,具體代碼以下:

module.exports = {
    optimazation: {
       	runtimeChunk: {
        	name: 'runtime'
    	} 
    }
}
複製代碼

⚾7、Shimming的做用

1. Shimming墊片

繼續,如今咱們來了解一下在 webpack 中, shimming ,即墊片的概念。

webpack 的打包過程當中呢,咱們每每要作一些代碼上或者打包過程上的兼容。

好比,對於兩個 js 文件來講,模塊和模塊之間是相互獨立的,他們之間是沒有耦合度的。假設咱們如今有兩個文件,具體代碼以下:

jquery.ui.js:

export function ui(){
    $('body').css('background', 'red');
}
複製代碼

index.js:

import _ from 'lodash';
import $ from 'jquery';

import { ui } from './jquery.ui';

ui();

const dom = $('<div>');
dom.html(_.join(['Mondady', 'Tuesday']), '~');
$('body').append(dom);

複製代碼

你們能夠看到,如今咱們想要在 index.ui.js 文件中引入 $ ,可是在這個文件中,它並無引入 jquery 這個庫。因此,若是就這樣子直接運行,是確定的會報錯的。

所以,若是咱們想要解決這個問題,該怎麼進行配置呢?

下面咱們將對 webpack.common.js 進行配置。具體代碼以下:

const webpack = require('webpack');

module.exports = {
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            //'_': 'lodash',
            //_join: ['lodash', 'join']
        })
    ]
}
複製代碼

因此,這間接的能夠理解爲,拿點東西把 $ 墊上,也就有了咱們標題說的 shimming ,墊片的概念。

2. this指向

對於項目中的文件來講,其 this 的指向都是指向模塊自己,而不是指向全局。那咱們若是想讓項目中的全部 js 文件都指向全局,該怎麼處理呢?

第一步: 安裝 loader具體命令以下:

npm install imports-loader --save-dev
複製代碼

第二步: 配置 webpack.common.js具體代碼以下:

module.exports = {
    module: {
        rules: [{
			test: /\.m?js$/,
			exclude: /node_modules/,
			use: [{
				loader: "babel-loader",
			},{
				loader: 'imports-loader?this=>window'
			}]
		  }]
    }
}
複製代碼

經過配置 imports-loader 之後, webpack 代表,它將會把 js 文件中的 this 指向所有指向 window 全局中。

🎖️8、結束語

在今天的文章中,咱們學習了使用 Tree Shaking 來優化代碼的打包大小,同時,學習了 DevProd 環境下的區分打包,須要明確在這兩個模式下各自相同的配置以及不一樣的配置,分清楚他們之間的關係。

除此以外呢,咱們還學會了使用 webpack 來對 js 文件和 css 文件進行代碼分割。以及使用 webpack 來對代碼進行打包分析和提早加載 preloading

最後,咱們還學會了關於 webpack 如何開啓瀏覽器緩存,以及墊片 Shimming 的做用。

關於 webpack 的基礎特性和高級特性講到這裏就結束啦!但願對你們有幫助~

若有疑問或文章有誤歡迎小夥伴們評論區留言呀~💬

本系列文章代碼已上傳至公衆號,後臺回覆關鍵詞 webpack 便可獲取~

🐣彩蛋 One More Thing

(:往期推薦

👉webpack基礎知識系列

👉vuejs基礎知識系列

(:番外篇

🙃 關注公衆號星期一研究室,第一時間關注優質文章,更多精選專欄待你解鎖~

🙃 若是這篇文章對你有用,記得留個腳印jio再走哦~

🙃 以上就是本文的所有內容!咱們下期見!👋👋👋

相關文章
相關標籤/搜索