# esbuild插件基础介绍
esbuild 插件是一个带有 name 和一个 setup 函数的对象, 该 setup 函数为每个构建 API 调用运行一次。
# 案例1
当你在代码中导入一个不存在的模块, 或者是esbuild无法解析的文档的时候, 很明显,env是一个并不真正存在的文件, 是一个虚拟文件, 最终打最印出来的结果是process.env的环境变量。可以通过以下方式进行模块拦截,分配虚拟空间, 进行转换代码。
import { PATH } from 'env'
console .log( `PATH is ${PATH} ` )
let envPlugin = {
name : 'env' ,
setup ( build ) {
// 拦截名为“env”的导入路径,因此 esbuild 不会尝试
// 将它们映射到文件系统位置。用“env-ns”
// 命名空间标记它们,以便为这个插件保留它们。
build.onResolve({ filter : /^env$/ }, args => ({
path : args.path,
namespace : 'env-ns' ,
}))
// 加载带有“env-ns”命名空间标记的路径
// 它们指向包含环境变量的 JSON 文件。
build.onLoad({ filter : /.*/ , namespace: 'env-ns' }, () => ({
contents : JSON.stringify(process.env),
loader : 'json' ,
}))
},
}
# plugin 对象属性
- name
表示插件的名称。
- setup
表示插件调用的函数。
# onResolve
filter 通过正则匹配用来拦截导入的模块名称或者文件路径, 当遇到不支持解析的文件或者虚拟文件, 返回当前解析后的 path 可以通过 namespace 进行分配虚拟空间, 等待 onload 进行转换代码内容和指定 esbuild 可解析的文件后缀。
提示
如果返回值不设置namespace, path 则需要返回绝对路径。
# onLoad
filter 通过正则匹配用来拦截导入的模块名称或者文件路径, 同时满足 namespace 分配的虚拟空间,两者都满足时将通过 onload 进行自定义转换,contents 则是转换的文件的内容,loader 则是告诉 esbuild 构建内容时视为那种模块类型进行处理,不同的后缀esbuild 构建的方式也不同。
# 案例2
可以通过插件改变导入的模块。
导入模块作为外部引用, 不需要
bundle到主文件中。
// main.js
// 构建文件
import Image from 'images/a.jpg'
import Url from 'https://www.cdn-XXXXXXX.js'
let exampleOnResolvePlugin = {
name: 'example',
setup(build) {
let path = require('path')
// 将以“images/”开头的所有路径重定向到“./public/images/”
build.onResolve({ filter: /^images\// }, args => {
return { path: path.join(args.resolveDir, 'public', args.path) }
})
// 标记所有以“http://”开头的路径或“https://”作为外部
build.onResolve({ filter: /^https?:\/\// }, args => {
return { path: args.path, external: true }
})
},
}
# 替换模块
通过 filter 拦截到 images/ 开头的模块, 通过执行第二个参数方法的返回值确认替换结果, 方法执行时参数返回一个 args 对象, 代表以下内容:
resolveDir导入模块代码的文件所在的目录/user/demo/srcimporter导入模块代码的文件地址/user/demo/src/main.jspath导入的模块名称或者路径地址 (相对路径,绝对路径, npm包名称, 自定义虚拟名称) 等。
# 过滤模块
当拦截到 http 或者 https 开头的路径, 最后返回的时候可以通过 external 设置 true, 将会过滤对当前导入的模块, 当前模块不进行构建,还是以import 语法的方式进行导入, 不将源代码构建入主入口中, 同时当前被过滤的模块中内部导入的模块也会被过滤。