优雅webpack4
http://vlambda.com/wz_xetaQRp1gl.html
https://vue-loader-v14.vuejs.org/zh-cn/configurations/advanced.html
vue-cli直接搭建一个项目 不想从零开始
**、进入你的项目目录,创建一个基于 webpack 模板的新项目: vue init webpack 项目名**
说明:
Vue build ==> 打包方式,回车即可;
Install vue-router ==> 是否要安装 vue-router,项目中肯定要使用到 所以Y 回车;
Use ESLint to lint your code ==> 是否需要 js 语法检测 目前我们不需要 所以 n 回车;
Set up unit tests ==> 是否安装 单元测试工具 目前我们不需要 所以 n 回车;
Setup e2e tests with Nightwatch ==> 是否需要 端到端测试工具 目前我们不需要 所以 n 回车;
1、build:构建脚本目录
1)build.js ==> 生产环境构建脚本;``
2)check-versions.js ==> 检查npm,node.js版本;
3)utils.js ==> 构建相关工具方法;
4)vue-loader.conf.js ==> 配置了css加载器以及编译css之后自动添加前缀;
5)webpack.base.conf.js ==> webpack基本配置;
6)webpack.dev.conf.js ==> webpack开发环境配置;
7)webpack.prod.conf.js ==> webpack生产环境配置;
2、config:项目配置
1)dev.env.js ==> 开发环境变量;
2)index.js ==> 项目配置文件;
3)prod.env.js ==> 生产环境变量;
3、node_modules:npm 加载的项目依赖模块
4、src:这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:
1)assets:资源目录,放置一些图片或者公共js、公共css。这里的资源会被webpack构建;
2)components:组件目录,我们写的组件就放在这个目录里面;
3)router:前端路由,我们需要配置的路由路径写在index.js里面;
4)App.vue:根组件;
5)main.js:入口js文件;
5、static:静态资源目录,如图片、字体等。不会被webpack构建
6、index.html:首页入口文件,可以添加一些 meta 信息等
7、package.json:npm包配置文件,定义了项目的npm脚本,依赖包等信息``
8、README.md:项目的说明文档,markdown 格式
9、.xxxx文件:这些是一些配置文件,包括语法配置,git配置等
npm init -Y
yarn add webpack -D
yarn add webpack-cli -D
yarn add webpack-dev-server -D webpack开发配置
yarn add webpack-merge -D 配置合并
创建相应文件
vueProject
|-build
|--weboack.base.js
|--webpack.dev.js
|--webpack.prod.js
|-src
|--index.js
|--app.vue
|-index.html
const path = require("path")
module.exports = {
entry: {
app: "./src/index.js"
},
plugins: [],
module: {
rules: [
]
}
}
const path = require("path")
const basic = require("./webpack.base")
const {merge} = require("webpack-merge")
module.exports = merge(basic,{
mode:"development",
devtool:"inline-source-map", //生产环境不用
plugins:[],
module:{
rules:[]
}
})
const path = require("path")
const basic = require("./webpack.base")
const {merge} = require("webpack-merge")
module.exports = merge(basic,{
mode:"production",// 生产环境,默认开启相关插件,可删除未引用代码,压缩代码等
devtool:"#source-map",
plugins:[],
module:{
rules:[]
}
})
yarn add vue
**index.js**
import Vue from "vue"
import App from "./app.vue"
new Vue({
el: '#app',
render: h => h(App),
});
hello world
安装 node-sass sass-loader css-loader 用来编译css scss
注: 可能yarn不能安装的话使用cnpm
前端从零搭建Vue2+Webpack4
初始化到此结束
编译Vue模板以及开发环境下生成html
webpack.dev.js
plugins: [
new HtmlWebpackPlugin()
],
webpack.base.js
const VueLoaderPlugin = require('vue-loader/lib/plugin');
+plugins: [
+ new VueLoaderPlugin()
],
module: {
rules: [
+ {
+ test: /\.vue$/,
+ loader: 'vue-loader'
+ }
]
}
"scripts": {
"start": "webpack-dev-server --hot --open --config build/webpack.dev.js",
"build": "webpack --config build/webpack.prod.js"
}
此时可以启动一个网页为hello world为主题的一个页面
const path = require("path")
const basic = require("./webpack.base")
const { merge } = require("webpack-merge")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = merge(basic, {
mode: "production",// 生产环境,默认开启相关插件,可删除未引用代码,压缩代码等
devtool: "#source-map",
plugins: [
+ new HtmlWebpackPlugin({
+ filename:path.resolve(__dirname, +'../dist/index.html'),
+ template: 'index.html',
+ })
],
module: {
rules: []
},
+ output: {
+ filename: '[name].[contenthash].js', //contenthash 若文件内容无变化,则contenthash 名称不变
+ path: path.resolve(__dirname, '../dist')
},
})
至此打包的html文件 没有任何图片 css
见其他markdown文档
`
_import_development.js
module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+
_import_production.js
module.exports = file => () => import('@/views/' + file + '.vue')
`
import Vue from "vue"
import Router from "vue-router"
const _import = require('./_import_' + process.env.NODE_ENV)
Vue.use(Router)
// 不需要权限都能看到的
export const constantRouterMap = [
{
path: '/login',
component: _import('login/index'),
hidden: true
},
{
path:"/",
component:_import("home/index")
}
]
const router = new Router({
// mode: 'history', // require service support
mode: 'hash',
scrollBehavior: () => ({
y: 0
}),
routes: constantRouterMap
})
export default router
// 需要权限的路由表
export const asyncRouterMap = [
]
配置别名
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
module.exports={
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
}
},
}
scss css转换
参考开发环境配置rules
JS ES6->ES5
cnpm install -D babel-loader @babel/core @babel/preset-env
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [resolve('src')]
},
或者
// -- babel8.0
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader?cacheDirectory',支持缓存
options: {
presets: ['@babel/preset-env']
}
}
}
https://segmentfault.com/a/1190000017898866?utm_source=tag-newest
注“在webpack打包的时候,可以在js文件中混用require和export。但是不能混用import 以及module.exports。
解决: npm install babel-plugin-transform-es2015-modules-commonjs
然后在 babelrc文件中配置
{ “plugins”: [“transform-es2015-modules-commonjs”] }
分离css 写在生产环境下 开发环境不支持热更新
webpack3
cnpm i extract-text-webpack-plugin@next -D // 加上@next是为了安装最新的,否则会出错
const ExtractTextPlugin = require('extract-text-webpack-plugin') //引入分离插件
plugins: [
new VueLoaderPlugin(),
+ new ExtractTextPlugin('css/index.css') // 将css分离到/dist文件夹下的css文件夹中的index.css
],
webpack4
cnpm install mini-css-extract-plugin -D
- { loader: 'style-loader' }
+ MiniCssExtractPlugin.loader
new MiniCssExtractPlugin({
filename: devMode ? '[name].css' : 'css/[name].[hash:7].css',
chunkFilename: devMode ? '[id].css' : 'css/[id].[hash:7].css',
ignoreOrder: false
}),
**3.消除冗余css **暂不使用
cnpm i purifycss-webpack purify-css glob -D
安装完上述三个模块后,因为正常来说是在生产环境中优化代码,所以我们应该是在webpack.prod.js文件中进行配置,引入clean-webpack-plugin及glob插件并使用它们:
const PurifyCssWebpack = require('purifycss-webpack'); // 引入PurifyCssWebpack插件
const glob = require('glob'); // 引入glob模块,用于扫描全部html文件中所引用的css
new CleanWebpackPlugin(['dist']), // 所要清理的文件夹名称
new PurifyCssWebpack({
paths: glob.sync(path.join(__dirname, 'src/*.html')) // 同步扫描所有html文件中所引用的css
})
postcss-pxtorem
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-cssnext')(),
require('cssnano')(),
require('postcss-pxtorem')({
rootValue: 100,
propWhiteList: []
})
]
}
},
require('postcss-pxtorem')({
rootValue: 75,
unitPrecision: 5,
propList: ['*'],
selectorBlackList: [],
replace: true,
mediaQuery: false,
minPixelValue: 12
})
[](javascript:void(0)
假设设计稿750宽;
rootValue为75,说是对根元素大小进行设置.
unitPrecision为5,是转换成rem后保留的小数点位数.
selectorBlackList则是一个对css选择器进行过滤的数组,比如你设置为[‘fs’],那例如fs-xl类名,里面有关px的样式将不被转换,
这里也支持正则写法。
minPixelValue的选项,我设置了12,意思是所有小于12px的样式都不被转换.
propList是一个存储哪些将被转换的属性列表,这里设置为[’’]全部,假设需要仅对边框进行设置,可以写[’’, ‘!border*’]意思是排除带有border的属性.
1、scss css转换 放在base.config也可
// use的顺序从右往左
module: {
rules: [
{
test: /\.(sc|sa|c)ss$/,
use: [
{ loader: 'style-loader' }, {
loader: 'css-loader', options: {
sourceMap: true //为了映射文件
}
}, {
loader: "sass-loader", options: {
sourceMap: true
}
}]
}
]
}
postcss 增加前缀等
https://segmentfault.com/a/1190000004592944
安装好这两个模块后,在项目根目录下新建postcss.config.js文件:
module.exports = {
parser: 'postcss-scss',
plugins: [
require('autoprefixer') // 引用autoprefixer模块
]
}
修改webpack.common.js文件中的css-loader配置:
{loader: 'postcss-loader',options: {
sourceMap: true,
config: {
path: 'postcss.config.js'
}
}} // 使用postcss-loader
package.json
"browserslist": [
"defaults",
"not ie < 11",
"last 2 versions",
"> 1%",
"iOS 7",
"last 3 iOS versions"
]
图片转换
{
test: /\.(png|jpg|svg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 1000, // 限制只有小于1kb的图片才转为base64,例子图片为1.47kb,所以不会被转化
outputPath: 'images' // 设置打包后图片存放的文件夹名称
}
}
]
},
1、 CleanWebpackPlugin 在每次构建前清理
/dist文件夹
npm install clean-webpack-plugin --save-dev
+ const CleanWebpackPlugin = require('clean-webpack-plugin');
new CleanWebpackPlugin(),
npm i optimize-css-assets-webpack-plugin -D
2、引入及配置
// webpack.pord.config.js
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
// 普通压缩
plugins: [
new OptimizeCSSAssetsPlugin ()
]
// 使用cssnano配置规则
// 先 npm i cssnano -D
plugins: [
new OptimizeCSSAssetsPlugin ({
// 默认是全部的CSS都压缩,该字段可以指定某些要处理的文件
assetNameRegExp: /\.(sa|sc|c)ss$/g,
// 指定一个优化css的处理器,默认cssnano
cssProcessor: require('cssnano'),
cssProcessorPluginOptions: {
preset: [ 'default', {
discardComments: { removeAll: true}, //对注释的处理
normalizeUnicode: false // 建议false,否则在使用unicode-range的时候会产生乱码
}]
},
canPrint: true // 是否打印编译过程中的日志
})
]
注意,这样配置会存在只有css压缩的问题,这时webpack4原本自己配置好的js压缩会无效 ,需要重新配置UglifyJsPlugin(用于压缩js,webpack4内置了)一下
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true, // Boolean/String,字符串即是缓存文件存放的路径
parallel: true, // 启用多线程并行运行提高编译速度
sourceMap: true
/*
uglifyOptions: {
output: {
comments: false // 删掉所有注释
},
compress: {
warning: false, // 插件在进行删除一些无用的代码时不提示警告
drop_console: true // 过滤console,即使写了console,线上也不显示
}
} */
}),
new OptimizeCSSAssetsPlugin({})
]
}
作者:前端girl吖
链接:https://www.jianshu.com/p/dd9afa5c4d0f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
css转换
{
test: /\.(sc|sa|c)ss$/,
use: [
// { loader: 'style-loader' }
{
loader: MiniCssExtractPlugin.loader
}, {
loader: 'css-loader',
options: {
sourceMap: true
}
}, {
loader: 'postcss-loader',
options: {
sourceMap: true,
config: {
path: 'postcss.config.js'
}
}
}, // 使用postcss-loader
{
loader: "sass-loader",
options: {
sourceMap: true
}
}]
}
一些 css loader
npm install css-loader style-loader less less-loader node-sass sass-loader postcss-loader autoprefixer --save -dev
1
图片 loader
npm i file-loader --save-dev
1
我的安装版本
"autoprefixer": "^9.7.3",
"css-loader": "^3.4.0",
"file-loader": "^5.0.2",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"node-sass": "^4.13.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.1.2",
123456789
在根目录下创建== postcss.config.js ==文件
// 自动添加css兼容属性
const autoprefixer = require('autoprefixer');
module.exports = {
plugin: [
autoprefixer
]
}
1234567
在== webpack.base.js ==文件中添加 loader 代码
module.exports = {
entry: './src/index.js',
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
limit: 5000,
// 分离图片至imgs文件夹
name: 'imgs/[name].[ext]'
}
},
// 图片压缩
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false
}
}
}
]
}
]
},
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
npm install clean-webpack-plugin --save -dev
1
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new CleanWebpackPlugin(),
],
12345
npm install mini-css-extract-plugin --save -dev
1
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = merge(common, {
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.less$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},
'css-loader',
'postcss-loader',
'less-loader'
]
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].[hash].css',
chunkFilename: 'css/[id].[hash].css'
})
],
})
12345678910111213141516171819202122232425262728293031
npm install image-webpack-loader --save -dev
1
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
limit: 5000,
name: "imgs/[hash].[ext]",
}
},
// 图片压缩
{
loader: 'image-webpack-loader',
options: {
// bypassOnDebug: true,
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false,
}
},
}
}
1234567891011121314151617181920212223242526272829303132
npm install happypack --save -dev
1
const HappyPack = require('happypack')
const os = require('os')
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })
rules: [
{
test: /\.js$/,
loader: 'happypack/loader?id=happyBabel',
exclude: /node_modules/
},
]
plugins: [
new HappyPack({
//用id来标识 happypack处理类文件
id: 'happyBabel',
//如何处理 用法和loader 的配置一样
loaders: [
{
loader: 'babel-loader?cacheDirectory=true'
}
],
//共享进程池
threadPool: happyThreadPool,
//允许 HappyPack 输出日志
verbose: true
})
]
123456789101112131415161718192021222324252627
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'vendor',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // 只打包初始时依赖的第三方
}
}
}
}
12345678910111213
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
optimization: {
minimizer: [
// 压缩js
new TerserJSPlugin({}),
// 压缩css
new OptimizeCSSAssetsPlugin({})
]
},
12345678910
支持 vue-router 路由懒加载
安装 babel 插件
npm install --save-dev @babel/plugin-syntax-dynamic-import
1
新建.babelrc 文件
{
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
不配置任何选项的html-webpack-plugin插件,他会默认将webpack中的entry配置所有入口thunk和extract-text-webpack-plugin抽取的css样式都插入到文件指定的位置。
html-webpack-plugin配置项
template: path.join(__dirname, 'default_index.ejs'),
filename: 'index.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: [],
title: 'Webpack App',
xhtml: false
title
: 生成的html文档的标题。配置该项,它并不会替换指定模板文件中的title元素的内容,除非html模板文件中使用了模板引擎语法来获取该配置项值,如下ejs模板语法形式
{%= o.htmlWebpackPlugin.options.title %}
filename
:输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还可以为输出文件指定目录位置(例如’html/index.html’)
1、filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
2、指定生成的html文件内容中的link和script路径是相对于生成目录下的,写路径的时候请写生成目录下的相对路径。
template
: 本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等)
1、template配置项在html文件使用`file-loader`时,其所指定的位置找不到,导致生成的html文件内容不是期望的内容。
2、为template指定的模板文件没有指定**任何loader的话**,默认使用`ejs-loader`。如`template: './index.html'`,若没有为`.html`指定任何loader就使用`ejs-loader
`
templateContent: string|function,可以指定模板的内容,不能与template共存。配置值为function时,可以直接返回html字符串,也可以异步调用返回html字符串。
inject
:向template或者templateContent中注入所有静态资源,不同的配置值注入的位置不经相同。
1、true或者body:所有JavaScript资源插入到body元素的底部
2、head: 所有JavaScript资源插入到head元素中
3、false: 所有静态资源css和JavaScript都不会注入到模板文件中
favicon
: 添加特定favicon路径到输出的html文档中,这个同title
配置项,需要在模板中动态获取其路径值
hash
:true|false,是否为所有注入的静态资源添加webpack每次编译产生的唯一hash值,添加hash形式如下所示
chunks
:允许插入到模板中的一些chunk,不配置此项默认会将entry
中所有的thunk注入到模板中。在配置多个页面时,每个页面注入的thunk应该是不相同的,需要通过该配置为不同页面注入不同的thunk;
excludeChunks
: 这个与chunks
配置项正好相反,用来配置不允许注入的thunk。
chunksSortMode
: none | auto| function,默认auto; 允许指定的thunk在插入到html文档前进行排序。
>function值可以指定具体排序规则;auto基于thunk的id进行排序; none就是不排序
xhtml
: true|fasle, 默认false;是否渲染link
为自闭合的标签,true则为自闭合标签
cache
: true|fasle, 默认true; 如果为true表示在对应的thunk文件修改后就会emit文件
showErrors
: true|false,默认true;是否将错误信息输出到html页面中。这个很有用,在生成html文件的过程中有错误信息,输出到页面就能看到错误相关信息便于调试。
minify
: {…}|false;传递 html-minifier 选项给 minify 输出,false就是不使用html压缩,minify具体配置参数请点击html-minifier
};
参数 | 默认 | 说明 | 值 |
---|---|---|---|
chunks | async | 设置代码分割类型,和cacheGroups 配置配合使用 |
async 对异步代码分割 all 对同步和异步代码分割 |
minSize | 30000(30kb) | 当引入的模块大于30kb才会做代码分割 | |
maxSize | 0 | 当引入的模块大于maxSize 时,会尝试对引入的模块进行二次拆分,一般不用配置 |
|
minChunks | 1 | 当一个模块被至少引入1次,才会做代码分割 | |
maxAsyncRequests | 5 | 当引入模块10个时,只会将前5个模块进行打包 | |
maxInitialRequests | 3 | 入口文件引入的模块如果超过3个,只会将前3个模块做代码分割 | |
automaticNameDelimiter | ~ |
文件连接符 | |
name | true | 拆分块的名称,让cacheGroups 里面的名字有效 |
|
cacheGroups | {} | 对符合代码拆分的模块进行一个分类 |
参数 | 类型 | 说明 | 值 |
---|---|---|---|
priority | number | 有限权,当一个模块都符合cacheGroups分组条件,将按照优先权进行分组,priority值越大,优先权越高 | -10 |
filename | String|Function | 拆分的名称,一般不设置,默认生成vendors~mian 。vendors 分组名称,~ 连接符,main 引入模块的入口文件 |
|
reuseExistingChunk | boolean | 如果当前块包含已从主束拆分的模块,则将重用它而不是生成新的块。比如 import a from ‘A’ import b from 'B’在打包时候,按照打包顺序也会将b 打包进a 模块,但是在a 打包之前,如果已经将b 模块进行过打包,那么就不会将b 模块在打包到a 模块中 |
|
test | function (module, chunk) | RegExp | string | 控制此缓存组选择的模块。test:/[\\/]node_modules[\\/]/ 必须要在node_modules模块在才可以 |
|
enforce | boolean | 将对 splitChunks.minSize splitChunks.minChunks splitChunks.maxAsyncRequests splitChunks.maxInitialRequests 配置忽略 |
作者:瓦力博客
链接:https://www.jianshu.com/p/6fc4c5726762
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在网页需要向低版本兼容时,如IE不支持promise等新特性,我们仅仅使用babel进行es5转换是不够的,还需要把这些新特性进行转换
require("@babel-polyfill")
或者import()
base.config
entry: {
app: ['@babel/polyfill',"./src/index.js"]
// app: "./src/index.js"
},
我们再安装一个 webpack-bundle-analyzer,这个插件会清晰的展示出打包后的各个bundle所依赖的模块:
npm i webpack-bundle-analyzer -D
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
使用,在plugins数组中添加即可:
new BundleAnalyzerPlugin()
在url-loader中使用 图片压缩loader
// 压缩代码
new TerserPlugin({
terserOptions: {
compress: {
drop_debugger: true,//关闭debug
drop_console: true,//关闭console
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
注: unglifyJsPlugin 2.0版本不能删除打印的日志 用teser替换 否则也会报错
| 将对 splitChunks.minSize splitChunks.minChunks splitChunks.maxAsyncRequests splitChunks.maxInitialRequests 配置忽略 | |
作者:瓦力博客
链接:https://www.jianshu.com/p/6fc4c5726762
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在网页需要向低版本兼容时,如IE不支持promise等新特性,我们仅仅使用babel进行es5转换是不够的,还需要把这些新特性进行转换
require("@babel-polyfill")
或者import()
base.config
entry: {
app: ['@babel/polyfill',"./src/index.js"]
// app: "./src/index.js"
},
我们再安装一个 webpack-bundle-analyzer,这个插件会清晰的展示出打包后的各个bundle所依赖的模块:
npm i webpack-bundle-analyzer -D
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
使用,在plugins数组中添加即可:
new BundleAnalyzerPlugin()
在url-loader中使用 图片压缩loader
// 压缩代码
new TerserPlugin({
terserOptions: {
compress: {
drop_debugger: true,//关闭debug
drop_console: true,//关闭console
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
注: unglifyJsPlugin 2.0版本不能删除打印的日志 用teser替换 否则也会报错