在Node.js中是否需要使用JSON?

358
我想在我的JavaScript代码中包含一些与JavaScript源文件在同一目录下的JSON文件。
如果我想包含另一个JavaScript文件,我可以简单地使用 "require"。 现在我正在使用 "readFileSync" 和 "__dirname" 来获取JSON,我认为这是一种不好的做法。
是否有类似于 "require" 的东西可以使我加载一个JSON文件?

请参考类似的问题:https://dev59.com/Xm445IYBdhLWcg3w3N0f - holygeek
@coen 你所说的“包含一个JSON文件”是什么意思?读取并解析它吗?如果是,可能是重复的问题:https://dev59.com/IW025IYBdhLWcg3w6aUX - Ciro Santilli OurBigBook.com
3
是的,阅读并解析。但这是特别针对阅读一个“文件”,类似于阅读一个js文件,因此这不是重复的问题,并且goatslacker的答案仍然有效。 - Corno
11个回答

606

从 Node.js v0.5.x 开始,您可以像引入 js 文件一样引入 JSON 文件。

var someObject = require('./somefile.json')

在ES6中:

import someObject from './somefile.json'

15
假设文件在同一目录下(注意点和斜杠),您需要使用 require('./somefile.json')。 - Steve Willcock
88
这里有一点需要注意,结果将被缓存!因此,如果你由于某种原因需要重新加载数据(比如在定时任务中),你会得到相同的旧结果。 - Juho Vepsäläinen
57
注意:扩展名.json似乎很重要。 - nha
14
格式良好的 JSON 也有所帮助。 - sdeburca
8
请注意,如果您想解析除 .json 以外的其他文件格式作为 json 文件,您可以教导 require 如何读取它。 require.extensions['.har'] = require.extensions['.json']; var blar = require('./file.har'); 现在将被视为 json 文件。 - WORMSS
显示剩余8条评论

70

JSON文件不需要显式的导出语句,你无需导出即可将其作为Javascript文件使用。

因此,您可以只使用require来处理有效的JSON文档。

data.json

{
  "name": "Freddie Mercury"
}

主程序.js

var obj = require('data.json');

console.log(obj.name); 
//Freddie Mercury

52
两种最常见的导入方式:
第一种方式:
let jsonData = require('./JsonFile.json')

let jsonData = require('./JsonFile') // 如果我们省略 .json 也可以工作

或者

import jsonData from ('./JsonFile.json')

第二种方法:
同步地: ```javascript const fs = require('fs') let jsonData = JSON.parse(fs.readFileSync('JsonFile.json', 'utf-8')) ```
异步地: ```javascript const fs = require('fs') let jsonData = {} fs.readFile('JsonFile.json', 'utf-8', (err, data) => { if (err) throw err jsonData = JSON.parse(data) }) ```
注意:
1. 如果JsonFile.json被修改,即使我们重新运行`require('./JsonFile.json')`,也无法获取到新的数据。
2. 使用`fs.readFile`或者`fs.readFileSync`将会重新读取文件,并获取到最新的更改。

6
注意,fs方法使用启动node的目录作为起点,而不是读取源代码所在的目录,而“require”方法使用相对于导入源代码位置的路径。因此,只要将东西存储在不同的文件夹中,这两种方法之间的路径就会有所不同。 - Will59
жЬАе•љдЄНи¶БзЬБзХ•.jsonпЉМеЫ†дЄЇNodeдЉЪе∞ЭиѓХеК†иљљ.jsжЦЗдїґпЉМињЩеПѓиГљдЉЪеѓЉиЗійФЩиѓѓгАВ - Ivan Pruchai

24

不行。要么使用 readFile 或者 readFileSync(后者只在启动时使用)。

或者使用现有的库,例如

作为替代,可以将配置写入 js 文件而不是 json 文件,例如

module.exports = {
  // json
}

1
@coen 是的,我们总是使用 __dirname 来创建相对路径。 - Raynos
遇到了这样的问题,本地可以导入JSON,但在AWS EC2实例上的Docker容器中却不能。我没有尝试配置MIME类型等,而是改用JS代替JSON。希望这能帮助到某些人。 - Erik Grosskurth
这个答案完全是错误的,你应该更新或删除它。 - ThisGuyCantEven

10
一个适用于 Node 15 模块的巧妙的异步单行代码,无需缓存。
import { readFile } from 'fs/promises';

const data = await readFile('{{ path }}').then(json => JSON.parse(json)).catch(() => null);

9

您可以使用 node.js v14 实验性的 json 模块标志导入 json 文件。更多详情请点击此处

file.js

import data from './folder/file.json' assert { type: 'json' }

export default {
  foo () {
    console.log(data)
  }
}

你可以使用 node --experimental-json-modules file.js 来调用它。


我得到了这个错误:TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING]: 模块“src/__tests__/operations.json”需要一个类型为“json”的导入断言 - Serkan KONAKCI

7

您甚至可以使用 require 导入您的 JSON 文件,而无需指定扩展名 .json。 这将使您能够在不更改导入内容的情况下将文件扩展名更改为 .js

假设我们在同一目录中有一个名为 ./myJsonFile.json 的文件。

const data = require('./myJsonFile')

如果将来你将 ./myJsonFile.json 更改为 ./myJsonFile.js,则导入的内容不应更改。


这很令人困惑。您提出的想要将json require更改为js require的示例是一种想象力的伸展。您的答案应该坚持事实,避免假设情况。我还建议您的假定文件名“./myJsonFile.js”令人困惑。如果它具有.js扩展名,为什么会被称为“myJsonFile”?但另一个有用的事实是:如果您执行require('./file')并且存在file.jsfile.json,那么它将使用file.js - Wyck
发现有用的是你可以抑制文件扩展名.json。谢谢 - Manu Artero

3
你可以使用一个模块来创建一个require。
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const foo = require('./foo.json')

1
这是一个很好的答案。虽然你应该要求使用 foo.json 而不是 foo.js - jwerre

1
在ES6中: 从'./somefile.json'导入someObject assert {type: 'json'};

-1

只需使用Node中的JSON对象即可,无需导入。请参见以下用法:

const jsonifiedObject = JSON.parse(an_array or a_object)
or
JSON.stringify(object)

希望这有所帮助。

问题是关于从磁盘获取数据的。您的解决方案仅适用于数据已经加载的情况。 - Corno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接