将共享节点模块用于通用类

Mau*_*ino 13 node.js npm node-modules firebase typescript

目标

所以我有一个具有这种结构的项目:

  • 离子应用
  • Firebase功能
  • 共享

目的是在shared模块中定义公共接口和类。

限制条件

我不想将代码上传到npm以便在本地使用它,也根本不打算上传代码。它应该100%脱机工作。

虽然开发过程应该脱机工作,但是ionic-appfirebase-functions模块将部署到Firebase(托管和功能)。因此,shared模块的代码应该在那里可用。

到目前为止我尝试过的

  • 我尝试在打字稿中使用项目引用,但还没有开始工作
  • 我尝试将其安装为npm模块,如该问题的第二个答案
    • 一开始它似乎运行良好,但是在构建过程中,运行时出现如下错误firebase deploy
Function failed on loading user code. Error message: Code in file lib/index.js can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'shared'
    at Function.Module._resolveFilename (module.js:548:15)
    at Function.Module._load (module.js:475:25)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/srv/lib/index.js:5:18)
Run Code Online (Sandbox Code Playgroud)

您是否有使用打字稿配置或NPM制作共享模块的解决方案?

请不要将此标记为重复项?我已经尝试过在StackOverflow上找到的任何解决方案。

附加信息

配置共享:

// package.json
{
  "name": "shared",
  "version": "1.0.0",
  "description": "",
  "main": "dist/src/index.js",
  "types": "dist/src/index.d.ts",
  "files": [
    "dist/src/**/*"
  ],
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "publishConfig": {
    "access": "private"
  }
}

// tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "rootDir": ".",
    "sourceRoot": "src",
    "outDir": "dist",
    "sourceMap": true,
    "declaration": true,
    "target": "es2017"
  }
}
Run Code Online (Sandbox Code Playgroud)

功能配置:

// package.json
{
  "name": "functions",
  "scripts": {
    "lint": "tslint --project tsconfig.json",
    "build": "tsc",
    "serve": "npm run build && firebase serve --only functions",
    "shell": "npm run build && firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "8"
  },
  "main": "lib/index.js",
  "dependencies": {
    "firebase-admin": "^8.0.0",
    "firebase-functions": "^3.1.0",
    "shared": "file:../../shared"
  },
  "devDependencies": {
    "@types/braintree": "^2.20.0",
    "tslint": "^5.12.0",
    "typescript": "^3.2.2"
  },
  "private": true
}


// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./",
    "module": "commonjs",
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "rootDir": "src",
    "outDir": "lib",
    "sourceMap": true,
    "strict": true,
    "target": "es2017"
  }
}
Run Code Online (Sandbox Code Playgroud)

当前状态

我在共享模块中添加了一个npm脚本,该脚本将所有文件(没有index.js)复制到其他模块。问题在于,我将重复的代码检入到SCM中,并且每次更改都需要运行该命令。而且,IDE只是将其视为不同的文件。

sam*_*man 5

前言:我不太熟悉 Typescript 编译的工作原理以及package.json应该如何定义这样的模块。这个解决方案虽然有效,但可以被认为是完成手头任务的一种黑客方式。

假设目录结构如下:

project/
  ionic-app/
    package.json
  functions/
    src/
      index.ts
    lib/
      index.js
    package.json
  shared/
    src/
      shared.ts
    lib/
      shared.js
    package.json
Run Code Online (Sandbox Code Playgroud)

部署 Firebase 服务时,您可以将命令附加到predeploy 和 postdeploy hooks。这是firebase.json通过属性predeploypostdeploy所需的服务完成的。这些属性包含在部署代码之前和之后分别运行的一系列顺序命令。此外,这些命令使用环境变量RESOURCE_DIR./functions或的目录路径./ionic-app,以适用者为准)和PROJECT_DIR(包含 的目录路径firebase.json)调用。

使用insidepredeploy数组,我们可以将共享库的代码复制到部署到 Cloud Functions 实例的文件夹中。通过这样做,你可以简单地包括共享代码,就好像它是位于子文件夹库,也可以使用它映射的名字打字稿的路径映射在一个名为模块(所以你可以使用)。functionsfirebase.jsontsconfig.jsonimport { hiThere } from 'shared';

predeploy挂钩定义(用途全球的安装shx为Windows兼容):

// firebase.json
{
  "functions": {
    "predeploy": [
      "shx rm -rf \"$RESOURCE_DIR/src/shared\"", // delete existing files
      "shx cp -R \"$PROJECT_DIR/shared/.\" \"$RESOURCE_DIR/src/shared\"", // copy latest version
      "npm --prefix \"$RESOURCE_DIR\" run lint", // lint & compile
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ]
  },
  "hosting": {
    "public": "ionic-app",
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

将复制的库的打字稿源链接到函数打字稿编译器配置:

// functions/tsconfig.json
{
  "compilerOptions": {
    ...,
    "baseUrl": "./src",
    "paths": {
      "shared": ["shared/src"]
    }
  },
  "include": [
    "src"
  ],
  ...
}
Run Code Online (Sandbox Code Playgroud)

将模块名称“共享”与复制的库的包文件夹相关联。

// functions/package.json
{
  "name": "functions",
  "scripts": {
    ...
  },
  "engines": {
    "node": "8"
  },
  "main": "lib/index.js",
  "dependencies": {
    "firebase-admin": "^8.6.0",
    "firebase-functions": "^3.3.0",
    "shared": "file:./src/shared",
    ...
  },
  "devDependencies": {
    "tslint": "^5.12.0",
    "typescript": "^3.2.2",
    "firebase-functions-test": "^0.1.6"
  },
  "private": true
}
Run Code Online (Sandbox Code Playgroud)

托管文件夹可以使用相同的方法。


希望这能激励那些更熟悉 Typescript 编译的人提出一个使用这些钩子的更清晰的解决方案。