尝试构建 Firebase 函数项目,同时从外部项目(上一级)导入类型。 `tsc` 编译后丢失文件夹结构

问题描述 投票:0回答:2

提前抱歉问了这么长的问题,但是项目结构问题/错误有点难以解释。

我有一个 Next.js 项目,这是我的根项目。这是一个 Typescript 项目,所以它有自己的

tsconfig.json

这是基本结构:

> app    // APP COMPONENTS
> pages  // NEXT.JS PAGES
> types  // SOME GLOBAL TYPES FOR THE PROJECT
firebase.json
firestore.rules
storage.rules
tsconfig.json

我需要给这个项目添加云功能。所以我遵循了以下文档:

https://firebase.google.com/docs/functions/typescript

基本上我已经输入了

firebase init functions
并按照 CLI 的说明进行操作。

然后创建了一个

functions
,如下所示(
>
符号表示文件夹):

> app

> functions  // NEW FOLDER FOR THE FUNCTIONS PROJECT
  > src
    index.ts
  package.json
  tsconfig.json

> pages
> types
firebase.json
firestore.rules
package.json
storage.rules
tsconfig.json

现在看到

functions
文件夹有自己的
tsconfig.json
文件和自己的
package.json
文件。从本质上讲,它是一个自己的项目。我同意这个想法。

这是创建的

tsconfig.json
文件:

{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "outDir": "lib",
    "sourceMap": true,
    "strict": true,
    "target": "es2017"
  },
  "compileOnSave": true,
  "include": [
    "src"
  ]
}

它还向我的

predeploy
文件添加了一个
firebase.json
钩子。

"functions": {
  "predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
}

这是在部署之前构建

.ts
文件所必需的。它将按照
functions/src
functions/lib
文件夹上的文件构建到
tsconfig.json
文件夹。

基本的

helloWorld
示例构建和部署得很好。我已将一些文件添加到
functions
文件夹中,并且一切正常。

查看我的文件

functions/src
:

查看编译后的文件

functions/lib

它的结构和文件完全相同,正如您所期望的那样。

问题

当我从“外部”根项目导入类型时,问题就开始了。例如:

我继续

functions/src/index.ts
并执行以下操作:

import SomeType from "../../types/whatever"

// USE THE TYPE HERE

现在看看构建结果是什么(即:

functions/lib
文件夹):

现在它基本上在

functions
文件夹下创建了另一个
lib
。它还基本上从我的
types
文件夹中复制文件。我不知道为什么要这样做。

我根本没想到会这样。我想使用外部根项目中的类型,但不会弄乱生成的

functions/lib
文件夹的结构。

可能会发生什么?

node.js typescript firebase google-cloud-functions tsc
2个回答
1
投票

解决这个问题的一种方法(不太hacky)是将共享类型声明为命名空间,并使用

/// <reference path="...">
命令导入它们。

这样,您将能够通过声明的命名空间访问您的类型,并且构建将保留所需的目录结构。

假设以下项目

my-project/
  functions/
    src/
      index.ts
  shared/
    type.d.ts
  ...otherFiles

共享.ts

declare namespace shared {
  interface IType {
    name: string
  }
}

index.ts

// eslint-disable-next-line
/// <reference path="../../shared/model.d.ts" /> 
import * as functions from "firebase-functions";

export const helloWorld = functions.https.onRequest((request, response) => {
  const type:shared.IType = {name: "John"};
  functions.logger.info("Hello logs!", {structuredData: true});
  response.send(`Hello ${type.name}!`);
});

如果您由于

// eslint-disable-next-line
规则而使用 Firebase 模板中的 eslint 默认规则,则需要
@typescript-eslint/triple-slash-reference
注释。


0
投票

我刚刚解决了一个类似的问题,我想将类型从项目文件夹导入到 firebase 函数文件夹中。

// Default folder structure for Next.js and firebase functions
project-folder/
├── functions/
│   ├── src/
│   │   ├── index.ts
│   ├── package.json
│   └── tsconfig.json
├── types/
│   └── index.ts
├── lib/
├── pages/
│   ├── _app.tsx
│   └── index.tsx
├── package.json
└── tsconfig.json

要从函数文件夹外部的文件夹导入类型,只需将其添加到您的

functions/tsconfig.json
:

{
  "compilerOptions": {
    "paths": {
      "types": ["../types"]
    }
  }
}

函数文件夹中的文件现在应该能够从

types
导入类型,如下所示:

import { MyType } from "types"

不过你还必须改变一件事: 如果你现在在函数文件夹中运行

tsc
,它将生成一个看起来与以前不同的文件结构:

// Output when not importing from outside functions src folder
lib/
├── index.js
└── index.js.map

// Output when importing interfaces from outside src folder
lib/
├── functions/
│   └── src/
│       ├── index.js
│       └── index.js.map
└── types/

您需要使

package.json
指向新输出文件夹结构中的正确路径。将
package.json
更改为:

{
  "main": "lib/functions/src/index.js"
}

就是这样!函数文件夹中的文件可以从项目文件夹导入!

还有一个建议:

将对

functions/tsconfig.json
所做的更改也添加到顶级
tsconfig.json

这样您就可以在项目中的任何地方以相同的方式从“类型”导入。

© www.soinside.com 2019 - 2024. All rights reserved.