《Webpack5 核心原理与应用实践》学习笔记-> loader配置效验与内置工具

简介: 《Webpack5 核心原理与应用实践》学习笔记-> loader配置效验与内置工具


webpack为loader提供了一系列的配置属性,同时也为提取这些配置属性提供了一系列的工具方法,这些东西原先并不是webpack本身就包含的,只是用的地方多了, 他就放进去了。

使用 schema-utils


schema-utils是验证一个对象中是否包含这个这个属性,并且这个属性是否符合预期值,正好webpack中的loaderplugin都会有大量的配置,那就正好可以使用这个工具包来验证配置是否符合预期,用法如下:


  1. 安装依赖:npm i -D schema-utils
  2. 编写代码:


// 引入 schema-utils ,里面有一个 validate 函数
const { validate } = require('schema-utils');
// 定义预期配置值
const schema = {
    "type": "object",
    "properties": {
        // 有一个 name 属性,属性值为 boolean
        "name": {
            "type": "boolean"
        }
    },
    // name 属性值必须要有
    "required": ["name"],
    // 不能使用其他没有被声明的属性值
    "additionalProperties": false
}
validate(schema, {name: ''}); // name 属性值不是 boolean 报错
validate(schema, {name: true, a: ''}); // 有其他没有被声明的属性值报错

一般在loader中使用的时候,配置量比较大可以定义为外部.json文件:


const { validate } = require('schema-utils');
// 定义外部json文件
const schema =  require('./schema.json');
function loader(source, sourceMap, data) {
    // 获取loader配置
    const options = this.getOptions();
    validate(schema, options);
    this.callback(
        null,
        source,
        sourceMap,
        data
    );
}
module.exports = loader

webpack5之后,可以简化上面的流程:


const schema =  require('./schema.json');
function loader(source, sourceMap, data) {
    this.getOptions(schema);
    return source;
}
module.exports = loader

如果验证不合规,schema-utils会抛出异常,如下

image.png

抛出异常自然就会阻断后续的任务,除非你捕获异常。


schema-utils 的校验能力很强,其实了解这个工具后,不仅可以在webpackloaderplugin中去验证配置,还可以在其他你任何需要验证的地方使用。


schema-utils 内部使用 ajv 的 JSON-Schema模式实现参数校验,而 JSON-Schema 是一种以 JSON 格式描述数据结构的 公共规范,使用时至少需要提供 type 参数,如:


{
  "type": "number"
}

ajv默认支持下面这些基础属性(不想做搬运工,下面的就简写了,感兴趣的自行查看文档):


  • number:数值型,支持整数、浮点数,支持如下校验规则:


maximumminimumexclusiveMaximumexclusiveMinimummultipleOf

  • interger:整数型,与 number 类似,也支持上面介绍的 maximum 等校验规则;
  • string:字符串型,支持如下校验规则:


maxLengthminLengthpatternformat

  • boolean:bool 值;
  • array:数组型,支持如下校验属性:


maxItemsminItemsuniqueItemsitems

  • null:空值,常用于复合 type 类型,如 type = ['object', 'null'] 支持传入对象结构或 null 值;
  • object:对象结构,这是一个比较负责的结构,支持如下校验属性:


maxProperties / minPropertiesrequiredproperties

  • patternProperties:同样用于定义对象属性的 Schema,但属性名支持正则表达式形式,例如:


{
  type: "object",
  patternProperties: {
    "^el-.*$": {type: "string"},
    "^a-.*$": {type: "string"}
  }
}

  • additionalProperties:限定对象是否可以提供除 propertiespatternProperties 之外的属性;


上面的这些是基本的配置属性解释,除了上面这些还有其他的通用规则字段: enum:枚举数组; const:静态数值,属性值必须完全等于 const 定义;


还有复合指令:


  • not:数值必须不符合该条件,例如:{type: "number", not: {minimum: 3}} 时,传入数值必须小于 3;
  • anyof:数值必须满足 anyof 条件之一;
  • oneof:数值必须满足且只能满足 oneof 条件之一;
  • allof:数值必须满足 allof 指定的所有条件;
  • if/then/else:这个有点绕,所以我翻译一下:


{
    "type": "object",
    "if": {"properties": {"foo": {"minimum": 10}}},
    "then": {"required": ["bar"]},
    "else": {"required": ["baz"]}
}

配置长上面这样,直接用代码翻译:


if (option.foo < 10) {
    if (option.bar == null) {
        throw new Error()
    }
} else {
    if (option.baz == null) {
        throw new Error()
    }
}

