Import '.json' extension in ES6 Node.js throws an error
Asked Answered
J

6

117

We're trying to use the new ways of exporting and importing modules for ES6 with Node.js. It's important for us to get the version number from the package.json file. The following code should do that:

import {name, version} from '../../package.json'

However, on execution the following error is thrown:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".json" for T:\ICP\package.json imported from T:\ICP\src\controllers\about.js

Is there something we're missing?
Is the extension .json not supported?
Is there another way to retrieve this information using Node.js 13+?

Jink answered 13/2, 2020 at 10:41 Comment(2)
Do you have a json file in that path? Have you tried other ways to import like import pkg from ('../../package.json')?Tarrel
Yes, the .json file location is correct.Jink
P
169

From Node.js version 17.5.0 onward, importing a JSON file is possible using Import Assertions:

import packageFile from "../../package.json" assert { type: "json" };

const {
    name,
    version
  } = packageFile;
  • assert { type: "json" } is mandatory
  • Destructuring such as { name, version } is not possible in the import declaration directly
  • The contents of the JSON file are exported as a default export, so they need to be imported from default.

The dynamic import version looks like this:

const {
    default: {
      name,
      version
    }
  } = await import("../../package.json", {
    assert: {
      type: "json"
    }
  });

Since import assertions and JSON modules have only recently promoted to stage 3, older versions of Node.js might have supported an older syntax. According to the compatibility tables on MDN for import declarations and dynamic import, older versions of Node.js (16.0.0 – 16.14.0 and 17.0.0 – 17.4.0) had varying support:

  • These versions required the --experimental-json-modules flag:

    node --experimental-json-modules about.js
    
  • Some versions did not support import assertions on dynamic import

  • Some versions did not support the "json" type, specifically

  • Some versions relied on an older proposal which did not specify the assert syntax yet

Perdita answered 13/2, 2020 at 11:8 Comment(3)
Hii Idder, Even I got the same error after adding the flag . yarn run dev --experimental-json-modules that's the script is used to run my projectLoveinidleness
But it's annoying to add that flag every time. Can it be set permanently?Companionate
@Companionate You can add the flag to one of your startup scripts in package.json.Extranuclear
P
64

You can sill import require in an ES6 module for Node.js:

import { createRequire } from "module"; // Bring in the ability to create the 'require' method
const require = createRequire(import.meta.url); // construct the require method
const my_json_file = require("path/to/json/your-json-file.json") // use the require method
Pym answered 22/12, 2020 at 3:34 Comment(2)
Node.Js v15 lastest give me this error ReferenceError: require is not definedTranslate
@CAlonsoCOrtega We are creating the require on line 2 of my answer. If it is undefined, you must have skipped the first few lines.Pym
E
28

You can use it as in docs node-js as follow:

import { readFile } from 'fs/promises';

const json = JSON.parse(await readFile(new URL('../../package.json', import.meta.url)));
Edwin answered 17/4, 2021 at 10:22 Comment(2)
If you're doing this on a server... I highly recommend the cleaner fs-extra, which promises everything transparently and supports recursive directory copyMarquetry
eslint throws error on this as the await keyword can only be used within async functionsAmaliaamalie
M
22

2022

From Node.js v16 & v18 official documentation:

import SomeJson from './some.json' assert { type: 'json' }

And run it with the matching experimental flag:

node --experimental-json-modules ./your-file.js
Michellmichella answered 13/6, 2022 at 16:40 Comment(0)
C
0

I had this same issue when compiling using Vite. Not even changing with to asset worked for me, I had to change the file from .json to .js and add export default at the beginning of the file to be able to import the data.

For me, this was the solution and it also simplified all the NodeJS syntax bureaucracy.

Concernment answered 20/12, 2023 at 12:34 Comment(0)
E
-15

try to use

process.env.npm_package_version

this might help you

Earhart answered 13/2, 2020 at 10:54 Comment(4)
This will only work if the app is started with npm, which is not always the case.Jink
did you try using fs to load the file ?Earhart
That seems to be bad practice as it loads the complete file which shows the dependencies and other information that mekes the app vulnerable to attacks.Jink
This feature will probably be removed... due to the mentioned security concerns, and the lack of support for deno and qbrtMarquetry

© 2022 - 2024 — McMap. All rights reserved.