从零学脚手架(三)---webpack属性详解
如果此篇对您有所帮助,在此求一个star。项目地址: OrcasTeam/my-cli
在上一篇中,介绍了webpack的entry、output、plugins属性。
在这一篇,接着介绍其它配置属性。
mode
这个属性在上一篇中使用过一次,设置webpack编译模式的,那么这个属性到底是什么东西呢?
打包器是将开发环境代码编译为可部署环境代码
搭建的工程化代码基本都无法直接运行在浏览器,所以本地测试也都是使用打包编译后的代码预览。
但是本地开发预览又必须具有代码可读性、可调试性等条件。
webpack为了解决这个问题,就提供了两种打包模式:开发模式(development)和发布模式(production)
由mode属性设置
{
mode:'development'
}
也可以使用CLI参数进行设置

????
- webpack默认使用的是发布模式(production),缺少mode属性执行时,webpack会进行提示
- CLI参数设置 优先级要高于 webpack.config.js 文件设置。
- 更好的方案是使用两个webpack.config.js文件,脚手架一般都是这样区分,在之后介绍webpack merge时处理
测试两种模式的区别时,最直观区别就是查看编译生成的代码是否进行了压缩:在production模式下,webpack会预设压缩plugin
webpack中的mode属性值其实具有三个:development、production、none
none属性值与两者的区别只是没有预设任何插件
?????? development和production两种模式只是针对不同场景下功能差异化的区分,其实现具体的功能还是使用的插件
为了配置简单化,development和production两种模式都预设了一些基本插件。
下面来介绍下 development和production两种模式中的预设的部分功能
development
process.env.NODE_ENV
development模式时,webpack使用内置DefinePlugin
预设了一个环境变量属性process.env.NODE_ENV,属性值为development
开发人员可以编写业务代码时根据process.env.NODE_ENV属性判断当前编译模式,以此执行不同环境中的代码。
process.env.NODE_ENV属性和DefinePlugin稍后详细介绍
设置模块和模块名称设置有效性
development模式时,webpack会将JS模块、模块名称设置为有效名称,用来方便调试
webpack@4.X版本设置代码可读性使用的是webpack内置的plugin:NamedModulesPlugin和NamedChunksPlugin
webpack@5.X版本设置代码可读性使用的是 optimization.moduleIds 和optimization.chunkIds 两个属性。
但根源也是使用内置plugin:NamedModuleIdsPlugin和NamedChunkIdsPlugin
optimization: {
moduleIds: 'named',
chunkIds: 'named',
}
optimization属性是webpack提供的优化属性,与mode一样,只是为了方便管理,其根源还是使用插件设置的。
设置devtool属性
development模式时,webpack会将devtool属性设置为eval
devtool属性是控制SourceMap文件如何生成的。SourceMap是用于将原始模块文件与打包后的代码映射文件。用于调试使用。具体稍候介绍
production
process.env.NODE_ENV
production模式时,webpack使用内置DefinePlugin
预设一个环境变量属性process.env.NODE_ENV,属性值为production
开发人员可以编写业务代码时根据process.env.NODE_ENV属性判断当前编译模式,以此执行不同环境中的代码。
process.env.NODE_ENV属性和DefinePlugin稍后详细介绍
设置模块和模块名称混淆
production模式时,webpack将 JS模块、模块名称进行混淆,以保证代码安全性
webpack@4.X版本设置代码可读性使用的是webpack内置的plugin:NamedModulesPlugin和NamedChunksPlugin
webpack@5.X版本设置代码可读性使用的是 optimization.moduleIds 和optimization.chunkIds 两个属性。
但根源也是使用内置plugin:DeterministicModuleIdsPlugin和DeterministicChunkIdsPlugin
optimization: {
moduleIds: 'deterministic',
chunkIds: 'deterministic',
}
代码压缩
production模式时,webpack 开启了代码压缩优化 ,使用terser-webpack-plugin库对打包生成代码进行压缩
???? webpack@5.X默认使用terser-webpack-plugin压缩代码,webpack@4.X版本及之前版本,默认使用的压缩库为uglifyjs-webpack-plugin。但uglifyjs-webpack-plugin已停止维护
作用域提升
production模式时,webpack 会使用内置的ModuleConcatenationPlugin 对代码的作用域进行提示。用于减少打包生成的代码量和执行速度。
错误处理
production模式时,webpack 会预设内置NoEmitOnErrorsPlugin 。
打包编译时,如果出现代码错误,则不在生成代码。用于避免代码错误代码依然打包成功
????webpack@5.X和webpack@4.X对于development和production 预设功能具有一定的差异,具体请参考 webpack5-mode、webpack4-mode、显微镜下的webpack4的新特性:mode详解
DefinePlugin
在development和production两种模式中, 都设置了一个环境变量属性:process.env.NODE_ENV,只是属性值不相同。
环境变量用于编写业务代码时 针对不同环境下的差异化代码。例如调用第三方SDK时:区分开发环境 和正式环境。
当然可以选择每次发版时手动修改配置,只要自己不会觉得麻烦。
做一个测试
在/src/index.js中输出process.env.NODE_ENV属性