口语瞎 J er 翻译:


if-> 如果传进来的配置满足:有一个 foo 的属性,它的值必须小于 10

then-> 如果通过了if老哥的考验,那么传进来的属性中 必须有一个 bar 属性

else-> 如果没有通过if老哥的考验,那么传进来的属性中 必须有一个 baz 属性


大白话翻译:


满足if的条件就需要进入then,然后再满足then的条件,不满足if的条件就需要进入else,然后满足else的条件。


这些基础数据类型与校验规则让我们可以非常完善的属性规则定义,再也不必写a != null || typeof a === 'string' ...这样的验证代码了,我们使用 schema-utils 时大部分时间都需要构建这些配置体系,所以简写就是让你多看文档。


使用 loader-utils


loader-utils见名知意,就是webpack开发loader的工具类,据说在webpack5之前这玩意很重要,别问为什么是据说,因为我在webpack5之前就没开发过loader,然后webpack5看这玩意这么多人用,还用的这么频繁,就给里面的一些功能,做到了loader注入的上下文中了。


被裁减后的 loader-utils 仅保留了四个接口:


  • urlToRequest:用于将模块路径转换为文件路径的工具函数;
  • isUrlRequest:用于判定字符串是否为模块请求路径;
  • getHashDigest:用于计算内容 Hash 值;
  • interpolateName:用于拼接文件名的模板工具;


课程中只讲了interpolateName,说上面的三个没多少地方使用,就没讲了。


在配置webpack的时候,output.filename属性支持[path]/[name].[ext]这样的占位符,用interpolateName这个方法就可以做到这样的效果,使用方法如下:


const {interpolateName} = require('loader-utils');
function loader(source, sourceMap, data) {
    const url = interpolateName(this, "js/[hash].script.[ext]", { content: source });
    this.emitFile(url, source);
    return source;
}
loader.pitch = function (remainingRequest, previousRequest, data) {
}
module.exports = loader

interpolateName支持如下占位符,:

  • [ext]:原始资源文件的扩展名;
  • [name]:原始文件名;
  • [path]:原始文件相对 context 参数的路径;
  • [folder]:原始文件所在的文件夹;
  • [query]:查询参数,即?foo=bar
  • [contenthash]:文件内容hash


上面这些占位符在官网里面都有详细的解释,之前有提到过,而且这里的占位符没有Template String全。


总结


了解schema-utilsloader-utils能更高效的开发loaderloader-utils是为loader服务的,但是schema-utils并不是只为loader服务,了解这些工具,可以让你的开发更高效和稳定。


目录
相关文章
|
3月前
|
Web App开发 JSON 前端开发
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
53 0
|
4月前
|
JSON 前端开发 JavaScript
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)(上)
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
56 0
|
4天前
|
前端开发 JavaScript 开发者
深入了解Webpack:前端模块打包工具
深入了解Webpack:前端模块打包工具
8 1
|
6天前
|
JavaScript 前端开发
构建工具:配置Webpack打包Vue项目
【4月更文挑战第24天】本文介绍了如何配置Webpack来打包Vue项目。首先,Webpack作为模块打包器处理依赖并打包成可执行文件。接着,通过安装Node.js和npm,创建Vue项目,进入项目目录并配置Webpack的入口、输出、加载器和插件。最后,运行构建命令完成打包。理解Webpack基础并按需配置,能优化前端项目构建和开发体验。
|
2月前
|
存储 前端开发 文件存储
webpack成长指北第5章---webpack的基础配置
webpack成长指北第5章---webpack的基础配置
26 0
|
3月前
|
前端开发 JavaScript Java
|
4月前
|
域名解析 JavaScript 前端开发
TypeScript笔记(3)—— 使用WebPack工具
TypeScript笔记(3)—— 使用WebPack工具
25 0
|
4月前
|
前端开发 JavaScript
webpack 核心武器:loader 和 plugin 的使用指南(下)
webpack 核心武器:loader 和 plugin 的使用指南(下)
webpack 核心武器:loader 和 plugin 的使用指南(下)
|
4月前
|
JSON 前端开发 JavaScript
webpack 核心武器:loader 和 plugin 的使用指南(上)
webpack 核心武器:loader 和 plugin 的使用指南(上)
webpack 核心武器:loader 和 plugin 的使用指南(上)
|
4月前
|
人工智能 移动开发 前端开发
【利用AI让知识体系化】Webpack 相关配置技巧(三)
【利用AI让知识体系化】Webpack 相关配置技巧