【问题标题】:How should I import JSON in Node?我应该如何在 Node 中导入 JSON?
【发布时间】:2021-06-17 22:27:49
【问题描述】:

我想将package.json导入test.js,两个文件都在同一个目录中。

我试过require

const jsonfile = require("./packages.json");

console.log({ jsonfile });

它抛出错误:

file:///home/.../test.js:1
const jsonfile = require("./packages.json");
                 ^
ReferenceError: require is not defined
    at file:///home/.../test.js:1:18
    at ModuleJob.run (internal/modules/esm/module_job.js:145:37)
    at async Loader.import (internal/modules/esm/loader.js:182:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

这个错误意味着,就像它在浏览器中运行一样,没有require,我发现an answer有类似的消息。

我试过import

import * as jsonfile from './packages.json';

console.log({ jsonfile });
internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/.../packages.json' imported from /home/.../test.js
    at finalizeResolution (internal/modules/esm/resolve.js:271:11)
    at moduleResolve (internal/modules/esm/resolve.js:694:10)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:784:11)
    at Loader.resolve (internal/modules/esm/loader.js:100:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:246:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:47:40)
    at link (internal/modules/esm/module_job.js:46:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

我尝试了更多?

  • 文件名周围的单引号和双引号
  • 带扩展名和不带扩展名的文件名。
  • 带有标志--experimental-json-modules
  • adding "type":"modulepackage.json (但这是针对节点 >= 13,但没有它我收到警告 (node:7170) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. 然后还有错误 SyntaxError: Cannot use import statement outside a module

我什至发现了将 JSON 文件加载为常规文本文件并将其解析为数据结构的建议,但这似乎是最后的手段......

这似乎是一项微不足道的任务,但我还没有找到如何将 JSON 数据导入 Javascript 变量的惯用方法。这里有什么问题?我应该如何导入它?

我使用节点 12.21.0

【问题讨论】:

  • 你应该可以require Node 中的一个 json 文件,不知道出了什么问题。
  • Node 当前的 LTS 是 14,当前的 stable 是 15,所以至少你可能想更新到 14,但是如果你必须使用 12 : 你不是在写 ES 模块代码,你为什么要强迫 Node 像它一样运行你的代码?只需运行node test.js(不是node test),您的代码就会运行良好。
  • require("./file.json"); 应该可以工作。这只是一个错字吗? packages.json 与 package.json?
  • @simon.ro 是的,这里只是拼写错误,实际代码是package.json
  • @Mike'Pomax'Kamermans 感谢您指出旧版本,升级似乎是合理的。而且我总是使用扩展程序运行。

标签: javascript node.js json


【解决方案1】:

您想导入package.json,但在您的代码中您尝试导入packages.json(有错字)。

请注意,当您使用 ESM(import ... from ... 语法)时,您不能直接导入 .json 文件,并且不会定义 require(在 nodejs 上),而在 CJS 中您可以使用 require(...) 语法加载 json 文件(请参阅https://nodejs.org/api/esm.html#esm_no_json_module_loading)。

另外,请注意,您可以创建一个 CJS 文件来导入 JSON 文件并导出其内容,以便以后从 ESM 文件中导入它。

pkg.cjs (CJS)

const pkg = require('./package.json');
module.exports = pkg;

index.mjs (ESM)

import pkg from './pkg.cjs';
console.info(`Starting ${pkg.name} v${pkg.version}`);

【讨论】:

    【解决方案2】:

    导入语法应该始终有效,但在这种情况下,您是错误地要求它。 尝试从'./packages.json'导入jsonfile;。 在这种情况下,您不需要 *

    【讨论】:

    • 其实我先试了你的版本,在OP里忘了提
    【解决方案3】:

    您在 ESM 模式下使用 Node.js,ESM 目前默认不导入 JSON 模块。您可以:

    1. 打开 JSON 模块导入(通过传递 CLI 标志) 或
    2. 在您的 ESM 代码中创建一个 require 函数并使用它或
    3. JSON.手动解析文件

    打开 JSON 模块导入(通过传递 CLI 标志)

    您可以通过传递--experimental-json-modules 标志来做到这一点。

    node --experimental-json-modules yourfile.js # can import JSON here
    

    在您的 ESM 代码中创建 require 函数

    您也可以随时使用 CommonJS 模块并创建自己的 require

    import { createRequire } from 'module';
    const require = createRequire(import.meta.url);
    require('./package.json'); // now works
    

    JSON.手动解析文件

    您始终可以使用常规文件系统方法读取 JSON 文件:

    # const fs = require('fs');
    import * as fs from 'fs';
    const result = JSON.parse(fs.readFileSync('./package.json'));
    

    【讨论】:

    • 我不确定 --experimental-json-modules 是否适用于 Node.js 12,因此您可能会使用 createRequire
    • 我可以确认:所有这 3 个变体都可以正常工作。使用标志--experimental-json-modules 我没有包含扩展名(是'./package')。谢谢!
    • ESM 不仅“当前”不支持 JSON,而且永远不会支持 JSON =)
    • @Mike'Pomax'Kamermans JSON 模块在上个月达到了第 3 阶段github.com/tc39/proposal-json-modules#json-modules,目前正在 Chrome 中进行开发chromestatus.com/feature/5749863620804608。你知道我不知道它在浏览器中发布或未标记的可能性吗? (如果 TC39 发布,我们将 100% 在 Node.js 中发布)
    • @w.k 谢谢,我很高兴能帮上忙——我不知道为什么你的问题被否决了(我投了赞成票,我认为这是一个很好且合理的问题)。可能是因为它听起来太像一个“简单”的问题(如何在没有 ECMAScript 模块的情况下做到这一点)
    猜你喜欢
    • 2018-05-14
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 2019-09-17
    • 2020-11-02
    • 1970-01-01
    相关资源
    最近更新 更多