如果此篇对您有所帮忙,在此求一个star。我的项目地址: OrcasTeam/my-cli
在上一篇中,介绍了 <font style="color:cornflowerblue">webpack</font> 的 entry 、 output 、 plugins 属性。
在这一篇,接着介绍其它配置属性。
mode
这个属性在上一篇中应用过一次:设置 <font style="color:cornflowerblue">webpack</font> 编译模式,那么这个属性到底是什么货色呢?
<font style="color:cornflowerblue">打包器</font>是将<font style="color:#007FFF">开发环境代码</font> 编译 为<font style="color:#007FFF">可部署环境代码</font>
搭建的 <font style="color:cornflowerblue">工程化</font> 代码根本都无奈间接运行在浏览器,所以本地测试也都是应用打包编译后的代码预览。
然而本地开发预览又必须具备代码可读性、可调试性等条件。
<font style="color:cornflowerblue">webpack </font>为了解决这个问题,就提供了两种 <font style="color:cornflowerblue">打包模式</font>:<font style="color:cornflowerblue">开发模式(development)</font>和<font style="color:cornflowerblue">公布模式(production)</font>
由mode属性设置
{ mode:'development' }
也能够应用 CLI参数 进行设置
- <font style="color:cornflowerblue">webpack</font> 默认应用的是 <font style="color:cornflowerblue">公布模式(production)</font>,短少 mode 属性执行时,<font style="color:cornflowerblue">webpack</font> 会进行提醒
- CLI参数设置 优先级要高于 webpack.config.js 文件设置。
- 更好的计划是应用两个 webpack.config.js 文件,脚手架个别都是这样辨别,在之后介绍 <font style="color:cornflowerblue">webpack merge</font> 时解决
测试两种模式的区别时,最直观区别就是查看编译生成的代码是否进行了压缩:在 production 模式下,<font style="color:cornflowerblue">webpack</font> 会预设压缩 plugin
<font style="color:cornflowerblue">webpack</font>中的 mode 属性值其实具备三个:development、production、none
none 属性值与两者的区别只是没有预设任何 <font style="color:#06f">插件</font>
development 和 production 两种模式只是针对不同场景下性能差异化的辨别,其实现具体的性能还是应用的 <font style="color:#06f">插件</font>为了配置简单化,development 和 production 两种模式都预设了一些根本 <font style="color:#06f">插件</font>。
上面来介绍下 development 和 production 两种模式中的预设的局部性能
development
process.env.NODE_ENV
development 模式时,<font style="color:cornflowerblue">webpack</font> 应用内置 <font style="color:cornflowerblue">DefinePlugin</font>
预设了一个环境变量属性 process.env.NODE_ENV,属性值为 development
开发人员能够编写业务代码时依据 process.env.NODE_ENV 属性判断以后编译模式,以此执行不同环境中的代码。
process.env.NODE_ENV 属性和 <font style="color:cornflowerblue">DefinePlugin</font> 稍后具体介绍
设置模块和模块名称设置有效性
development 模式时,<font style="color:cornflowerblue">webpack</font> 会将 JS模块 、 模块名称 设置为无效名称,用来不便调试
<font style="color:cornflowerblue">webpack@4.X</font> 版本设置代码可读性应用的是 <font style="color:cornflowerblue">webpack</font> 内置的 <font style="color:cornflowerblue">plugin</font> : <font style="color:cornflowerblue">NamedModulesPlugin</font> 和 <font style="color:cornflowerblue">NamedChunksPlugin</font>
<font style="color:cornflowerblue">webpack@5.X</font>版本设置代码可读性应用的是 optimization.moduleIds 和 optimization.chunkIds 两个属性。
但本源也是应用内置<font style="color:cornflowerblue">plugin</font>:<font style="color:cornflowerblue">NamedModuleIdsPlugin</font> 和 <font style="color:cornflowerblue">NamedChunkIdsPlugin</font>
optimization: { moduleIds: 'named', chunkIds: 'named',}
optimization 属性是<font style="color:cornflowerblue">webpack</font>提供的优化属性,与mode一样,只是为了方便管理,其本源还是应用 <font style="color:#06f">插件</font >设置的。
设置devtool属性
development 模式时,<font style="color:cornflowerblue">webpack</font>会将 devtool 属性设置为 eval
devtool 属性是管制 <font style="color:cornflowerblue">SourceMap </font> 文件如何生成的。<font style="color:cornflowerblue">SourceMap</font> 是用于将原始模块文件与打包后的代码映射文件。用于调试应用。具体稍候介绍
production
process.env.NODE_ENV
production 模式时,<font style="color:cornflowerblue">webpack</font> 应用内置 <font style="color:cornflowerblue">DefinePlugin</font>
预设一个环境变量属性 process.env.NODE_ENV,属性值为 production
开发人员能够编写业务代码时依据 process.env.NODE_ENV 属性判断以后编译模式,以此执行不同环境中的代码。
process.env.NODE_ENV 属性和 <font style="color:cornflowerblue">DefinePlugin</font> 稍后具体介绍
设置模块和模块名称混同
production 模式时,<font style="color:cornflowerblue">webpack</font>将 JS模块 、 模块名称 进行混同,以保障代码安全性
<font style="color:cornflowerblue">webpack@4.X </font>版本设置代码可读性应用的是 <font style="color:cornflowerblue">webpack</font> 内置的<font style="color:cornflowerblue">plugin</font>:<font style="color:cornflowerblue">NamedModulesPlugin</font> 和 <font style="color:cornflowerblue">NamedChunksPlugin</font>
<font style="color:cornflowerblue">webpack@5.X</font> 版本设置代码可读性应用的是 optimization.moduleIds 和 optimization.chunkIds 两个属性,但本源也是应用内置<font style="color:cornflowerblue">plugin</font>:<font style="color:cornflowerblue">DeterministicModuleIdsPlugin</font> 和 <font style="color:cornflowerblue">DeterministicChunkIdsPlugin</font>
optimization: { moduleIds: 'deterministic', chunkIds: 'deterministic',}
代码压缩
production 模式时,<font style="color:cornflowerblue">webpack</font> 开启了代码压缩优化 ,应用terser-webpack-plugin库对打包生成代码进行压缩
<font style="color:cornflowerblue">webpack@5.X </font>默认应用terser-webpack-plugin压缩代码,<font style="color:cornflowerblue">webpack@4.X </font>版本及之前版本,默认应用的压缩库为uglifyjs-webpack-plugin。但uglifyjs-webpack-plugin已进行保护
作用域晋升
production模式时,<font style="color:cornflowerblue">webpack</font> 会应用内置的 <font style="color:cornflowerblue">ModuleConcatenationPlugin</font> 对代码的作用域进行提醒。用于缩小打包生成的代码量和执行速度。
错误处理
production模式时,<font style="color:cornflowerblue">webpack</font> 会预设内置 <font style="color:cornflowerblue">NoEmitOnErrorsPlugin</font> 。
打包编译时,如果呈现代码谬误,则不在生成代码。用于防止代码错误代码仍然打包胜利
<font style="color:cornflowerblue">webpack@5.X</font> 和 <font style="color:cornflowerblue">webpack@4.X</font> 对于 development 和 production 预设性能具备肯定的差别,具体请参考 webpack5-mode、webpack4-mode、显微镜下的webpack4的新个性:mode详解
DefinePlugin
在 development 和 production 两种模式中, 都设置了一个环境变量属性: process.env.NODE_ENV ,只是属性值不雷同。
环境变量用于编写业务代码时 针对不同环境下的差异化代码。例如调用第三方SDK时:辨别 <font style="color:cornflowerblue">开发环境</font> 和 <font style="color:cornflowerblue">正式环境</font>。
当然能够抉择每次发版时手动批改配置,只有本人不会感觉麻烦。
做一个测试
在 /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 环境变量的作用,<font style="color:cornflowerblue">webpack</font> 在打包编译时会将设置的环境变量属性值进行替换,能够在编写业务代码时进行环境判断。
<font style="color:cornflowerblue">webpack</font> 应用了内置的 <font style="color:cornflowerblue">DefinePlugin</font> 设置 process.env.NODE_ENV。
当然也能够应用 <font style="color:cornflowerblue">DefinePlugin</font> 设置自定义环境变量。具体详情请参考:官网
const webpack = require("webpack");{ plugins:[ new webpack.DefinePlugin({ "global_a": JSON.stringify("我是一个打包配置的全局变量") }), ]}
devtool
在 development 模式中会设置 devtool 属性。
devtool 属性也是 <font style="color:cornflowerblue">webpack</font> 提供的一个属性项。用于设置 <font style="color:cornflowerblue">javascript-source-map</font>
咱们都看过打包编译生成的代码,哪怕是 development 模式下生成的,也是超级凌乱。
而想要对这些代码调试排查谬误,那几乎是个噩梦。
对于这个问题,<font style="color:cornflowerblue">Google</font> 提供了一种工具叫做:<font style="color:cornflowerblue">javascript-source-map</font>
<font style="color:cornflowerblue">javascript-source-map </font> 提供一个映射信息,将 打包编译生成的代码 与 开发编写的代码文件 进行映射,调试时间接针对 开发编写的代码文件进行调试。
<font style="color:cornflowerblue">source-map</font> 具体介绍请参考阮一峰老师的:JavaScript Source Map 详解
<font style="color:cornflowerblue">webpack</font>提供了 devtool 属性来设置 <font style="color:cornflowerblue">javascript-source-map</font>
development 模式 devtool 属性默认值为 eval;
production 模式 devtool 属性默认值为 false(none)
eval 属性值生成的代码都是由 eval 语法编译,并提供了一个 sourceURL 属性用于指向文件源门路
devtool 属性具备十分多的属性值,不同的属性值 操作具备差别 和 打包耗费工夫不同。
有的属性值会生成一个 .map 文件,个文件中寄存映射信息,有的间接在生成文件中显示映射信息。
在此就不不具体介绍 devtool,有趣味的敌人能够参考官网自行测试
{ // 属性能够设置为false和字符串 devtool:false; // 'eval'}
optimization
<font style="color:cornflowerblue">webpack</font> 针对代码优化治理,提供了 optimization 属性进行治理。
就像方才介绍的 optimization.moduleIds 和 optimization.chunkIds 提供了对 模块 和 模块名称 治理。
但其本源还是应用了<font style="color:#06f">插件</font>进行治理,属性只是为了方便管理。
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 属性性能雷同,都是用来设置<font style="color:cornflowerblue">plugin</font>的。
而两者的区别在于:optimization.minimizer 会受到 optimization.minimize 属性的治理
optimization.minimizer属性会受到optimization.minimize属性的管制:
如果optimization.minimize属性值为false,那么就不加载设置在optimization.minimizer属性中的<font style="color:cornflowerblue">plugin</font>
也就是optimization.minimize是管制optimization.minimizer属性的开关。
<font style="color:#f03d3d">terser-webpack-plugin</font> 默认状况下是设置在optimization.minimizer属性中,所以optimization.minimize属性设置为false 代码会不压缩。
如果<font style="color:#f03d3d">terser-webpack-plugin</font> 手动设置在plugins属性中,
那么就算optimization.minimize为false,代码仍然会压缩。
<font style="color:#f03d3d">webpack</font>曾经依赖了<font style="color:#f03d3d">terser-webpack-plugin</font>,所以就不须要再装置<font style="color:cornflowerblue">webpack@4.X</font>以下默认应用的压缩裤为uglifyjs-webpack-plugin,好多文章都是以uglifyjs-webpack-plugin为根底解说的,不过uglifyjs-webpack-plugin目前不再保护,<font style="color:cornflowerblue">webpack@5.X</font>开始改为了terser-webpack-plugin
optimization.minimize和optimization.minimizer是<font style="color:cornflowerblue">webpack</font>为方便管理提供的属性。
在配置时能够将对于优化的<font style="color:cornflowerblue">plugin</font>设置在optimization.minimizer属性,由optimization.minimize对立治理。
而<font style="color:cornflowerblue">webpack</font>提供的一系列默认值提供了最小配置。
代价却进步了<font style="color:cornflowerblue">webpack</font>学习老本。让很多人对这些属性感到蛊惑。
terser-webpack-plugin
<font style="color:#f03d3d">terser-webpack-plugin</font> 作为<font style="color:cornflowerblue">webpack@5.X</font>默认的压缩工具。在此就间接介绍此库的属性
<font style="color:#f03d3d">terser-webpack-plugin</font>压缩对devtool属性具备肯定的要求,只反对none、source-map、inline-source-map、hidden-source-map、nosources-source-map。 像eval生成的是字符串。<font style="color:#f03d3d">terser-webpack-plugin</font>就没方法进行解决
在方才手动设置<font style="color:#f03d3d">terser-webpack-plugin</font>时没有增加任何参数。
而<font style="color:#f03d3d">terser-webpack-plugin</font>是有很多配置项的,配置项通过构造函数传递。
<font style="color:#f03d3d">terser-webpack-plugin</font>第一层参数次要对于文件多线程的设置。
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:设置其它压缩工具笼罩<font style="color:#f03d3d">terser-webpack-plugin</font>
此属性能够设置一个函数,函数内容许应用其它压缩工具代替<font style="color:#f03d3d">terser-webpack-plugin</font>, 其实相当于做了一个拦挡,基本上不会应用此属性。 具体介绍能够参考 官网
属性可设置为: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中创立这么一个函数
应用默认压缩配置进行打包编译,后果能够看到生成的代码只有实在执行的代码。
默认<font style="color:#f03d3d">terser-webpack-plugin</font>配置基本上做到了最优解。
如果将var a = 1改为let a = 1,则后果有些不统一,这是因为ES6问题,有趣味的诸君能够测试一下
<font style="color:#f03d3d">terser-webpack-plugin</font>配置属性中: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:移除指定的函数。
此属性能够设置移除指定的函数,然而须要毛病要移除的函数没有任何<font style="color:cornflowerblue">副作用(没有应用)</font>,有趣味的敌人能够测试删除自定义函数
<font style="color:#f03d3d">terser-webpack-plugin</font>配置项还有好多,然而个别应用默认属性即可,
会被应用到可能也就是 :
terserOptions.compress.drop_console去除所有console和parallel来设置多线程
其它个别都是默认值即可。
临时先将optimization.minimize属性设置false,能够更不便的查看生成代码
loader
在上一篇文章说过:<font style="color:cornflowerblue">webpack</font>是一个<font style="color:#06f">JavaScript应用程序</font>的动态模块打包器,其自身并不反对非JS模块。
但<font style="color:cornflowerblue">webpack</font>提供了将 非JS模块 转换为JS模块的性能---<font style="color:cornflowerblue">loader </font>
<font style="color:cornflowerblue">loader</font>相当于一个<font style="color:cornflowerblue">拦截器</font>,将<font style="color:#06f">指定文件</font>进行编译为JS模块,再传递给<font style="color:cornflowerblue">webpack</font>。
在这里先不学习具体的<font style="color:cornflowerblue">loader </font>,只介绍下<font style="color:cornflowerblue">loader </font>的配置语法。
<font style="color:cornflowerblue">loader</font>的配置是在module.rules属性,module.rules是一个Array类型属性。
数组每一项都能够设置 拦挡文件应用指定<font style="color:cornflowerblue">loader </font>。
{ 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$ 示意拦挡所有的[.css]()文件。应用Regex能够拦挡多种文件类型应用同一<font style="color:cornflowerblue">loader</font>
属性可设置为:Regex
- include:蕴含拦挡的文件目录。
此属性能够设置拦挡指定目录的文件,个别应用此属性设置只拦挡 /src 目录中文件
属性可设置为:String
- exclude:排除拦挡的文件目录。
此属性与include相似,只不过性能相同,指定要排除的目录。个别应用此属性排除node_modules目录。
此属性与include只应用一种。
属性可设置为:String
- use:拦挡到的文件所应用的<font style="color:cornflowerblue">loader</font>。
属性可设置为:String、Array
属性值为String:设置<font style="color:cornflowerblue">loader </font>名称
属性值为Array:能够指定多个<font style="color:cornflowerblue">loader </font>解决,并且能够对每一个<font style="color:cornflowerblue">loader </font> 设置属性配置。
当指定多个<font style="color:cornflowerblue">loader </font>时,<font style="color:cornflowerblue">loader </font>加载程序为从右往左。具体请参考Webpack的Loader为什么是从右往左写?
resolve
resolve是<font style="color:cornflowerblue">webpack</font>提供的一个属性,用来配置打包编译时的模块解析规定。
resolve是一个Object类型,具备不少的属性配置。
在此只介绍三个罕用的属性。其它属性,有趣味的敌人能够去参考中武官网
alias
应用<font style="color:cornflowerblue">vue-cli</font>这类脚手架,开发时引入本地文件模块,通常能够应用一个 <font style="color:cornflowerblue">符号(@)</font> 来代替 /src 工作目录。
这个性能就是resolve.alias提供的。
resolve.alias属性能够对一个指定门路设置别名。打包编译时会将设置别名替换为配置的实在门路
{ resolve: { alias:{ // 设置门路别名 '@':path.join(__dirname,'src'), '~': path.resolve(__dirname, '../src/assets') }, }}
此时在援用文件模块时,就能够应用 @ 来代替 /src 工作目录(工作根目录)
<font style="color:cornflowerblue">webpack</font>容许设置除关键字外的任意符号作为别名。<font style="color:cornflowerblue">vue-cli</font>这类脚手架个别都预设<font style="color:cornflowerblue">符号(@)</font>代替 /src 工作目录。
extensions
应用<font style="color:cornflowerblue">vue-cli</font>这类脚手架,开发时引入本地文件模块。很常见的一种行为就是不须要增加后缀名称。
这个性能就是resolve.extensions提供的。
resolve.extensions性能容许设置多个后缀名称。导入文件模块时能够疏忽文件后缀名称,
打包编译时依照配置缀程序顺次匹配,直到寻到第一个匹配文件或报错(找不到匹配文件)。
resolve.extensions属性类型为Array,默认值为:['.js', '.json'],也就是能够疏忽JS文件和JSON文件后缀
上面将resolve.extensions设置为 ['.json'] 做一个测试
{ resolve: { extensions:['.json'] }}
此时因为援用index2.js时还是没有增加后缀,打包编译时就间接报错了。
而援用index2.js增加 .js 后缀名称才能够打包胜利。。
<font style="color:cornflowerblue">vue-cli</font>、<font style="color:cornflowerblue">react-cli</font>这类脚手架都会在resolve.extensions属性配置本人文件类型的后缀名称。
在此以<font style="color:cornflowerblue">react-cli</font>为例
打包编译时匹配resolve.extensions,应用的是队列模式。Array从先到后
mainFiles
应用<font style="color:cornflowerblue">vue-cli</font>这类脚手架,开发时引入本地文件模块,有一种常见形式只指定其文件所在目录,并没有指定文件名称。
这种形式常见于以 目录为组件单元的代码格调。例如<font style="color:cornflowerblue">antd</font>,就是以目录为组件单元。
这个性能是由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
配置<font style="color:cornflowerblue">webpack</font>时,应用文件目录时都应用了相对地址:path.join(__dirname, ...)
<font style="color:cornflowerblue">webpack</font>其实提供了一个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属性还是绝对路径都无伤大雅,集体习惯罢了,只有文件门路正确即可
总结
- <font style="color:cornflowerblue">webpack</font>提供了两种<font style="color:cornflowerblue">打包模式</font>: *开发测试打包编译 (development) 和 *线上公布打包编译 (production) 。两种打包模式可能更加方便管理<font style="color:cornflowerblue">插件</font>
- <font style="color:cornflowerblue">webpack</font>对development和 production 都预设了一些根底性能,大大减少了开发时的配置
- <font style="color:cornflowerblue">source-map</font>是<font style="color:cornflowerblue">Google</font>提供的打包编译后代码与开发代码的一种映射文件,主要用途是不便开发人员调试
- optimization属性是<font style="color:cornflowerblue">webpack</font>提供的管制优化的属性, optimization只是一系列优化性能的汇合,次要是为了方便管理,实质还是由<font style="color:cornflowerblue">插件</font>实现性能
- resolve属性提供了打包编译时的解析规定,
如果此篇对您有所帮忙,在此求一个star。我的项目地址: OrcasTeam/my-cli
本文参考
- 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