在执行yarn start
后查看打包生成代码会看到process.env.NODE_ENV 替换为了development字符串

同样如果执行yarn build
process.env.NODE_ENV 属性 会替换成production字符串
这就是 process.env.NODE_ENV环境变量的作用,webpack 在打包编译时会将设置的环境变量属性值进行替换,可以在编写业务代码时进行环境判断。
webpack 使用了内置的DefinePlugin设置 process.env.NODE_ENV。
当然也可以使用DefinePlugin设置自定义环境变量。具体详情请参考:官网
const webpack = require("webpack");
{
plugins:[
new webpack.DefinePlugin({ "global_a": JSON.stringify("我是一个打包配置的全局变量") }),
]
}
devtool
在development模式中会设置devtool属性。
devtool属性也是webpack提供的一个属性项。用于设置javascript-source-map
我们都看过打包编译生成的代码,哪怕是development模式下生成的,也是超级混乱。
而想要对这些代码调试排查错误,那简直是个噩梦。

对于这个问题,Google提供了一种工具叫做:javascript-source-map
javascript-source-map提供一个映射信息,将 打包编译生成的代码 与 开发编写的代码文件 进行映射,调试时直接针对 开发编写的代码文件进行调试。
?? source-map详细介绍请参考阮一峰老师的:JavaScript Source Map 详解
webpack提供了devtool属性来设置javascript-source-map
development模式 devtool属性默认值为 eval;
production模式 devtool属性默认值为 false(none)
eval属性值生成的代码都是由eval语法编译,并提供了一个sourceURL属性用于指向文件源路径

devtool属性具有非常多的属性值,不同的属性值 操作具有差异 和 打包消耗时间不同。
有的属性值会生成一个.map文件,个文件中存放映射信息,有的直接在生成文件中显示映射信息。
在此就不不详细介绍devtool,有兴趣的朋友可以参考官网自行测试
{
// 属性可以设置为false和字符串
devtool:false; // 'eval'
}
optimization
webpack针对代码优化管理,提供了optimization属性进行管理。
就像刚才介绍的optimization.moduleIds和optimization.chunkIds提供了对模块和模块名称管理。
但其根源还是使用了插件进行管理,属性只是为了方便管理。
optimization对象具有好多属性,在此也不详细介绍,
只介绍optimization.minimize和optimization.minimizer。这两个也是经常被使用到属性。
minimize和minimizer
minimize
先来做一个测试,将optimization.minimize手动改为false
optimization:{
minimize:false
}
此时使用yarn build
执行打包可以看到代码并没有进行压缩

也就是optimization.minimize属性是控制代码压缩的。
而production模式只是将optimization.minimize设置为了true

optimization:{
// 开启默认优化
minimize:true
}
minimizer
在optimization对象中还具有一个minimizer属性,这个属性和plugins属性功能相同,都是用来设置plugin的。
而两者的区别在于:optimization.minimizer会受到optimization.minimize属性的管理
optimization.minimizer属性会受到optimization.minimize属性的控制:
如果optimization.minimize属性值为false,那么就不加载设置在optimization.minimizer属性中的plugin
也就是optimization.minimize是控制optimization.minimizer属性的开关。

