使用打字稿在 Firebase Cloud 函数中动态导入类的正确方法是什么? [英] What is the correct way to dynamically import a class inside of a Firebase Cloud function using typescript?

查看:21
本文介绍了使用打字稿在 Firebase Cloud 函数中动态导入类的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Firebase Cloud Function 项目中...

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

I have the following typescript file at the root of my src directory right along side of my main index.ts file which imports one dependency and exports a class that includes 2 methods. This file is titled 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);
        }
    });
  }
}

在我的 Firebase Cloud 函数 index.ts 文件中,我导入了这个类并在我的一个函数中毫无问题地调用它的比较"方法,这可以按预期工作:

In my Firebase Cloud functions index.ts file I import this class and make a call to it's 'compare' method within one of my functions without issue, this works as expected:

'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

});

问题

我的应用程序包含许多函数,但我只需要上面提到的类在其中一个,所以为了优化我所有其他函数的冷启动时间,我尝试在需要的函数中动态导入这个类它而不是如上所述将其导入全局范围.这不起作用,我不知道为什么:

My application includes many functions, but I only need the class noted above in one of them, so in an attempt to optimize cold start time for all my other functions, I attempt to dynamically import this class inside of the function that needs it instead of importing it into the global scope as outlined above. This does not work and I cannot figure out why:

'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')' 

});

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

Is my class not written or exported correctly?

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

Am I not importing the class correctly inside of my cloud function?

推荐答案

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

The top-level import (import BcryptTool from './bcrypt.class';) will automatically import the default export from the bcrypt.class module. However, when using the import statement as a function (so called "dynamic import"), it will import the module itself, not the default export.

您可以在 console.log(BcryptTool) 两个导入时看到区别:

You can see the difference when you would console.log(BcryptTool) both imports:

  • import BcryptTool from './bcrypt.class' 将显示 { default: { [Function: BcryptTool] hashValue: [Function], compare: [Function] } }
  • const BcryptTool = await require('bcrypt.class') 将显示 { [Function: BcryptTool] hashValue: [Function], compare: [Function] }
  • import BcryptTool from './bcrypt.class' will show { default: { [Function: BcryptTool] hashValue: [Function], compare: [Function] } }
  • const BcryptTool = await require('bcrypt.class') will show { [Function: BcryptTool] hashValue: [Function], compare: [Function] }

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

Did you notice the default in the first console.log? That shows you imported the module, not the default.

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

Now actually the import BcryptTool from './bcrypt.class' syntax is syntactic sugar for doing import { default as BcryptTool } from './bcrypt.class'. If you apply this knowledge on the dynamic import, you could do this:

const BcryptToolModule = await import('./bcrypt.class');
BcryptToolModule.default.compare(...);

或者用更简洁的语法:

const { default: BcryptTool } = await import('./bcrypt.class');
BcryptTool.compare(...);

这篇关于使用打字稿在 Firebase Cloud 函数中动态导入类的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