webpack 本質上是一個打包工具,它會根據代碼的內容解析模塊依賴,幫助咱們把多個模塊的代碼打包。javascript
開始接觸
wbpack
是在vue-cli
腳手架中,用於打包、壓縮以及一些各個環境的配置,當初花了些時間來研究它,發現裏面的可配置項仍是不少的。最近面試中也有問到過關於webpack
的配置,今天從新把筆記中的記錄結合官網最新的API
作了一個整理,以備後續查閱!css
webpack官網地址html
entry
入口:用來指定一個入口起點(或多個入口起點),進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。前端
module.exports = {
entry: './src/index.js'
}
複製代碼
output
輸出:
output
屬性告訴webpack
在哪裏輸出它所建立的bundles
,以及如何命名這些文件,默認值爲./dist
。基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中。你能夠經過在配置中指定一個output
字段,來配置這些處理過程。vue
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
複製代碼
loader
解析器:讓
webpack
可以去處理那些非 JavaScript 文件(webpack
自身只理解JavaScript
),將全部類型的文件轉換爲webpack
可以處理的有效模塊,而後你就能夠利用webpack
的打包能力,對它們進行處理。java
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
'css-loader'
]
},
{
test:/\.(png|svg|jpg|gif)$/,
use:[
'file-loader'
]
},
{
test:/\.(woff|woff2|eot|ttf|otf)/,
use:[
'file-loader'
]
},
{
test:/\.(csv|tsv)$/,
use:[
'csv-loader'
]
},
{
test:/\.xml$/,
use:[
'xml-loader'
]
}
]
}
};
複製代碼
plugins
插件:
plugins
並非直接操做單個文件,它直接對整個構建過程起做用下面列舉了一些咱們經常使用的plugins
和他的用插件的範圍包括,從打包優化和壓縮,一直到從新定義環境中的變量。插件接口功能極其強大,能夠用來處理各類各樣的任務,例如開啓gzip
壓縮,開發環境去掉警告,debugger
,console
註釋等。node
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
// 插件管理,需先進行引入,再使用
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
};
複製代碼
webpack
的配置以及使用:此處省略了官網的一步步下載
loader
包並配置的過程,如需看詳細的版本能夠移步到官網詳細查閱。 當前版本webpack@4.40.2
webpack-cli@3.3.9
webpack
關於webpack的下載和初始化:ios
<!--初始化package.json-->
npm init -y
<!--下載webpack-->
npm install webpack webpack-cli --save-dev
複製代碼
初始化後的目錄以下:git
每一個文件裏的具體代碼以下:
package.json:
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
// 此處配置的build ,可在後期用 npm run build 直接運行壓縮打包
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^3.2.0",
"csv-loader": "^3.0.2",
"file-loader": "^4.2.0",
"style-loader": "^1.0.0",
"webpack": "^4.40.2",
"webpack-cli": "^3.3.9",
"xml-loader": "^1.2.1"
},
"dependencies": {
"lodash": "^4.17.15"
}
}
複製代碼
index.html
前臺頁面:
<!doctype html>
<html>
<head>
<title>起步</title>
</head>
<body>
<!--這個bundle.js就是咱們打包後的js壓縮文件,配置在webpack.config.js中-->
<script src="bundle.js"></script>
</body>
</html>
複製代碼
index.js
:
import _ from 'lodash';
import './style.css';
import Img from './img.jpg';
import Data from './data.xml'
function component() {
var element = document.createElement('div');
element.innerHTML = _.join(['Hello', 'webpack!'], ' ');
return element;
}
document.body.appendChild(component());
複製代碼
webpack.config.js
配置頁面:
const path = require('path');
module.exports = {
<!--這裏是入口-->
entry: './src/index.js',
<!--這裏是壓縮後的導出-->
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
<!--這裏是咱們下載的loader,不一樣格式的文件處理-->
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
'css-loader'
]
},
{
test:/\.(png|svg|jpg|gif)$/,
use:[
'file-loader'
]
},
{
test:/\.(woff|woff2|eot|ttf|otf)/,
use:[
'file-loader'
]
},
{
test:/\.(csv|tsv)$/,
use:[
'csv-loader'
]
},
{
test:/\.xml$/,
use:[
'xml-loader'
]
}
]
}
};
複製代碼
接下來你須要下載package
裏面的依賴:
cnpm install
複製代碼
執行壓縮:
npm run build
複製代碼
而後打開index.html
能夠看到以下頁面:
好了到這裏咱們能夠正常顯示頁面了,那接下來能夠再添加一些其餘文件,css
,img
,data
來壓縮試試:
style.css:
.hello{
color:red;
font-family: 'MyFont';
background:url('./img.jpg');
}
複製代碼
index.js
import _ from 'lodash';
import './style.css';
import Img from './img.jpg';
import Data from './data.xml'
function component() {
var element = document.createElement('div');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
// 添加css
element.classList.add('hello');
// 將圖像添加到咱們現有到div
var myImg =new Image();
myImg.src = Img;
element.appendChild(myImg)
// 添加數據
console.log(Data)
return element;
}
document.body.appendChild(component());
複製代碼
而後再執行壓縮,查看結果:
壓縮後的文件:
頁面展現:
到目前爲止,咱們實現了將打包都壓縮到一個文件中,可是若是是大型項目中的話,這樣是不可取的,接下來咱們配置分別將不一樣文件壓縮並輸出不一樣的文件。
HtmlWebpackPlugin
( 配置多個文件分別打包 )新建一個
print.js
文件在src
中
npm install --save-dev html-webpack-plugin
複製代碼
webpack.config.js
配置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入
module.exports = {
// 配置多入口
entry: {
app:'./src/index.js',
print:'./src/print.js'
},
//分別打包成不一樣名稱的js文件
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
// 配置plugins模塊
plugins:[
new HtmlWebpackPlugin({
title:'Output Management'
})
]
};
複製代碼
執行打包,而後打開
index.html
,你就會看到HtmlWebpackPlugin
建立了一個全新的文件,全部的bundle
會自動添加到html
中。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Output Management</title>
</head>
<body>
<!--我當前只打包了這兩個文件,plugins就幫我都引入到了index.html-->
<script type="text/javascript" src="app.bundle.js"></script>
<script type="text/javascript" src="print.bundle.js"></script>
</body>
</html>
複製代碼
打包到dist 文件下
clean-webpack-plugin
( 每次打包清理dist文件夾 )一般,在每次構建前清理
/dist
文件夾,也是比較推薦的作法。
npm install clean-webpack-plugin --save-dev
複製代碼
webpack.config.js
配置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
/*
*此處有坑,在webpack的中文文檔中這裏的引入方式仍是原來的方式
*const CleanWebpackPlugin = require('clean-webpack-plugin');
*如下是正確的引入方式,小夥伴們請注意哦!
*/
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management'
})
]
};
複製代碼
執行後看到,咱們到dist文件中除了index.html 和咱們打包到兩個文件,就沒有了其餘冗餘的文件了。
當
webpack
打包源代碼時,可能會很難追蹤到錯誤和警告在源代碼中的原始位置。例如,若是將三個源文件(a.js, b.js 和 c.js)
打包到一個bundle(bundle.js)
中,而其中一個源文件包含一個錯誤,那麼堆棧跟蹤就會簡單地指向到bundle.js
。這並一般沒有太多幫助,由於你可能須要準確地知道錯誤來自於哪一個源文件。source map
就提供了這個功能。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
// 配置 source-map
devtool: 'inline-source-map',
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management'
})
]
};
複製代碼
src/print.js
中手動添加一條錯誤
export default function printMe() {
cosnole.error('I get called from print.js!');
}
複製代碼
打開index頁面定位錯誤信息:
webpack-dev-server
熱加載如今咱們每次修改完內容,還須要用
npm run build
執行纔會進行打包,這用起來很麻煩,那咱們有沒有方法,改變後直接從新打包並刷新頁面呢?有的!
npm install --save-dev webpack-dev-server
複製代碼
在package.json
中的script
中配置腳本命令,用於開啓熱加載:
"start": "webpack-dev-server --open",
複製代碼
webpack.config.js
配置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
app: './src/index.js'
},
devtool: 'inline-source-map',
// 添加熱加載
devServer: {
contentBase: './dist',
hot: true
},
// 配置css loader,用來後面測試熱加載使用
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management'
}),
//啓動 HMR
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
};
複製代碼
index.js:
import _ from 'lodash';
import printMe from './print.js';
// 添加一個css樣式,並引入進來
import './style.css'
function component() {
var element = document.createElement('div');
var btn = document.createElement('button');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
btn.innerHTML = 'Click me and check the console!';
btn.onclick = printMe;
element.appendChild(btn);
return element;
}
document.body.appendChild(component());
// 添加熱更新,以便當 print.js 內部發生變動時能夠告訴 webpack 接受更新的模塊
if (module.hot) {
module.hot.accept('./print.js', function () {
console.log('Accepting the updated printMe module!');
printMe();
})
}
複製代碼
執行熱加載命令:
npm start
開啓熱加載,而後手動更改style.css
中的樣式,頁面會自 動更新,此時就已經完成了webpack
的最基礎的配置。
上面咱們介紹了非項目中的
webpack
配置,這一講咱們來試着在vue
項目中配置一下webpack
,看看有哪些注意事項。
首先在Vue腳手架的項目中,咱們搭建完成後便可生成如下目錄:
項目中的自帶webpack
版本爲: "^3.6.0"
分別有以下三個文件:
1. webpack.base.conf.js
webpack
的基礎文件,裏面用於配置一些關於webpack的基礎屬性。
2. webpack.dev.conf.js
webpack
關於開發環境下的配置文件。
3. webpack.prod.conf.js
webpack
關於生產環境下的配置文件。
接下來分享些我項目中的基礎配置:
babel-polyfill
entry: {
// 來解析es6的特性
app: ['babel-polyfill', './src/main.js']
}
複製代碼
resolve
resolve: {
// 用於設置自動添加後綴的順序
extensions: ['.js', '.vue', '.json'],
// alias能夠映射文件也能夠映射路徑,用於模塊別名,方便後續直接引用別名,例如:@ 表示默認src層
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
},
// 避免新增默認文件,編碼時使用詳細的文件路徑,代碼會更容易解讀,也有益於提升構建速度
mainFiles: ['index']
}
複製代碼
loader
之 ExtractTextPlugin
( 抽離css
樣式 )
ExtractTextPlugin
該插件的主要是爲了抽離css
樣式,防止將樣式打包在js
中引發頁面樣式加載錯亂的現象,會單獨打一個css
的包出來。這樣帶來的好處還有,分離出來的css
和js
是能夠並行下載的,這樣能夠更快地加載樣式和腳本。
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['vue-style-loade','css-loader','less-loader', 'postcss-loader'],
}),
exclude: /node_modules/,
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader?modules', 'less-loader', 'postcss-loader'],
}),
}
複製代碼
plugins: [
new ExtractTextPlugin("styles.css")
]
複製代碼
loader
之減小loader 編譯範圍 exclude
、include
include 表示哪些目錄中的 .js 文件須要進行 babel-loader
exclude 表示哪些目錄中的 .js 文件不要進行 babel-loader
咱們在使用 loader 的時候,儘量把 loader 應用的文件範圍縮小,只在最少數必須的代碼模塊中去使用必要的 loader,例如 node_modules 目錄下的其餘依賴類庫文件,基本就是直接編譯好可用的代碼,無須再通過 loader 處理了:
exclude
:
{
test: /\.(js|vue|jsx)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
enforce: 'pre',
options: {
fix: true
}
}
複製代碼
include
:
{
test: /\.js$/,
use: [{
loader: 'babel-loader'
},
{
loader: 'iview-loader',
options: {
prefix: false
}
}
],
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client'), resolve('node_modules/iview/src')]
複製代碼
webpack.base.conf.js
基礎配置文件:'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
// 配置babel-polyfill 來解析es6的特性
app: ['babel-polyfill', './src/main.js']
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
// 其餘解決方案
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
},
mainFiles: ['index']
},
module: {
rules: [
{
test: /\.vue$/,
use: [{
loader: 'vue-loader',
options: vueLoaderConfig
},
{
loader: 'iview-loader',
options: {
prefix: false
}
}]
},
{
test: /\.js$/,
use: [{
loader: 'babel-loader'
},
{
loader: 'iview-loader',
options: {
prefix: false
}
}
],
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client'), resolve('node_modules/iview/src')]
},
// ExtractTextPlugin 用於將css文件從js文件中拆出來,單獨打成一個包,
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['vue-style-loade','css-loader','less-loader', 'postcss-loader'],
}),
exclude: /node_modules/,
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader?modules', 'less-loader', 'postcss-loader'],
}),
},
// 把小於limit閥值大小的圖片轉爲base64字符串
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
},
{
test: /\.(js|vue|jsx)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
enforce: 'pre',
options: {
fix: true
}
}
]
},
plugins: [
/**
* 將樣式提取到單獨的css文件,而不是內嵌到打包的js文件中。
* 這樣帶來的好處時分離出來的css和js是能夠並行下載的,
* 這樣能夠更快地加載樣式和腳本。
*/
new ExtractTextPlugin("styles.css"),
// 清空輸出文件夾以前的輸出文件
new CleanWebpackPlugin(),
],
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native). setImmediate: false, // prevent webpack from injecting mocks to Node native modules // that does not make sense for the client dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' } } 複製代碼
webpack.dev.conf.js
開發環境配置文件:'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const OpenBrowserPlugin = require('open-browser-webpack-plugin')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
// 將基本配置合併到開發環境
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
// vue run dev後自動打開瀏覽器插件
new OpenBrowserPlugin({url: 'http://localhost:8080' }),
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
// 模塊熱替換,無需整個刷新頁面
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
// 拷貝插件
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
]),
// 去除依賴中重複的插件
new webpack.optimize.DedupePlugin() ,
/**
* 爲組件分配ID,經過這個插件webpack能夠分析和優先考慮使用最多的模塊,
* 併爲它們分配最小的ID
*/
new webpack.optimize.OccurrenceOrderPlugin()
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
複製代碼
webpack.prod.conf.js
生產環境的配置文件:'use strict'
const version = require('../package.json').version || '';
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const zip = require('zip-webpack-plugin')
const env = require('../config/prod.env')
// 將基本配置合併到生產環境
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
// 對js文件進行壓縮
new UglifyJsPlugin({
extractComments: {
// 根據條件保存須要保留的註釋
condition: function (a, data) {
return /app.\w+.js$/.test(data.file);
},
//存儲提取的註釋的文件名調用
banner: 'version:' + version,
},
// 部分格式化,根據須要配置
uglifyOptions: {
compress: {
warnings: false, // 自動刪除警告
drop_console: true, // 自動刪除console.log
typeofs: false, //將typeof foo==「未定義」轉換爲foo==void 0。注意:對於IE10和早期版本有問題。
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
// 將css 提取到本身的文件中
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks(module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
// CommonsChunkPlugin:提取通用模塊文件,vue vuex vue-router axios
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// 拷貝插件
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
]),
// 打成zip包,通常用於上線
new zip({
path: './',
filename: `frame-fe.zip`
}),
/**
* 將原來的 chunk 分紅更小的 chunk
* 直到各個 chunk 的大小達到 option 設置的 maxSize
*/
new webpack.optimize.AggressiveSplittingPlugin({
minSize: 30000,
maxSize: 50000
}),
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// 開啓gzip壓縮 gzip能在本來壓縮的基礎上再進行壓縮50%以上!!!
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
複製代碼
編寫時間緊張,內容稍有粗糙,正在改進中,請見諒!
還有些參考文獻當時忘記保存,後續會陸續添加上,感謝閱讀!
郵箱:christine_lxq@sina.com
未完待續.....做者:Christine
出處:https://juejin.im/user/594c9772128fe10065110aa5/posts
版權全部,歡迎保留原文連接進行轉載:但願看到個人最新文章的能夠添加下關注哦!:)
複製代碼