发布npm包时遇Node.js报错:Unknown file extension .ts
解决npm包执行时的"Unknown file extension '.ts'"错误
问题根源
通过npm link关联包后执行auto-eslint命令时,Node.js会直接尝试运行package.json的bin字段指定的./src/index.ts文件,但Node.js默认不识别.ts扩展名,且全局执行场景下没有加载ts-node/esm loader来处理TypeScript文件——这就是报错的核心原因。而本地npm start能正常运行,是因为启动命令显式添加了--loader ts-node/esm等必要参数。
解决方案
方案一:编译TypeScript为JavaScript(推荐,适合生产发布)
该方式发布编译后的纯JS文件,无需依赖ts-node运行,更稳定且无额外依赖负担。
添加编译与前置发布脚本
在package.json的scripts中新增编译命令,同时添加prepublishOnly确保发布前自动编译:"scripts": { "lint": "ts-standard", "start": "node --experimental-specifier-resolution=node --loader ts-node/esm src/index.ts", "build": "tsc", "prepublishOnly": "npm run build", "auto-eslint": "auto-eslint" }修改
bin指向编译后的文件
将package.json中的bin字段改为指向编译后的产物:"bin": "./dist/index.js"验证效果
- 执行
npm run build编译代码 - 重新执行
npm link关联包 - 在测试项目中运行
auto-eslint即可正常执行
- 执行
方案二:使用JS启动脚本加载TS文件(适合开发阶段快速测试)
若不想每次修改都编译,可创建JS启动文件,通过ts-node加载TS入口:
创建启动脚本
src/cli.js#!/usr/bin/env node import { register } from 'ts-node'; import { resolve } from 'path'; // 注册ts-node处理ES模块 register({ esm: true, project: resolve(__dirname, '../tsconfig.json') }); // 导入TS入口文件 await import('./index.ts');调整
package.json配置- 修改
bin指向该JS脚本:"bin": "./src/cli.js" - 将
ts-node从devDependencies移到dependencies(全局执行时需依赖该包):"dependencies": { "@clack/prompts": "^0.6.3", "picocolors": "^1.0.0", "@types/semver": "^7.5.0", "ts-node": "^10.9.1" }
- 修改
重新关联测试
执行npm link后,在测试项目中运行auto-eslint即可。
额外注意事项
- 确保
tsconfig.json中的outDir设置为dist,且include包含所有需要编译的TS文件 - 方案一中,
prepublishOnly脚本会在npm publish前自动执行编译,避免发布未编译的TS文件 - 方案二中,
ts-node作为生产依赖会增加包体积,仅适合开发调试,正式发布优先选择方案一
内容的提问来源于stack exchange,提问作者Salvador Bacci
相关产品推荐
相关产品推荐

