千家信息网

如何配置Webpack

发表于:2024-09-30 作者:千家信息网编辑
千家信息网最后更新 2024年09月30日,本篇内容主要讲解"如何配置Webpack",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何配置Webpack"吧!为什么出现 webpack-chain
千家信息网最后更新 2024年09月30日如何配置Webpack

本篇内容主要讲解"如何配置Webpack",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何配置Webpack"吧!

为什么出现 webpack-chain ?

相信大家都对业界鼎鼎有名的构建工具Webpack并不陌生了,作为目前为止最稳定、生产环境应用最多的构建打包工具,它固然有着很多优势,比如:

  • 生态丰富。在社区有大量的 loader 和 plugin,想要的基本都能找到。

  • 可插拔的插件机制。基于 Tapable 实现的可扩展架构。

  • 文档成熟。有中文版,且一直在更新和维护。

  • 稳定性高。现在正式的前端项目生产环境下基本用 Webpack 来构建,经过这么多年业界的验证,该踩的坑也都踩的差不多了。

但其实说了这么多优势,大家估计还是对这个东西没什么好感,因为还有最重要的一点不容忽视,那就是开发体验。对于构建打包这个事情来说,本来就是工程化当中的一个细节极其复杂的环节,需要输入大量的配置信息来保证打包结果符合预期。在Webpack当中,我们如果不用其他的方案,就只有手动地配置一个巨大的 JavaScript 对象,所有的配置信息都在这个对象当中,这样原始的方式的确给人体验很不好,归纳为以下几个原因:

  1. 鸿蒙官方战略合作共建--HarmonyOS技术社区

  2. 对象过于庞大,直观上让人看的眼花缭乱,尽管可以封装一些逻辑,但还是避免不了深层的嵌套配置;

  3. 难以动态修改。举个例子,如果通过脚本动态修改一些配置信息,比如删除 babel-loader 的一个 plugin,那么需要从最顶层的配置对象,一步步找到到 babel-loader 的位置,然后遍历插件列表,这个手动寻找和遍历的过程比较繁琐。

  4. 难以共享配置。如果你尝试跨项目共享 webpack 配置对象,那后续的修改就会变的混乱不堪,因为你需要动态地修改原来的配置。

社区当中也有人发现了这些痛点,于是出现了针对Webpack的流式配置方案——webpack-chain。

webpack-chain 核心概念

其实真正学会 webpack-chain,我觉得首先不是去学习具体每个属性的配置方法,而是理解webpack-chain核心的两个对象——ChainedMap和ChainedSet。

什么是 ChainMap ?

比如我现在配置路径别名:

config.resolve.alias   .set(key, value)   .set(key, value)   .delete(key)   .clear()

那么,现在的 alis 对象就是一个ChainMap。如果一个属性在webpack-chain当中标记为ChainMap之后,它会有一些额外的方法,并且允许这些链式调用(如上面的示例)。

接下来就来一个个认识这些方法:

// 清空当前 Map 的所有属性 clear() // 通过键值从 Map 移除单个配置. delete(key) // Map中是否存在一个配置值的特定键,返回真或假 has(key) // 返回 Map中已存储的所有值的数组 values() //  提供一个对象,这个对象的属性和值将映射进 Map。第二个参数为一个数组,表示忽略哪些属性 merge(obj, omit) // handler: ChainedMap => ChainedMap // 一个把ChainedMap实例作为单个参数的函数 batch(handler) // condition: Boolean // whenTruthy: ChainMap -> any, 条件为真时执行 // whenFalsy: ChainSet -> any, 条件为假时执行 when(condition, whenTruthy, whenFalsy) // 获取 Map 中相应键的值 get(key) // 先调用 get,如果找不到对应的值, 就返回 fn 函数返回的结果 getOrCompute(key, fn) // 配置键值对 set(key, value)

这些方法的返回对象也都是 ChainMap,这样可以实现链式调用,简化操作。在 Webpack中,大部分的对象都是 ChainMap,具体大家可以去源码当中看看,实现并不复杂。

ChainMap 是webpack-chain当中非常重要的一个数据结构,封装了链式调用的方法,以至于后面所有 ChainMap 类型的配置都可以直接复用ChainMap本身的这些方法,非常方便。

