1

I want to import package.json into test.js, both files are in same directory.

I tried with require :

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

console.log({ jsonfile });

it throws error:

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)

This error implies, like it runs in browser, where is no require, I found an answer with similar message.

I tried with 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'
}

What I have tried more?

  • Single quotes and double quote around filename
  • filename with extension and without.
  • with flag --experimental-json-modules
  • adding "type":"module into package.json (but this is for Node >= 13, but without it I got warning (node:7170) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. and then also error SyntaxError: Cannot use import statement outside a module)

I found even suggestions to load JSON-file as regular text files and parse them into data structure, but this seems like the last resort...

It seems such a trivial task, but I have not found the idiomatic way how to import JSON-data into Javascript variable. What is wrong here? How should I import it?

I use Node 12.21.0

w.k
  • 8,038
  • 4
  • 27
  • 50
  • You should be able to `require` a json file in Node, not sure what is going wrong. – olawrdhalpme Mar 20 '21 at 20:55
  • The current LTS for Node is 14, and the current stable is 15, so at the very least you probably want to update to 14, but if you _have_ to use 12: you're not writing ES module code, why would you try to force Node into running your code as if it is? Just run `node test.js` (not `node test`), and your code will run just fine. – Mike 'Pomax' Kamermans Mar 20 '21 at 20:56
  • `require("./file.json");` should work. Is it just a typo? package**s**.json vs. package.json? – simon.ro Mar 20 '21 at 21:03
  • @simon.ro yes, it was just typo here, in actual code it was `package.json` – w.k Mar 20 '21 at 22:10
  • @Mike'Pomax'Kamermans Thank you for pointing out old version, seems reasonable to upgrade. And I run always with extension. – w.k Mar 20 '21 at 22:11

2 Answers2

2

You're using Node.js in ESM mode, ESM does not currently import JSON modules by default. You can either:

  1. Turn on JSON module importing (by passing a CLI flag) OR
  2. Create a require function in your ESM code and use that OR
  3. JSON.parse the file manually

Turn on JSON module importing (by passing a CLI flag)

You can do that by passing the --experimental-json-modules flag.

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

Create a require function in your ESM code

You can also always fall back on CommonJS modules and create a require of your own:

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

JSON.parse the file manually

You can always just read JSON files with regular filesystem methods:

# const fs = require('fs');
import * as fs from 'fs';
const result = JSON.parse(fs.readFileSync('./package.json'));
Benjamin Gruenbaum
  • 246,787
  • 79
  • 474
  • 476
  • I am not sure if `--experimental-json-modules` works on Node.js 12, so you might be down to `createRequire`. – Benjamin Gruenbaum Mar 20 '21 at 21:00
  • 1
    I can confirm: all those 3 variants work fine. With flag `--experimental-json-modules` I did not include extension (was './package'). Thank you! – w.k Mar 20 '21 at 22:08
  • ESM doesn't just not "currently" support JSON, it will never support JSON =) – Mike 'Pomax' Kamermans Mar 20 '21 at 22:51
  • @Mike'Pomax'Kamermans JSON modules reached stage 3 in last month https://github.com/tc39/proposal-json-modules#json-modules and is currently in-development in Chrome https://www.chromestatus.com/feature/5749863620804608 . anything you know I don't regarding the chances of it shipping in browsers or being unflagged? (If TC39 ships it, we'll 100% ship it in Node.js) – Benjamin Gruenbaum Mar 21 '21 at 08:15
  • @w.k thanks, I'm happy I could help - I'm not sure why your question got downvoted (I upvoted it, I think it's a good and reasonable question). Probably because it sounds too similar to an "easy" question (how to do it without ECMAScript modules) – Benjamin Gruenbaum Mar 21 '21 at 08:16
  • interesting, I thought it got shot down as proposal, guess that changed since last time I looked. – Mike 'Pomax' Kamermans Mar 21 '21 at 16:37
0

The import syntax should be always working, but in this case you are requiting it wrong. Try import jsonfile from './packages.json';. Youn don't need the * in this case

voxtool
  • 355
  • 1
  • 9