DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
PanstarCloud:部署应用,接入 AI,云服务器与 AI 网关
OnlineSIM:在线接收短信,虚拟号码租用

esbuild 打包成功却报 Base 未定义:检查 import-equals 别名

esbuild 0.28.1 打包某些默认导入的 TypeScript 别名时,可能删掉仍被 new Base 使用的导入。0.28.2 已修复,检查产物比增加 sideEffects 更直接。

esbuild 构建退出成功,没有 warning,运行到 new Base() 却报 ReferenceError: Base is not defined。若源文件明明导入了 Base,同时还有 import Alias = Base.SomeType,应检查打包结果中默认导入及其实现是否被错误移除。

esbuild 0.28.1 的明确条件是启用 bundle,别名以默认导入为基底;正式 0.28.2 已包含相应 tree shaking 修复。它不是所有 TypeScript 别名都会触发,也不能只凭 Base 这个名字判断。

运行时使用没有随导入一起保留下来

失败文件的关键形态是:

import Base from './dep.js';
import Alias = Base.SomeType;

export function make() {
  return new Base();
}

这段用于识别导入与别名的关系,不是一套完整类型定义。实际项目里的 dep.js 及其声明,需要提供真实的 Base、SomeType 和对应用途;不能据此声称只有一个 Base 类、没有 SomeType 的任意依赖也能通过类型检查。

受影响的打包可能把依赖实现和默认导入都删掉,却留下 make 中的 Base。即使 metafile.inputs 列出了 dep.js,也只能说明读过输入,不能证明其实现已进入输出。输出中的自由变量还可能没有被重命名,但这只是定位线索。

如果关闭 bundle 后导入恢复,且仅移开这一条未使用别名也能恢复,就符合这条收窄方向。不要把依赖没有导出该成员、模块路径错误或所有类型错误一并归给打包器。

升级实际参与打包的 esbuild

采用兼容的 0.28.2,保留原模块格式、目标和业务入口重新构建,检查 Base 的实现与值引用都能正确连接。项目有嵌套工具链时,核对真正调用 esbuild 的依赖版本,而不是只看根目录新装了一份包。

无法立即更新,且该 import-equals 别名确实完全未使用时,可以只移除无用声明,保留默认导入及运行时使用。别名仍用于真实类型或值时,不要机械删除;应按项目的模块与声明契约改写,并通过原有类型检查。把它随手换成另一种语法,也可能改变命名空间和值的关系。

修改 sideEffects 并不是这条回归的对应处理。也不要给 globalThis 填一个同名 Base,或直接修补生成文件,那会掩盖真正丢失的模块绑定,下一次构建还会覆盖。

验收经过最终包的实际入口调用 make,确认实例来自正确实现,并检查相关别名的类型用途仍然成立。构建通过、类型检查通过、运行时导入正确是三个需要分别确认的结果。