什么是 ChainSet ?

跟 ChainMap 类似,封装了自己的一套 API:

// 末尾增加一个值 add(value) // 在开始位置增加一个值 prepend(value) // 清空 set 内容 clear() // 删除某个值 delete(value) // 判断是否有某个值 has(value) // 返回值列表 values() // 合并给定的数组到 Set 尾部。 merge(arr) // handler: ChainSet => ChainSet // 一个把 ChainSet 实例作为单个参数的函数 batch(handler) // condition: Boolean // whenTruthy: ChainSet -> any, 条件为真时执行 // whenFalsy: ChainSet -> any, 条件为假时执行 when(condition, whenTruthy, whenFalsy)

ChainSet 的作用和ChainMap类似,也是封装了底层链式调用的 API,在需要操作Webpack配置当中的数组类型的属性时,通过调用ChainSet的方法即可完成。

速记方法

对于 ChainMap,有这样一种简化的写法,官网称之为速记写法:

devServer.hot(true);  // 上述方法等效于: devServer.set('hot', true);

因此,在实际的webpack-chain配置中,可以经常看到直接 .属性()这样调用方式,是不是感觉很巧妙?源码当中的实现非常简单:

extend(methods) {   this.shorthands = methods;   methods.forEach(method => {     this[method] = value => this.set(method, value);   });   return this; }

在ChainMap初始化的时候,会调用 extend 方法,然后把属性列表作为 methods参数直接传入,然后通过下面一行代码间接调用 set 方法:

this[method] = value => this.set(method, value);

这样的设计也是值得学习的。

配置 Webpack

首先,需要创建一个新的配置对象:

const Config = require('webpack-chain');  const config = new Config();  // 一系列链式操作之后 // 得到最后的 webpack 对象 console.log(config.toConfig())

然后依次配置 resolve、entry、output、module、plugins、optimization 对象,本文关键还是带大家能够落地 webpack-chain,因此详细介绍一下各个配置的使用方法。

entry 和 output

这里列举一个常用的配置,由于 Webpack 在 entry 和 output 挂了太多属性,大家参考 Webpack 官方文档照着如下的方式去配就好了。

config.entryPoints.clear() // 会把默认的入口清空 config.entry('entry1').add('./src/index1.tsx')//新增入口 config.entry('entry2').add('./src/index2.tsx')//新增入口  config.output       .path("dist")       .filename("[name].[chunkhash].js")       .chunkFilename("chunks/[name].[chunkhash].js")       .libraryTarget("umd")

alias

对于路径别名的配置,也是几乎所有项目必不可少的部分,配置方式如下:

// 可以发现 resolve.alias 其实是一个 ChainMap 对象 config.resolve.alias   .set('assets',resolve('src/assets'))   .set('components',resolve('src/components'))   .set('static',resolve('src/static'))   .delete('static') // 删掉指定的别名

plugins

插件的配置可以说是相当重要的一个环节了,webpack-chain 当中的配置会和平时的配置有些不同,让我们来具体看看。

1. 添加一个插件

// 先指定名字(这个名字是自定义的),然后通过 use 添加插件 config   .plugin(name)   .use(WebpackPlugin, args)

举个例子:

const ExtractTextPlugin = require('extract-text-webpack-plugin');  // 先指定名字(这个名字可以自定义),然后通过 use 添加插件,use 的第二个参数为插件参数,必须是一个数组,也可以不传 config.plugin('extract')   .use(ExtractTextPlugin, [{     filename: 'build.min.css',     allChunks: true,   }])

2. 移除插件

移除一个插件很简单,还记得添加插件时我们指定了每个插件的 name 吗?现在通过这个 name 移除即可:

config.plugins.delete('extract')

3. 指定插件在 xx 插件之前/之后调用

比如,我现在需要指定 html-webpack-plugin 这个插件在刚刚写的 extract 插件之前执行,那么这么写就行了:

const htmlWebpackPlugin = require('html-webpack-plugin');  config.plugin('html')   .use(htmlWebpackPlugin)   .before('extract')

通过 before 方法,传入另一个插件的 name 即可,表示在另一个插件之前执行。

同样,如果需要在 extract 插件之后执行,调用 after 方法:

