提前抱歉问了这么长的问题,但是项目结构问题/错误有点难以解释。
我有一个 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
文件夹的结构。
可能会发生什么?
解决这个问题的一种方法(不太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
注释。
我刚刚解决了一个类似的问题,我想将类型从项目文件夹导入到 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
。
这样您就可以在项目中的任何地方以相同的方式从“类型”导入。