最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从零学脚手架(三)---webpack属性详解

    正文概述 掘金(yanzhangshuai)   2021-03-10   769

    在上一篇中,介绍了 webpack 的 entryoutputplugins 属性。

    在这一篇,接着介绍其它配置属性。

    mode

    这个属性在上一篇中使用过一次:设置 webpack 编译模式,那么这个属性到底是什么东西呢?

    打包器是将开发环境代码 编译 为可部署环境代码

    搭建的 工程化 代码基本都无法直接运行在浏览器,所以本地测试也都是使用打包编译后的代码预览。

    但是本地开发预览又必须具有代码可读性、可调试性等条件。

    webpack 为了解决这个问题,就提供了两种 打包模式:开发模式(development)和发布模式(production)

    mode属性设置

     {
       mode:'development'
     }
    

    也可以使用 CLI参数 进行设置

    从零学脚手架(三)---webpack属性详解

    测试两种模式的区别时,最直观区别就是查看编译生成的代码是否进行了压缩:在 production 模式下,webpack 会预设压缩 plugin

    webpack中的 mode 属性值其实具有三个:developmentproductionnone

    none 属性值与两者的区别只是没有预设任何 插件

    下面来介绍下 developmentproduction 两种模式中的预设的部分功能

    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 : NamedModulesPluginNamedChunksPlugin

    webpack@5.X版本设置代码可读性使用的是 optimization.moduleIdsoptimization.chunkIds 两个属性。

    但根源也是使用内置plugin:NamedModuleIdsPluginNamedChunkIdsPlugin

    optimization: {
        moduleIds: 'named',
        chunkIds: 'named',
    }
    
    设置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:NamedModulesPluginNamedChunksPlugin

    webpack@5.X 版本设置代码可读性使用的是 optimization.moduleIdsoptimization.chunkIds 两个属性,但根源也是使用内置plugin:DeterministicModuleIdsPluginDeterministicChunkIdsPlugin

    optimization: {
        moduleIds: 'deterministic',
        chunkIds: 'deterministic',
    }
    
    代码压缩

    production 模式时,webpack 开启了代码压缩优化 ,使用terser-webpack-plugin库对打包生成代码进行压缩

    作用域提升

    production模式时,webpack 会使用内置的 ModuleConcatenationPlugin 对代码的作用域进行提示。用于减少打包生成的代码量和执行速度。

    错误处理

    production模式时,webpack 会预设内置 NoEmitOnErrorsPlugin

    打包编译时,如果出现代码错误,则不在生成代码。用于避免代码错误代码依然打包成功

    DefinePlugin

    developmentproduction 两种模式中, 都设置了一个环境变量属性: process.env.NODE_ENV ,只是属性值不相同。

    环境变量用于编写业务代码时 针对不同环境下的差异化代码。例如调用第三方SDK时:区分 开发环境 和 正式环境。

    当然可以选择每次发版时手动修改配置,只要自己不会觉得麻烦。

    做一个测试

    /src/index.js 中输出 process.env.NODE_ENV 属性

    从零学脚手架(三)---webpack属性详解

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

    从零学脚手架(三)---webpack属性详解

    同样如果执行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 模式下生成的,也是超级混乱。

    而想要对这些代码调试排查错误,那简直是个噩梦。

    从零学脚手架(三)---webpack属性详解

    对于这个问题,Google 提供了一种工具叫做:javascript-source-map

    javascript-source-map  提供一个映射信息,将 打包编译生成的代码开发编写的代码文件 进行映射,调试时直接针对 开发编写的代码文件进行调试。

    webpack提供了 devtool 属性来设置 javascript-source-map

    development 模式 devtool 属性默认值为 eval

    production 模式 devtool 属性默认值为 false(none)

    eval 属性值生成的代码都是由 eval 语法编译,并提供了一个 sourceURL 属性用于指向文件源路径

    从零学脚手架(三)---webpack属性详解

    devtool 属性具有非常多的属性值,不同的属性值 操作具有差异 和 打包消耗时间不同。

    有的属性值会生成一个 .map 文件,个文件中存放映射信息,有的直接在生成文件中显示映射信息。

    在此就不不详细介绍 devtool,有兴趣的朋友可以参考官网自行测试

    {
    	//	属性可以设置为false和字符串
    	devtool:false; // 'eval'
    }
    

    optimization

    webpack 针对代码优化管理,提供了 optimization 属性进行管理。

    就像刚才介绍的 optimization.moduleIdsoptimization.chunkIds 提供了对 模块模块名称 管理。

    但其根源还是使用了插件进行管理,属性只是为了方便管理。

    optimization 对象具有好多属性,在此也不详细介绍,

    只介绍 optimization.minimizeoptimization.minimizer 。这两个也是经常被使用到属性。

    minimize和minimizer

    minimize

    先来做一个测试,将 optimization.minimize 手动改为 false

      optimization:{
        minimize:false
      }
    

    此时使用yarn build执行打包可以看到代码并没有进行压缩

    从零学脚手架(三)---webpack属性详解

    也就是 optimization.minimize 属性是控制代码压缩的。

    production 模式只是将 optimization.minimize 设置为了 true

    从零学脚手架(三)---webpack属性详解
      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属性的开关。

    从零学脚手架(三)---webpack属性详解

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

    从零学脚手架(三)---webpack属性详解

    如果terser-webpack-plugin 手动设置在plugins属性中,

    那么就算optimization.minimizefalse,代码依然会压缩。

    从零学脚手架(三)---webpack属性详解

    optimization.minimizeoptimization.minimizer是webpack为方便管理提供的属性。

    在配置时可以将关于优化的plugin设置在optimization.minimizer属性,由optimization.minimize统一管理。

    而webpack提供的一系列默认值提供了最小配置。

    代价却提高了webpack学习成本。让很多人对这些属性感到迷惑。

    terser-webpack-plugin

    terser-webpack-plugin 作为webpack@5.X默认的压缩工具。在此就直接介绍此库的属性

    在刚才手动设置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:指定压缩的文件

      属性可设置为:StringString[]Regex

      默认值为:undefined

    • exclude:排除压缩的文件

      属性可设置为:StringString[]Regex

      默认值为:undefined

    • parallel:是否启用多线程运行

      属性可设置为:BooleanNumber

      属性值为false:不启动多线程

      属性值为true:启动多线程,多线程数量为:os.cpus()-1

      属性值为Number:表示使用的多线程数量

      默认值为:true

    • minify:设置其它压缩工具覆盖terser-webpack-plugin

      此属性可以设置一个函数,函数内允许使用其它压缩工具替代terser-webpack-plugin, 其实相当于做了一个拦截,基本上不会使用此属性。 详细介绍可以参考 官方

      属性可设置为:Function

      默认值为undefined

    • extractComments:是否将代码注释提取到一个单独的文件。

      经过压缩的代码都会去除注释,此属性就是设置是否提取注释,个人感觉这个属性也没什么用。详细介绍可以参考 官方

      属性可设置为:BooleanStringRegExpFunction<(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中创建这么一个函数

    从零学脚手架(三)---webpack属性详解

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

    从零学脚手架(三)---webpack属性详解

    默认terser-webpack-plugin配置基本上做到了最优解。

    terser-webpack-plugin配置属性中:terserOptions.compress属性才是控制压缩。

    terserOptions.compress 设置类型为 BooleanObject

    接下来将此属性设置为false。查看打包编译代码,可以发现,代码并没有被压缩,只是改变了属性名称和函数函数

    {
       optimization: {
        // 配置可优化
        minimize: true,
        minimizer: [
          new TerserPlugin({
            //  压缩时的选项设置
            terserOptions: {
                 compress:false
            }
          })
        ]
      }
    }
    
    从零学脚手架(三)---webpack属性详解

    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:指定压缩格式。例如是否保留注释,是否始终为iffor等设置大括号。

      formatoutput的配置相同。output官方不再推荐使用。这个属性就不介绍,具体请参考官方

      属性可设置为:Object

      默认值为null

    • ie8:是否支持IE8

      属性可设置为:Boolean

      默认值为false

    • compress:设置压缩选项

      属性可设置为:BooleanObject

      属性值为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去除所有consoleparallel来设置多线程

    其它一般都是默认值即可。

    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$ 表示拦截所有的.css文件。使用Regex可以拦截多种文件类型使用同一loader

      属性可设置为:Regex

    • include:包含拦截的文件目录。

      此属性可以设置拦截指定目录的文件,一般使用此属性设置只拦截 /src 目录中文件

      属性可设置为:String

    • exclude:排除拦截的文件目录。

      此属性与include类似,只不过功能相反,指定要排除的目录。一般使用此属性排除node_modules目录。

      此属性与include只使用一种。

      属性可设置为:String

    • use:拦截到的文件所使用的loader。

      属性可设置为:StringArray

      属性值为String:设置loader 名称

      属性值为Array:可以指定多个loader 处理,并且可以对每一个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属性详解 从零学脚手架(三)---webpack属性详解

    extensions

    使用vue-cli这类脚手架,开发时引入本地文件模块。很常见的一种行为就是不需要添加后缀名称。

    这个功能就是resolve.extensions提供的。

    resolve.extensions功能允许设置多个后缀名称。导入文件模块时可以忽略文件后缀名称,

    打包编译时按照配置缀顺序依次匹配,直到寻到第一个匹配文件或报错(找不到匹配文件)。

    resolve.extensions属性类型为Array,默认值为:['.js', '.json'],也就是可以忽略JS文件和JSON文件后缀

    下面将resolve.extensions设置为 ['.json'] 做一个测试

    {
       resolve: {
        extensions:['.json']
      }
    }
    

    此时由于引用index2.js时还是没有添加后缀,打包编译时就直接报错了。

    从零学脚手架(三)---webpack属性详解

    而引用index2.js添加 .js 后缀名称才可以打包成功。。

    vue-cli、react-cli这类脚手架都会在resolve.extensions属性配置自己文件类型的后缀名称。

    在此以react-cli为例

    从零学脚手架(三)---webpack属性详解 从零学脚手架(三)---webpack属性详解

    mainFiles

    使用vue-cli这类脚手架,开发时引入本地文件模块,有一种常见方式只指定其文件所在目录,并没有指定文件名称。

    这种方式常见于以 目录为组件单元的代码风格。例如antd,就是以目录为组件单元。

    从零学脚手架(三)---webpack属性详解

    这个功能是由resolve.mainFiles属性提供的。

    resolve.mainFiles允许设置多个文件名称,导入文件模块时可以忽略此文件名称。

    打包编译时按照配置缀顺序依次匹配,直到寻到第一个匹配文件或报错(找不到匹配文件)。

    resolve.extensions属性类型为Array,默认值为:['index'],也就是可以忽略index名称的文件。

    下面将resolve.mainFiles设置为 ['index','main'] 做测试

    {
       resolve: {
       	extensions:['.js','.json'],
        mainFiles:['index','main'],
      }
    }
    
    从零学脚手架(三)---webpack属性详解 从零学脚手架(三)---webpack属性详解

    可以看到, 可以看到导入 /demo/main.js 时,忽略了文件名称,但是依然打包编译、导入成功

    context

    配置webpack时,使用文件目录时都使用了绝对地址:path.join(__dirname, ...)

    webpack其实提供了一个context属性:在配置项中允许 以此目录为基准 设置 相对目录。

    不过context属性个人感觉并不太好用。

    context属性String类型,设置一个绝对路径的目录地址

    context默认值为当前项目根目录,也就是package.json文件所在目录

    context属性默认值为当前项目根目录,所以可以直接使用相对路径

    {
        entry: './src/index.js' ,
    }
    

    此时执行yarn build打包也可以进行打包成功。

    从零学脚手架(三)---webpack属性详解

    也可以使用context指定其它目录为基准目录

    {
      context: path.join(__dirname, './src'),
      //  入口文件
      //  字符串形式
      entry: './index.js' ,
    }
    

    context属性具有一定的缺陷

    output不允许相对路径

    并不是所有的属性都可以设置为相对路径

    例如output属性就只允许使用绝对路径。

    从零学脚手架(三)---webpack属性详解

    配置属性中既有相对路径又有绝对路径,对于我这个强迫症来说感觉怪怪的。

    基准绝对路径

    个人比较喜欢的方案就是自定义一个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属性还是绝对路径都无伤大雅,个人习惯罢了,只要文件路径正确即可

    总结

    如果此篇对您有所帮助,在此求一个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
    
    

    起源地下载网 » 从零学脚手架(三)---webpack属性详解

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元