esbuild 的 --target 指定同一引擎多个版本时为什么以最低版本生效
esbuild 的 --target 指定同一引擎多个版本时为什么以最低版本生效【免费下载链接】esbuildAn extremely fast bundler for the web项目地址: https://gitcode.com/GitHub_Trending/es/esbuild配置 esbuild 构建时--target允许传入逗号分隔的多个目标环境。如果同一个引擎被写了多次例如--targetchrome1,chrome99最终输出的语法限制由其中的最低版本chrome1决定。这篇文章解释这个行为的原因、修复前后的差异以及如何验证当前使用的 esbuild 版本走的是哪套逻辑。--target的语义输出受限于所有目标都支持的特性理解最低版本生效之前先要理解--target对多个目标的处理规则。esbuild 的--target从 CHANGELOG-2020.md 记录的一次更新开始接受逗号分隔的列表可以逐个指定 JavaScript 环境例如esbuild entry.js --targetchrome58,firefox57,safari11,edge16多目标的核心语义在 CHANGELOG-2022.md 中有明确说明--target可以指定一个或多个 JavaScript 运行时的特定版本如chrome80,node14esbuild 会把输出限制在所有目标运行时都支持的语法特性之内。也就是说多目标取的是特性交集任何一个目标不支持的特性都会被降级转换。这个交集是如何计算的CHANGELOG-2021.md 解释了机制当你使用--targetnode12.20这样的版本号时esbuild 用这个数字查询一张内部特性兼容表表中记录了每个特性在哪些目标环境中受支持。把这两条规则合起来就能推出同一引擎多版本的情况同一个引擎的较低版本支持的特性一定是较高版本的子集交集因此被最低版本完全主导。--targetchrome1,chrome99的都支持条件实际上就退化成了chrome1 支持所以最低版本生效不是特殊规则而是所有目标交集语义的自然结果。修复前的问题重复引擎曾以最后一个版本为准上面的语义是 esbuild 期望的行为但重复指定同一引擎这个边界情况曾经没有被正确处理。CHANGELOG.md 的 Unreleased 部分记录了针对 issue #4509 的修复Handle target collisions旧行为同一引擎出现多次时取的是列表中最后一个版本而不是最低版本。以--targetchrome1,chrome99为例esbuild 之前按chrome99处理生成的代码可能使用 chrome1 不支持的语法导致产物在最老的目标环境中直接报错。新行为esbuild 会取所有重复目标引擎之间的最低版本即按chrome1处理。需要注意版本兼容问题在这份仓库的 CHANGELOG.md 中该修复位于Unreleased章节最新已发布版本为 0.28.1。也就是说0.28.1 及之前的版本仍然按最后一个版本处理重复引擎。如果你的配置里存在同一引擎写多次的写法升级到包含此修复的版本后输出会发生变化降级转换变多这是预期内的行为变更如果暂时停留在旧版本正确做法是直接删掉多余的版本号、只保留最低版本而不是依赖最后一个生效的旧行为。验证当前版本走的是哪套逻辑修复规则本身给出了可直接核对的推论在包含此修复的版本中--targetchrome1,chrome99等效于--targetchrome1。可以用同一段输入分别构建对比两份产物是否一致esbuild entry.js --targetchrome1,chrome99 --outfileout_dup.js esbuild entry.js --targetchrome1 --outfileout_min.js包含修复的版本out_dup.js与out_min.js应一致重复引擎收敛到最低版本 chrome1。0.28.1 及更早版本out_dup.js会按chrome99生成与out_min.js不同且可能包含 chrome1 无法执行的语法。判断自己处于哪一侧的依据是版本号按 CHANGELOG.md 的记录0.28.1 是包含此修复前最新发布的版本此修复尚未随已发布版本提供。最低版本过老时用--supported:按特性覆盖如果你的真实目标环境其实较新只是配置里误带了老版本或者某个老版本不支持的特性你确认有兜底方案可以不必整体提高最低版本而是按单个特性覆盖。--supported:设置允许按特性粒度覆盖兼容表中的支持状态见 CHANGELOG-2022.md。CHANGELOG 中出现的实际用法示例包括# 显式声明逻辑赋值运算符|| 等不受支持强制降级 esbuild entry.js --supported:logical-assignmentfalse # 示例显式关闭 media range 特性 esbuild styles.css --supported:media-rangefalse注意两点覆盖只改变特性是否可用的判定--target的整体交集语义不变。CHANGELOG-2022.md 还提到用--supported:配置出自相矛盾的组合例如同时--supported:async-awaitfalse --supported:async-generatortrue早期可能导致构建成功但产物无效新版本会对这类矛盾做约束。按特性覆盖时只调整你确实在意的那一个特性。相关规则tsconfig 的 target 参与同样的交集如果项目中存在tsconfig.json它的target字段会与命令行--target合并。CHANGELOG-2021.md 说明每个 JavaScript 文件会按最近一层tsconfig.json的target语言级别转换两个设置合并的方式是——任何在 esbuild 的--target值或 tsconfig 的target属性中不受支持的语言特性都会被转换。即交集语义同样成立tsconfig 里一个更老的target会让实际生效的目标进一步变保守排查为什么产物降级了时除了--target也要检查就近的tsconfig.json。另外当输入文件包含比目标版本更新的语法且 esbuild 尚不能转换时这不是警告而是构建错误CHANGELOG-2020.md 中将该类提示从 warning 提升为 error 的原因正是忽略它会在老浏览器中产生坏代码。遇到目标比输入旧的报错时正确方向是放宽最低目标或升级 esbuild而不是忽略提示。小结多目标取所有目标都支持的特性交集因此同一引擎写多个版本时最低版本天然主导同一引擎重复出现的边界情况在旧版本含 0.28.1按最后一个版本处理存在产物不兼容最老目标的隐患修复后改为取最低版本用--targetchrome1,chrome99与--targetchrome1的产物对比可验证当前版本的行为确需跳过个别降级时用--supported:特性状态精确覆盖。【免费下载链接】esbuildAn extremely fast bundler for the web项目地址: https://gitcode.com/GitHub_Trending/es/esbuild创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →