问题描述
为了抽象 firebase-admin
依赖项,我有一个文件 index.js
用于导出我的项目使用的功能。为什么不能将 initializeApp
作为属性导出?
例如:
index.js
const firebaseAdmin = require('firebase-admin');
exports.initializeApp = firebaseAdmin.initializeApp;
consumer.js
const firebaseAdmin = require('path/to/index.js');
firebaseAdmin.initializeApp();
抛出以下错误:
TypeError: 无法读取未定义的属性 'initializeApp'
为了隔离问题,我写了以下内容来证明 initializeApp
不能作为属性导出,就像我对其他函数所做的那样:
const firebaseAdmin = require('firebase-admin');
const initializeApp = firebaseAdmin.initializeApp;
initializeApp();
这会抛出:
为什么我不能将 initializeApp
作为属性导出?这个错误迫使我将 index.js 中的导出重写为:
exports.initializeApp = () => firebaseAdmin.initializeApp();
但这感觉就像一个黑客。
我的每个文件都以 'use strict;'
开头有区别吗?这会令人惊讶。
解决方法
这是 Admin SDK 实施方式的结果。 Admin SDK 包的主要导出不是一个真正的模块,而是一个类的实例。因此,当您从该类实例中提取单个方法时,它会丢失其所有上下文,并且 this
之类的内部引用开始出现故障。这是一个简单的例子来说明问题。
// file: sdk.ts
class Firebase {
public INSTANCE = {key: 'sdk'};
public initializeApp() {
console.log('Initializing',this.INSTANCE['key']);
}
}
const admin = new Firebase();
export = admin;
# File: test.js
// admin actually points to an instance of the Firebase class
const admin = require('./sdk');
// extract a single method from the object instance
const initializeApp = admin.initializeApp;
// The "this" reference in the initializeApp method no longer works
initializeApp();
您必须继续使用目前找到的解决方法。它可能会在 SDK 的未来版本中得到解决,但目前不支持。