首页 > 解决方案 > 在javascript中导入json似乎没有成功

问题描述

在 firebase 函数项目中,我想在 settings.json 中有一些设置,然后在我的打字稿文件中导入这些设置。由于某种原因,导入似乎没有成功,我无法看到或弄清楚原因。

我的文件夹/文件结构如下所示:

src
 - database
   - index.ts <-- only exports uppercase.ts
   - uppercase.ts
 - regions.ts

在uppercase.ts 中,我导入regions.ts 以使用函数对象和配置在europe-west1 上部署。

import { functionsEUWest1 } from '../regions';

export const uppercase = functionsEUWest1.database.ref('/messages/{pushId}/original').onCreate((snapshot, context) => {
    //Code as can be found in the tutorials of firebase.
});

在这些地区,我尝试从 settings.json 中读取设置以用于配置。

import functions from 'firebase-functions';
import settings from "./settings.json";

const region: any = settings.region;

export const functionsEUWest1 = functions.region(region);

这是 settings.json 的内容

{
    "region": "europe-west1"
}

构建输出的文件夹/文件结构是相同的(仅在 lib 而不是 src 但这是默认情况下由 firebase 配置的)。

当我尝试部署我的功能时,我收到以下错误:

Error: Error occurred while parsing your function triggers.

TypeError: Cannot read property 'region' of undefined
    at Object.<anonymous> (<local basepath>\functions\lib\regions.js:9:57)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (<local basepath>\functions\lib\database\uppercase.js:3:19)
    at Module._compile (module.js:653:30)

当我查看文件 region.js 中的构建输出时,我无法检测到任何罕见的转译代码:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const firebase_functions_1 = __importDefault(require("firebase-functions"));
const settings_json_1 = __importDefault(require("./settings.json"));
const region = settings_json_1.default.region;
exports.functionsEUWest1 = firebase_functions_1.default.region(region);
//# sourceMappingURL=regions.js.map

此外,settings.json 被复制到构建位置,并且与 region.js 位于同一文件夹中。然而 setting_json_1 的属性默认值是未定义的,我不知道出了什么问题。

编辑 我向 tsconfig.json 添加了 2 个设置。我这样做是因为在我发现的几篇文章中都建议过:

"resolveJsonModule": true,
"esModuleInterop": true

标签: jsontypescript

解决方案


经过一些更多的研究,我后来发现,似乎不是 json 导入不起作用,但它看起来像设置

"esModuleInterop": true

似乎不能与 firebase 一起使用,或者可能更具体:firebase 功能,就我所见和得出的结论而言。

研究结论

首先,我想弄清楚 TypeScript 中的导入是否真的有效,所以我创建了 3 个 .ts 文件和一个 .json 文件,以及一个放在文件夹中的 .ts 文件。然后我生成了 tsconfig.json

tsc --init

我添加了 2 个设置(resolveJsonModule 和 esModuleInterop)。我将 .ts 文件转换为 .js 文件并使用节点运行代码。这很有效,我看到了控制台中打印的 .json 文件中的设置值。

导入 .json 文件的 .ts 文件具有以下代码行:

import settings from "./settings.json";

console.log('from test.ts: ' + settings.setting1);

export const Settings = settings;

这被转换为:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var settings_json_1 = __importDefault(require("./settings.json"));
console.log('from test.ts: ' + settings_json_1.default.setting1);
exports.Settings = settings_json_1.default;

现在,我不完全理解这段代码,因为我不知道 __importDefault 或 mod 是什么。

但是这段代码和其他代码确实做了它应该做的事情:从 .json 文件中读取设置并在控制台中打印它。所以导入 .json 文件确实有效。所以它必须与firebase做点什么。

我所做的下一步是创建一个使用函数和托管的干净的 firebase 项目。在由 firebase CLI 生成的 index.ts 中的 functions/src 文件夹中,我将代码更改为:

import functions from 'firebase-functions';
import settings from "./settings.json";

const setting1 = settings.setting1;

export const helloWorld = functions.region('europe-west1').https.onRequest((request, response) => {
  response.send("Hello from Firebase! Settings1 value = " + setting1);
});

我还在 tsconfig.json 中添加了相同的 2 个设置(resolveJsonModule 和 esModuleInterop)。当我尝试将此功能部署到 Firebase 云时,我遇到了与我在问题帖子中提到的相同的错误:

TypeError: Cannot read property 'region' of undefined

但是这一次,我的 .json 文件中没有属性区域。因此,我在问题帖子中的代码中有区域这一事实以及我没有查看堆栈跟踪的行号这一事实误导了我,让我认为 .json 导入不起作用。但它正在工作。

错误的原因是在 firebase_functions_1.default 上调用的方法区域。出于某种原因,默认值未定义,并且正在生成错误。这让我也意识到我真的错过了错误中的一个或多个对象的名称。我想看到的是

TypeError: Cannot read property 'region' of undefined (firebase_functions_1.default)

所以,回到问题,我仍然得到错误,但它不是由 .json 导入引起的。为了弄清楚实际原因是什么,我首先恢复了 tsconfig.json 中的“esModuleInterop”设置,这导致我的 index.ts 中的导入部分出现错误。我不得不将进口改回

import * as functions from 'firebase-functions';
import * as settings from "./settings.json";

现在,通过导入 .json 文件,再次部署到 firebase 云。此外,在不使用“esModuleInterop”设置的情况下,编译后的代码看起来会有所不同:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const functions = require("firebase-functions");
const settings = require("./settings.json");
const setting1 = settings.setting1;
exports.helloWorld = functions.region('europe-west1').https.onRequest((request, response) => {
    response.send("Hello from Firebase! Settings1 value = " + setting1);
});
//# sourceMappingURL=index.js.map

它不再具有 firebase_functions_1 上的默认属性,而是现在仅具有函数。


推荐阅读