用转换工具链处理项目时,突然卡住、报错或输出空文件——这种场景开发者都熟悉。不是代码写错了,也不是环境没配好,偏偏就卡在转换这一步。下面这些原因,我们挨个拆开看。
1. 输入格式不匹配
工具链往往对输入有硬性要求。比如某工具只认 .ts 文件,但你传了 .tsx;或者 JSON Schema 要求顶层是 object,结果你给的是 array。它不会提示“格式不对”,只会默默失败或抛出模糊异常。
检查办法:打开源文件,确认扩展名、顶层结构、编码(比如 BOM 头会导致某些解析器静默退出)。
2. 依赖版本打架
一个工具链常串联多个子工具(如 babel → terser → rollup)。某个子工具升级后,输出格式变了,但下游还没适配。比如 babel 7.20+ 默认输出 ES2022 语法,而旧版 terser 不支持 class static block,直接崩溃。
典型报错:Unexpected token '{' at position 123。别急着改代码,先跑 npm ls babel-core terser 看实际装的是哪个版本。
3. 配置文件被忽略或加载错位
工具链会按约定顺序查找配置文件(如 babel.config.js、.babelrc、package.json#babel),但优先级和作用域容易混淆。比如你在子目录下运行命令,却没意识到当前工作目录下没有 babel.config.js,结果回退到全局默认配置,把 JSX 全删了。
验证方式:加 --verbose 或 -d 参数(视工具而定),看它到底加载了哪个配置文件。
4. 插件/Loader 执行时报错,但被吞掉
有些工具链(尤其是 webpack + 自定义 loader)遇到插件内部 throw 错误时,只打印一行 Module build failed 就停了,堆栈全没了。这时候得手动加 try-catch 或临时注释掉部分 loader 测试。
例如 webpack 中:
module: {
rules: [
{
test: /\.js$/,
use: [
'babel-loader',
// 先注释掉这个自定义 loader,看看是否恢复正常
// 'my-ast-transform-loader'
]
}
]
}5. 环境变量或路径问题
工具链脚本里用了 process.env.NODE_ENV 或 __dirname,但在 CI 或 Docker 里没设环境变量,或挂载路径和本地不一致,导致读不到配置、找不到模板文件。常见表现:本地 OK,上线就失败,错误信息却是 Cannot find module './config'。
解决思路:在脚本开头加一行 console.log('CWD:', process.cwd(), 'ENV:', process.env.NODE_ENV),对比两端输出。
6. 内存溢出(OOM)静默退出
处理大文件或复杂 AST 时,Node.js 默认内存上限(~1.4GB)可能不够。工具链没报错,进程直接 exit code 137,日志里只剩一句 Killed。这不是 bug,是系统杀的。
临时解法:启动时加 node --max-old-space-size=4096 ./node_modules/.bin/your-tool;长期建议拆分输入或优化插件逻辑。
排查不用猜,先看 exit code、翻完整日志、确认输入样本、再逐段关插件。工具链不是黑盒,每个环节都有迹可循。