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
版权全部,欢迎保留原文连接进行转载:但愿看到个人最新文章的能够添加下关注哦!:)
复制代码