TypeScript编译为ECMAScript模块后Firebase Functions模块解析问题
我基于React框架和Google Firebase后端开发应用,前后端共用的逻辑代码放在共享库中,全部用TypeScript编写。为保证组件一致性,我将代码编译为ECMAScript模块(ESM)。但在Firebase Functions中遇到了模块解析问题:Functions源文件包含index.ts和sisAPI.ts,在index.ts中通过import ... from './sisAPI'导入sisAPI.ts,运行函数模拟器时出现错误:
Cannot find module functions/lib/sisAPI imported from functions/lib/index.js
问题根源是编译后的ESM导入语句丢失了.js扩展名,而Node.js的ESM规范要求必须使用完整的文件扩展名才能正确解析模块。
我的tsconfig.json配置如下:
{ "compilerOptions": { "module": "ESNext", "noImplicitReturns": true, "noUnusedLocals": true, "outDir": "lib", "sourceMap": true, "strict": true, "target": "ES2020", }, "compileOnSave": true, "include": [ "src" ] }
修复步骤
调整TypeScript配置,自动添加ESM扩展名
修改tsconfig.json的compilerOptions,添加moduleResolution: "NodeNext"(或Node16),这一配置会让TypeScript按照Node.js的ESM规则处理导入路径,编译时自动为生成的.js文件添加正确的扩展名:{ "compilerOptions": { "module": "ESNext", "moduleResolution": "NodeNext", "noImplicitReturns": true, "noUnusedLocals": true, "outDir": "lib", "sourceMap": true, "strict": true, "target": "ES2020", "esModuleInterop": true // 可选,提升跨模块兼容性 }, "compileOnSave": true, "include": [ "src" ] }标记Firebase Functions为ESM项目
在Firebase Functions目录下的package.json中添加"type": "module"字段,告诉Node.js当前项目使用ESM规范,避免按CommonJS规则解析模块:{ "name": "functions", "type": "module", // 其他原有配置... }重新编译并测试
执行tsc重新编译TypeScript代码,然后重启Firebase Functions模拟器,此时编译后的index.js中会自动生成带.js扩展名的导入语句(如import ... from './sisAPI.js'),模块解析错误即可解决。
内容的提问来源于stack exchange,提问作者Someone