config.plugin('html')   .use(htmlWebpackPlugin)   .after('extract')

4. 动态修改插件参数

我们也可以用 webpack-chain 来动态修改插件的传参,举个例子:

// 使用 tap 方法修改参数 config   .plugin(name)   .tap(args => newArgs)

5. 修改插件初始化过程

我们也可以自定义插件的实例化的过程,比如下面这样:

// 通过 init 方法,返回一个实例,这将代替原有的实例化过程 config   .plugin(name)   .init((Plugin, args) => new Plugin(...args));

loader

loader 是 Webpack 中必不可少的一个配置,下面我们来看看 loader 的相关操作。

1. 添加一个 loader

config.module   .rule(name)     .use(name)       .loader(loader)       .options(options)

举个例子:

config.module   .rule('ts')   .test(/\.tsx?/)   .use('ts-loader')     .loader('ts-loader')     .options({       transpileOnly: true     })     .end()

2. 修改 loader 参数

可通过 tap 方法修改 loader 的参数:

config.module   .rule('ts')   .test(/\.tsx?/)   .use('ts-loader')     .loader('ts-loader')     .tap(option => {       // 一系列       return options;     })     .end()

在所有的配置完成之后,可以通过调用config.toConfig()来拿到最后的配置对象,可以直接作为webpack的配置。

3. 移除一个 loader

// 通过 uses 对象的 delete 方法,根据 loader 的 name 删除 config.module   .rule('ts')   .test(/\.tsx?/)   .uses.delete('ts-loader')

optimization

Webpack 中的optimization也是一个比较庞大的对象,参照官方文档:https://webpack.js.org/configuration/optimization/。

这里以其中的 splitChunks 和 minimizer 为例来配置一下:

config.optimization.splitChunks({      chunks: "async",      minChunks: 1, // 最小 chunk ,默认1      maxAsyncRequests: 5, // 最大异步请求数, 默认5      maxInitialRequests : 3, // 最大初始化请求数,默认3      cacheGroups:{ // 这里开始设置缓存的 chunks          priority: 0, // 缓存组优先级          vendor: { // key 为entry中定义的 入口名称              chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是async)              test: /react|vue/, // 正则规则验证,如果符合就提取 chunk              name: "vendor", // 要缓存的 分隔出来的 chunk 名称              minSize: 30000,              minChunks: 1,          }      } });  // 添加一个 minimizer config.optimization   .minimizer('css')   .use(OptimizeCSSAssetsPlugin, [{ cssProcessorOptions: {} }]) // 移除 minimizer config.optimization.minimizers.delete('css') // 修改 minimizer 插件参数 config.optimization   .minimizer('css')   .tap(args => [...args, { cssProcessorOptions: { safe: false } }])

善用条件

配置之前提到过,对于ChainSet和ChainMap对象都有条件配置方法when,可以在某些很多场景下取代 if-else,保持配置的链式调用,让代码更加优雅。

config.when(   process.env.NODE === 'production',   config.plugin('size').use(SizeLimitPlugin) )

到此,相信大家对"如何配置Webpack"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

配置 插件 方法 对象 参数 属性 条件 链式 动态 实例 数组 例子 入口 名字 就是 方式 过程 学习 封装 重要 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 派出所开展网络安全大排查 steam方舟服务器错误代码 穿越火线各国服务器比赛 视频服务器128路什么意思 慈溪现代化刀片服务器售后服务 自己在电脑上做服务器 上千台服务器管理 2021 长安杯 网络安全极客 华科考研网络安全 互联网科技公司的宗旨 互联网保险是一种高科技保险吗 电脑软件开发职校 涌涌易网络技术有限公司 我的世界宝可梦神奇宝贝服务器 5g新型软件开发 联想网络安全命令模式怎么改密码 海外空间服务器 修改数据库文件的sql语句 电脑开机网络安全模式卡在 国际服和日韩服是一个服务器吗 派出所开展网络安全大排查 数据库的系统核心是 2016年网络安全伊胜伟 彩虹六号异种连不上服务器 怀柔区正规软件开发价位 绿色书签2020网络安全手抄报 佛山市新宝网络技术有限公司 服务器图片管理 浦东新区综合软件开发协议 从数据库同时查询多条
0