尝试在从外部项目(上一级)导入类型时构建 Firebase 函数项目。 `tsc` 编译后丢失文件夹结构
Posted
技术标签:
【中文标题】尝试在从外部项目(上一级)导入类型时构建 Firebase 函数项目。 `tsc` 编译后丢失文件夹结构【英文标题】:Trying to build a Firebase functions project while importing types from an outer project (one level up). Losing folder structure after `tsc` compiles 【发布时间】:2021-08-15 16:39:12 【问题描述】:抱歉这个问题太长了,但是项目结构问题/错误有点难以解释。
我有一个 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"
]
它还在我的firebase.json
文件中添加了一个predeploy
挂钩。
"functions":
"predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
这是在部署之前构建.ts
文件所必需的。它将根据tsconfig.json
将functions/src
文件夹中的文件构建到functions/lib
文件夹。
基本的helloWorld
示例可以很好地构建和部署。我已将一些文件添加到 functions
文件夹中,并且它们都可以正常工作。
在functions/src
查看我的文件:
在functions/lib
上查看编译文件:
正如您所期望的那样,它的结构和文件完全相同。
问题
当我从“外部”根项目导入类型时,问题就开始了。例如:
我继续functions/src/index.ts
并执行以下操作:
import SomeType from "../../types/whatever"
// USE THE TYPE HERE
现在看看构建结果是什么(即:functions/lib
文件夹):
现在它基本上在lib
文件夹下创建了另一个functions
。它还基本上从我的types
文件夹中复制文件。我不知道它为什么这样做。
我完全没想到。我想使用外部根项目中的类型,但不会弄乱生成的 functions/lib
文件夹的结构。
会发生什么?
【问题讨论】:
这个解决方案对您有用吗? Using a shared node module for common classes。我不再像 TypeScript 那样缺乏经验了,但这似乎适用于您正在尝试做的事情。 @samthecodingman 谢谢。您建议将共享文件夹内容复制到functions
文件夹并进行某种路径别名映射来访问它?它可以工作,但它是最好/唯一的方法吗?感觉很hacky。没有更好的办法吗?
啊,我有点误读了这个问题:你最终得到$PROJECT_DIR/functions/lib/functions/src
的原因是你在代码中使用的相对导入(../../types/whatever
)指向编译 键入$PROJECT_DIR/functions/lib/types
。当 Firebase 将您的代码部署为 Cloud Functions 映像时,它只会上传 $PROJECT_DIR/functions
的内容,因此要求该函数使用的所有代码和资源都在该目录中可用。
@samthecodingman 所以它应该从外部项目中收集每一段导入的代码并将其与functions/src
文件夹一起编译?我认为 Typescript 会尊重 include
属性,并且不会编译除此之外的任何内容。另外我只是在导入类型。它们与结果代码无关。这很奇怪。
如果它们是纯类型(即interface
、declare function
等 - 不是实际的函数/代码),请使用 import type ... from "../../types/whatever"
。这告诉 TypeScript 这些文件不包含代码,只是 IDE-helper 的东西。
【参考方案1】:
一种不太笨拙的解决方法是将您的共享类型声明为命名空间并使用/// <reference path="...">
命令导入它们。
这样,您将能够通过声明的命名空间访问您的类型,并且构建将保留所需的目录结构。
假设以下项目
my-project/
functions/
src/
index.ts
shared/
type.d.ts
...otherFiles
shared.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!`);
);
如果您使用来自 firebase 模板的 eslint 默认规则,则需要 // eslint-disable-next-line
cmets,因为 @typescript-eslint/triple-slash-reference
规则。
【讨论】:
以上是关于尝试在从外部项目(上一级)导入类型时构建 Firebase 函数项目。 `tsc` 编译后丢失文件夹结构的主要内容,如果未能解决你的问题,请参考以下文章