terser-webpack-plugin 默认情况下是设置在optimization.minimizer属性中,所以optimization.minimize属性设置为false 代码会不压缩。

如果terser-webpack-plugin 手动设置在plugins属性中,
那么就算 optimization.minimize 为 false,代码依然会压缩。

?? webpack已经依赖了terser-webpack-plugin,所以就不需要再安装
?? webpack@4.X以下默认使用的压缩裤为uglifyjs-webpack-plugin,好多文章都是以uglifyjs-webpack-plugin为基础讲解的,不过uglifyjs-webpack-plugin目前不再维护,webpack@5.X开始改为了terser-webpack-plugin
optimization.minimize和optimization.minimizer是webpack为方便管理提供的属性。
在配置时可以将关于优化的plugin设置在optimization.minimizer属性,由optimization.minimize统一管理。
而webpack提供的一系列默认值提供了最小配置。
代价却提高了webpack学习成本。让很多人对这些属性感到迷惑。
terser-webpack-plugin
terser-webpack-plugin 作为webpack@5.X默认的压缩工具。在此就直接介绍此库的属性
???? terser-webpack-plugin压缩对devtool属性具有一定的要求,只支持none、source-map、inline-source-map、hidden-source-map、nosources-source-map。 像eval生成的是字符串。terser-webpack-plugin就没办法进行处理
在刚才手动设置terser-webpack-plugin时没有添加任何参数。
而terser-webpack-plugin是有很多配置项的,配置项通过构造函数传递。
terser-webpack-plugin第一层参数主要对于文件多线程的设置。
const TerserPlugin = require('terser-webpack-plugin');
{
optimization: {
// 配置可优化
minimize: true,
minimizer: [
new TerserPlugin({
// 指定压缩的文件
include: /\.js(\?.*)?$/i,
// 排除压缩的文件
// exclude:/\.js(\?.*)?$/i,
// 是否启用多线程运行,默认为true,开启,默认并发数量为os.cpus()-1
// 可以设置为false(不使用多线程)或者数值(并发数量)
parallel: true,
// 可以设置一个function,使用其它压缩插件覆盖默认的压缩插件,默认为undefined,d,
minify: undefined,
// 是否将代码注释提取到一个单独的文件。
// 属性值:Boolean | String | RegExp | Function<(node, comment) -> Boolean|Object> | Object
// 默认为true, 只提取/^\**!|@preserve|@license|@cc_on/i注释
// 感觉没什么特殊情况直接设置为false即可
extractComments: false,
// 压缩时的选项设置
terserOptions: {}
})
]
}
}
-
include:指定压缩的文件
属性可设置为:String、String[]、Regex
默认值为:undefined
-
exclude:排除压缩的文件
属性可设置为:String、String[]、Regex
默认值为:undefined
-
parallel:是否启用多线程运行
属性可设置为:Boolean、Number
属性值为false:不启动多线程
属性值为true:启动多线程,多线程数量为:os.cpus()-1
属性值为Number:表示使用的多线程数量
默认值为:true
-
minify:设置其它压缩工具覆盖terser-webpack-plugin
此属性可以设置一个函数,函数内允许使用其它压缩工具替代terser-webpack-plugin, 其实相当于做了一个拦截,基本上不会使用此属性。 详细介绍可以参考 官方
属性可设置为:Function
默认值为undefined
-
extractComments:是否将代码注释提取到一个单独的文件。
经过压缩的代码都会去除注释,此属性就是设置是否提取注释,个人感觉这个属性也没什么用。详细介绍可以参考 官方
属性可设置为:Boolean、String、RegExp、Function<(node, comment) -> Boolean | Object>、 Object
属性值为false或者函数返回false:表示不提取
属性值为String时: all表示全部提取。some表示使用默认正则匹配:/^**!|@preserve|@license|@cc_on/i
属性值为true或者函数返回true时:表示提取,使用默认正则匹配:/^**!|@preserve|@license|@cc_on/i
属性值为Regex时:自定义提取规则。
属性值为Object时:允许自定义提取条件。
默认值为true
-
terserOptions:设置压缩选项
此属性才是详细设置压缩选项的参数。
属性可设置为:Object
terserOptions属性
先来做一个测试,在index.js中创建这么一个函数

使用默认压缩配置进行打包编译,结果可以看到生成的代码只有真实执行的代码。

默认terser-webpack-plugin配置基本上做到了最优解。
?? 如果将var a = 1改为let a = 1,则结果有些不一致,这是由于ES6问题,有兴趣的诸君可以测试一下
terser-webpack-plugin配置属性中:terserOptions.compress属性才是控制压缩。
terserOptions.compress 设置类型为 Boolean、Object。
接下来将此属性设置为false。查看打包编译代码,可以发现,代码并没有被压缩,只是改变了属性名称和函数函数
{
optimization: {
// 配置可优化
minimize: true,
minimizer: [
new TerserPlugin({
// 压缩时的选项设置
terserOptions: {
compress:false
}
})
]
}
}

terserOptions这一层中的设置主要是对代码中属性名称、函数名称。等一系列的设置
{
optimization: {
// 配置可优化
minimize: true,
minimizer: [
new TerserPlugin({
// 压缩时的选项设置
terserOptions: {
// 是否保留原始函数名称,true代表保留,false即保留
// 此属性对使用Function.prototype.name
// 默认为false
keep_fnames:false,
// 是否保留原始类名称
keep_classnames:false,
// format和output是同一个属性值,,名称不一致,output不建议使用了,被放弃
// 指定压缩格式。例如是否保留*注释*,是否始终为*if*、*for*等设置大括号。
format: {comments:true},
output: undefined,
// 是否支持IE8,默认不支持
ie8:true,
// ·压缩配置
compress: { },
}
})
]
}
}
-
keep_fnames:是否保留原始函数名称
刚才测试看到了,默认情况下会更改函数名称,此属性就是设置是否保留函数名称。
属性可设置为:Boolean
属性值为false:表示不保留原始名称
属性值为true:表示保留原始名称
默认值为false
-
keep_classnames: 是否保留原始类名称
与keep_fnames属性类似,只不过设置的是类名称
属性可设置为:Boolean
属性值为false:表示不保留原始名称
属性值为true:表示保留原始名称
默认值为false
-
format/output:指定压缩格式。例如是否保留注释,是否始终为if、for等设置大括号。
format和output的配置相同。output官方不再推荐使用。这个属性就不介绍,具体请参考官方
属性可设置为:Object
默认值为null
-
ie8:是否支持IE8
属性可设置为:Boolean
默认值为false
-
compress:设置压缩选项
属性可设置为:Boolean、Object
属性值为false:表示不压缩。
属性值为object:自定义压缩设置。
下面介绍下terserOptions.compress的配置。terserOptions.compress只介绍部分属性 。其它设置,有兴趣的朋友可以查看官方
{
optimization: {
// 配置可优化
minimize: true,
minimizer: [
new TerserPlugin({
// 压缩时的选项设置
terserOptions: {
compress: {
// 是否使用默认配置项,这个属性当只启用指定某些选项时可以设置为false
defaults: false,
// 是否移除无法访问的代码
dead_code: false,
// 是否优化只使用一次的变量
collapse_vars: true,
warnings: true,
// 是否删除所有 console.*语句,默认为false,这个可以在线上设置为true
drop_console: false,
// 是否删除所有debugger语句,默认为true
drop_debugger: true,
// 移除指定func,这个属性假定函数没有任何副作用,可以使用此属性移除所有指定func
// pure_funcs: ['console.log'], //移除console
}
}
})
]
}
}
-
defaluts:是否使用默认配置项
此属性表示是否使用官方设置默认配置项
属性可设置为:Boolean
默认值为true
-
dead_code:是否移除无法访问的代码
属性可设置为:Boolean
默认值为true
-
collapse_vars:是否优化只使用一次的变量
此属性表示是否将只使用一次的变量直接进行替换优化
属性可设置为:Boolean
默认值为true
-
drop_console:是否删除所有console语句
此属性可以在发布时设置为true
属性可设置为:Boolean
默认值为false
-
drop_debugger:是否删除所有debugger语句
属性可设置为:Boolean
默认值为true
-
pure_funcs:移除指定的函数。
此属性可以设置移除指定的函数,但是需要缺点要移除的函数没有任何副作用(没有使用),有兴趣的朋友可以测试删除自定义函数
terser-webpack-plugin配置项还有好多,但是一般使用默认属性即可,
会被使用到可能也就是 :
terserOptions.compress.drop_console去除所有console和parallel来设置多线程
其它一般都是默认值即可。
???? 暂时先将optimization.minimize属性设置false,可以更方便的查看生成代码
loader
在上一篇文章说过:webpack是一个JavaScript应用程序的静态模块打包器,其本身并不支持非JS模块。
但webpack提供了将 非JS模块 转换为JS模块的功能---loader
loader相当于一个拦截器,将指定文件进行编译为JS模块,再传递给webpack。
在这里先不学习具体的loader ,只介绍下loader 的配置语法。
loader的配置是在module.rules属性,module.rules是一个Array类型属性。
数组每一项都可以设置 拦截文件使用指定loader 。
{
module:{
rules:[
{
// test:/\.css$/,
// include:path.join(__dirname,'src'),
// exclude:path.join(__dirname,'node_modules'),
// // 字符串形式
// use:'css-loader',
// 数组形式,可以设置多个loader
// use:[
// {
// loader:'css-loader',
// options:{
//
// }
// }
// ]
}
]
}
}
-
test:设置拦截文件
使用此属性设置拦截的文件。例如:/.css$ 表示拦截所有的Webpack的Loader为什么是从右往左写
resolve
resolve 是webpack提供的一个属性,用来配置打包编译时的模块解析规则。
resolve是一个Object类型,具有不少的属性配置。
在此只介绍三个常用的属性。其它属性,有兴趣的朋友可以去参考中文官网
alias
使用vue-cli这类脚手架,开发时引入本地文件模块,通常可以使用一个符号(@)来代替/src工作目录。
这个功能就是resolve.alias提供的。
resolve.alias属性可以对一个指定路径设置别名。打包编译时会将设置别名替换为配置的真实路径
{ resolve: { alias:{ // 设置路径别名 '@':path.join(__dirname,'src'), '~': path.resolve(__dirname, '../src/assets') }, } }
此时在引用文件模块时,就可以使用@来代替/src工作目录(工作根目录)
?? webpack允许设置除关键字外的任意符号作为别名。vue-cli这类脚手架一般都预设符号(@)代替/src工作目录。
extensions
使用vue-cli这类脚手架,开发时引入本地文件模块。很常见的一种行为就是不需要添加后缀名称。
这个功能就是resolve.extensions提供的。
resolve.extensions功能允许设置多个后缀名称。导入文件模块时可以忽略文件后缀名称,
打包编译时按照配置缀顺序依次匹配,直到寻到第一个匹配文件或报错(找不到匹配文件)。
resolve.extensions属性类型为Array,默认值为:['.js', '.json'],也就是可以忽略JS文件和JSON文件后缀
下面将resolve.extensions设置为['.json']做一个测试
{ resolve: { extensions:['.json'] } }
此时由于引用index2.js时还是没有添加后缀,打包编译时就直接报错了。
而引用index2.js添加.js后缀名称才可以打包成功。。
vue-cli、react-cli这类脚手架都会在resolve.extensions属性配置自己文件类型的后缀名称。
在此以react-cli为例
?????? 打包编译时匹配resolve.extensions,使用的是队列形式。Array从先到后
mainFiles
使用vue-cli这类脚手架,开发时引入本地文件模块,有一种常见方式只指定其文件所在目录,并没有指定文件名称。
这种方式常见于以 目录为组件单元的代码风格。例如antd,就是以目录为组件单元。
这个功能是由resolve.mainFiles属性提供的。
resolve.mainFiles允许设置多个文件名称,导入文件模块时可以忽略此文件名称。
打包编译时按照配置缀顺序依次匹配,直到寻到第一个匹配文件或报错(找不到匹配文件)。
resolve.extensions属性类型为Array,默认值为:['index'],也就是可以忽略index名称的文件。
???? 使用resolve.mainFiles时需要设置resolve.extensions,目录是没有后缀的,需要设置忽略后缀,否则会报错:
下面将resolve.mainFiles设置为['index','main']做测试
{ resolve: { extensions:['.js','.json'], mainFiles:['index','main'], } }
可以看到, 可以看到导入/demo/main.js时,忽略了文件名称,但是依然打包编译、导入成功
?????? 打包编译时匹配resolve.mainFiles,使用的也是队列形式。Array从先到后
?????? 个人建议使用目录结构方式组织组件
context
配置webpack时,使用文件目录时都使用了绝对地址:path.join(__dirname, ...)
webpack其实提供了一个context属性:在配置项中允许 以此目录为基准 设置 相对目录。
不过context属性个人感觉并不太好用。
context属性String类型,设置一个绝对路径的目录地址
context默认值为当前项目根目录,也就是package.json文件所在目录
context属性默认值为当前项目根目录,所以可以直接使用相对路径
{ entry: './src/index.js' , }
此时执行
yarn build
打包也可以进行打包成功。也可以使用context指定其它目录为基准目录
{ context: path.join(__dirname, './src'), // 入口文件 // 字符串形式 entry: './index.js' , }
但context属性具有一定的缺陷
output不允许相对路径
并不是所有的属性都可以设置为相对路径
例如output属性就只允许使用绝对路径。
配置属性中既有相对路径又有绝对路径,对于我这个强迫症来说感觉怪怪的。
?? output属性只允许使用绝对路径应该是为了保证输出地址的准确安全性。
基准绝对路径
个人比较喜欢的方案就是自定义一个root目录。
在配置文件中 root目录 去设置路径
const config = { root: path.join(__dirname, './'), }; const { entry: path.join(config.root, 'src/index.js'), output: { path: path.join(config.root, 'dist'), filename: '[name]_[contenthash].js' }, }
至于自定义root属性而不直接使用__dirname原因是:
个人感觉自定义属性方便控制。 例如更换配置文件目录,直接使用__dirname,所有目录地址都需要更改,而自定义绝对路径基准就只需要更改root目录即可
当然真实开发不会出现此类情况。
使用context属性还是绝对路径都无伤大雅,个人习惯罢了,只要文件路径正确即可
总结
??????
- webpack提供了两种打包模式:开发测试打包编译(development)和线上发布打包编译(production) 。两种打包模式能够更加方便管理插件
- webpack对development和 production 都预设了一些基础功能,大大减少了开发时的配置
- source-map是Google提供的打包编译后代码与开发代码的一种映射文件,主要用途是方便开发人员调试
- optimization属性是webpack提供的控制优化的属性, optimization只是一系列优化功能的集合,主要是为了方便管理,本质还是由插件完成功能
- resolve属性提供了打包编译时的解析规则,
本文参考
- webpack官网
- webpack5-mode
- webpack4-mode
- webpack4的新特性:mode详解
- uglifyjs-webpack-plugin
- terser-webpack-plugin
- terser Github
- terser-webpack-plugin Github
- Webpack的Loader为什么是从右往左写?
webpack.config.js
const path = require('path') const webpack = require("webpack"); const HtmlWebpackPlugin = require('html-webpack-plugin') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const TerserPlugin = require('terser-webpack-plugin') const config = { root: path.join(__dirname, './'), } const modules = { // 入口文件 // 字符串形式 entry: path.join(config.root, 'src/index.js'), // 对象形式 // entry:{ // 'index': path.join(config.root, 'src/index.js'), // }, // 输出文件 // 字符串形式 // output:path.join(config.root, './dist/[name].js') //对象形式 output: { // 输出文件的目录地址 path: path.join(config.root, 'dist'), // 输出文件名称,contenthash代表一种缓存,只有文件更改才会更新hash值,重新打包 filename: '[name]_[contenthash].js' }, //devtool:false, //'eval' // module:{ // rules:[ // { // test:/\.css$/, // include: ath.join(config.root,'src'), // exclude: path.join(config.root,'node_modules'), // //// 字符串形式 // // use:'css-loader', // // 数组形式,可以设置多个loader // // use:[ // // { // // loader:'css-loader', // // options:{ // // // // } // // } // // ] // } // ] // } optimization: { // 暂时关闭压缩优化,方便观察打包生成代码 minimize: false, minimizer: [ new TerserPlugin({ // 指定压缩的文件 include: /\.js(\?.*)?$/i, // 排除压缩的文件 // exclude:/\.js(\?.*)?$/i, // 是否启用多线程运行,默认为true,开启,默认并发数量为os.cpus()-1 // 可以设置为false(不使用多线程)或者数值(并发数量) parallel: true, // 可以设置一个function,使用其它压缩插件覆盖默认的压缩插件,默认为undefined, minify: undefined, // 是否将代码注释提取到一个单独的文件。 // 属性值:Boolean | String | RegExp | Function<(node, comment) -> Boolean|Object> | Object // 默认为true, 只提取/^\**!|@preserve|@license|@cc_on/i注释 // 感觉没什么特殊情况直接设置为false即可 extractComments: false, // 压缩时的选项设置 terserOptions: { // 是否保留原始函数名称,true代表保留,false即保留 // 此属性对使用Function.prototype.name // 默认为false keep_fnames:false, // 是否保留原始类名称 keep_classnames:false, // format和output是同一个属性值,,名称不一致,output不建议使用了,被放弃 // 指定压缩格式。例如是否保留*注释*,是否始终为*if*、*for*等设置大括号。 format: { comments:false, }, output: undefined, // 是否支持IE8,默认不支持 ie8:false, compress: { // 是否使用默认配置项,这个属性当只启用指定某些选项时可以设置为false defaults:false, // 是否移除无法访问的代码 dead_code:false, // 是否优化只使用一次的变量 collapse_vars:true, warnings:true, // 是否删除所有 console.*语句,默认为false,这个可以在线上设置为true drop_console: false, // 是否删除所有debugger语句,默认为true drop_debugger:true, // 移除指定func,这个属性假定函数没有任何副作用,可以使用此属性移除所有指定func // pure_funcs: ['console.log'], //移除console }, } }) ] }, plugins: [ new HtmlWebpackPlugin({ // HTML的标题, // template的title优先级大于当前数据 title: 'my-cli', // 输出的html文件名称 filename: 'index.html', // 本地HTML模板文件地址 template: path.join(config.root, 'src/index.html'), // 引用JS文件的目录路径 publicPath: './', // 引用JS文件的位置 // true或者body将打包后的js脚本放入body元素下,head则将脚本放到中 // 默认为true inject: 'body', // 加载js方式,值为defer/blocking // 默认为blocking, 如果设置了defer,则在js引用标签上加上此属性,进行异步加载 scriptLoading: 'blocking', // 是否进行缓存,默认为true,在开发环境可以设置成false cache: false, // 添加mate属性 meta: {} }), new CleanWebpackPlugin({ // 是否假装删除文件 // 如果为false则代表真实删除,如果为true,则代表不删除 dry: false, // 是否将删除日志打印到控制台 默认为false verbose: true, // 允许保留本次打包的文件 // true为允许,false为不允许,保留本次打包结果,也就是会删除本次打包的文件 // 默认为true protectWebpackAssets: true, // 每次打包之前删除匹配的文件 cleanOnceBeforeBuildPatterns: ['**/*'], // 每次打包之后删除匹配的文件 cleanAfterEveryBuildPatterns:["*.js"], }), new webpack.DefinePlugin({ "global_a": JSON.stringify("我是一个打包配置的全局变量") }), ], resolve: { alias:{ // 设置路径别名 '@': path.join(config.root, 'src') , '~': path.join(config.root, 'src/assets') , }, // 可忽略的后缀 extensions:['.js', '.json'], // 默认读取的文件名 mainFiles:['index', 'main'], } } // 使用node.js的导出,将配置进行导出 module.exports = modules