使用打字稿在 Firebase Cloud 函数内动态导入类的正确方法是什么?

Dev*_*ike 2 node.js firebase typescript google-cloud-functions

在 Firebase Cloud Function 项目中...

我在src我的主index.ts文件旁边的目录根目录下有以下打字稿文件,该文件导入一个依赖项并导出一个包含 2 个方法的类。这个文件的标题是bcrypt.class.ts

import * as bcrypt from 'bcryptjs';

export default class BcryptTool {
  public static hashValue(value: string, rounds: number, callback: (error: Error, hash: string) => void) : void {
      bcrypt.hash(value, rounds, (error:any, hash:any) => {
            callback(error, hash);
      });
  }
  public static compare(value: string, dbHash: string, callback: (error: string | null, match: boolean | null) => void) {
    bcrypt.compare(value, dbHash, (err: Error, match: boolean) => {
        if(match) {
            callback(null, true);
        } else {
            callback('Invalid value match', null);
        }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

在我的 Firebase Cloud 函数index.ts文件中,我导入了这个类并在我的一个函数中调用它的“比较”方法没有问题,这按预期工作:

'use strict';
const express = require('express');
const functions = require('firebase-functions');
const cors = require('cors')({ origin: true });

const admin = require('firebase-admin');
admin.initializeApp();

const api = express();

import BcryptTool from './bcrypt.class'; // <-- i import the class here

// and use it in a function

api.use(cors);
api.post('/credentials', async (request: any, response: any) => {

   BcryptTool.compare(...) // <--- calls to this method succeed without issue

});
Run Code Online (Sandbox Code Playgroud)

问题

我的应用程序包含许多函数,但我只需要其中一个函数中提到的类,因此为了优化所有其他函数的冷启动时间,我尝试在需要它的函数内部动态导入此类,而不是如上所述将其导入全局范围。这不起作用,我无法弄清楚原因:

'use strict';
const express = require('express');
const functions = require('firebase-functions');
const cors = require('cors')({ origin: true });

const admin = require('firebase-admin');
admin.initializeApp();

const api = express();

api.use(cors);
api.post('/credentials', async (request: any, response: any) => {

   const BcryptTool = await import('./bcrypt.class'); // <-- when i attempt to import here instead

   BcryptTool.compare(...) // <--- subsequent calls to this method fail

   // Additionally, VS Code hinting displays a warning: Property 'compare' does not exist on type 'typeof import('FULL/PATH/TO/MY/bcrypt.class')' 

});
Run Code Online (Sandbox Code Playgroud)

我的类没有正确编写或导出吗?

我没有在我的云函数中正确导入类吗?

Ben*_*aVR 7

顶级导入 ( import BcryptTool from './bcrypt.class';) 将自动defaultbcrypt.class模块导入导出。但是,当将 import 语句用作函数时(所谓的“动态导入”),它将导入模块本身,而不是默认导出。

当您console.log(BcryptTool)同时导入时,您可以看到不同之处:

  • import BcryptTool from './bcrypt.class' 将会呈现 { default: { [Function: BcryptTool] hashValue: [Function], compare: [Function] } }
  • const BcryptTool = await require('bcrypt.class') 将会呈现 { [Function: BcryptTool] hashValue: [Function], compare: [Function] }

你注意到default第一个 console.log 了吗?这表明您导入了模块,而不是默认模块。

现在实际上import BcryptTool from './bcrypt.class'语法是 do 的语法糖import { default as BcryptTool } from './bcrypt.class'。如果您将这些知识应用于动态导入,您可以这样做:

const BcryptToolModule = await import('./bcrypt.class');
BcryptToolModule.default.compare(...);
Run Code Online (Sandbox Code Playgroud)

或者使用更简洁的语法:

const { default: BcryptTool } = await import('./bcrypt.class');
BcryptTool.compare(...);
Run Code Online (Sandbox Code Playgroud)