Angular 19 SSR集成@google-cloud/secret-manager报__dirname未定义错误
解决Angular 19 SSR中使用@google-cloud/secret-manager时的__dirname未定义错误
问题背景
在Angular 19 SSR应用的服务端代码中引入@google-cloud/secret-manager(已升级至v6.0.1,同步升级google-gax至v5.0.1-rc.0),启动开发服务或构建时出现ReferenceError: __dirname is not defined,错误溯源至依赖库google-gax的grpc.js文件。Angular 19默认采用ESM模块系统,而部分CommonJS依赖仍会依赖__dirname这类Node.js CommonJS环境变量。
解决方案
1. 手动在服务端全局注入__dirname和__filename
在src/server.ts最顶部添加以下代码,手动定义并挂载这两个变量到全局对象,让依赖库能正常访问:
import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // 挂载到全局对象 (globalThis as any).__dirname = __dirname; (globalThis as any).__filename = __filename;
这是最直接的临时修复方式,__dirname是CommonJS的内置变量,ESM环境下默认不提供,手动注入后可满足依赖库的需求。
2. 通过Webpack配置全局定义变量
如果上述方法无效,可通过自定义Webpack配置来全局声明__dirname:
- 在项目根目录创建
webpack.server.config.js文件:
module.exports = { plugins: [ { apply: (compiler) => { compiler.options.plugins.push( new compiler.webpack.DefinePlugin({ __dirname: JSON.stringify(__dirname), __filename: JSON.stringify(__filename), }) ); }, }, ], };
- 修改
angular.json,在服务端构建配置中引入这个自定义Webpack配置:
找到projects -> [你的项目名] -> architect -> server -> options,添加:
"extraWebpackConfig": "./webpack.server.config.js"
3. 使用动态导入替代静态导入
尝试将@google-cloud/secret-manager的静态导入改为动态导入,避免ESM与CommonJS的加载冲突:
async function bootstrap() { // 动态导入SecretManager客户端 const { SecretManagerServiceClient } = await import('@google-cloud/secret-manager'); const client = new SecretManagerServiceClient(); // 后续业务逻辑... } bootstrap();
内容的提问来源于stack exchange,提问作者adityaprakash
相关产品推荐
相关产品推荐

