尝试在从外部项目(上一级)导入类型时构建 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.jsonfunctions/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 属性,并且不会编译除此之外的任何内容。另外我只是在导入类型。它们与结果代码无关。这很奇怪。 如果它们是纯类型(即interfacedeclare 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` 编译后丢失文件夹结构的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 webpack 从项目根目录导入外部文件?

我想将外部 fbx 文件导入独立的统一项目

尝试将外部 QML 模块导入我的项目时出错

在Maven构建期间找不到来自外部jar的类文件? [复制]

每次尝试将项目导入eclipse时出现Java问题

在 Windows 上构建 C++ 项目时,Tensorflow 2.3 无法解析机器生成的文件中的外部符号