Node: Why are named imports from JSON forbidden?

Created on 12 Mar 2018  路  2Comments  路  Source: nodejs/node

Nodejs has chosen not to allow named imports for non ES6 modules, as discuseed in the NodeJS ES module directions.

This is done for the following reasons:

V8 team has misgivings on this because it would require pessimistically guarding against all potential side effects for accessing all imported variables, including in ESM to ESM calls. For example, would mean none of those can be inlined.

and

Temporal Dead Zone Problem: Exported names from CJS modules are not definitively known till after the CJS module is evaluated, not at parse time.
ES spec guarantees that exported names are definitively known at parse time, prior to evaluation. For example, ES specifies throwing an error at parse time if an undefined name from an imported module is used, but for CJS modules whether that name is defined or not cannot be absolutely determined till after evaluation.

None of this concerns importing from a JSON file! JSON files do not fall into some bucket of ES5 or ES6 exclusive modules! Therefore, I would like to understand why named imports have been excluded for JSON?

Most helpful comment

It is currently this way for consistency, also in case people want to modify the values or the value of the JSON itself is not an object.

Loading the following foo.json

123

Would not have any sensical named properties but is safely available as a single "default" value.

Loading non-identifier keys would also be problematic for some things like a whitelist.json:

{
  "en-US": true
}

In addition, if we make values available as named properties and as a reference we might have to face some mutability confusion.

[ 0 , 1 ]
import {length}, array from './foo.json';
array.pop();
console.log(length);

or

{ x: 0 }
import obj, * as namespace from './foo.json';
obj.y = 0; // mutates the reference
namespace.y; // not defined

At least thats why it is the way it is today.

All 2 comments

@nodejs/modules

It is currently this way for consistency, also in case people want to modify the values or the value of the JSON itself is not an object.

Loading the following foo.json

123

Would not have any sensical named properties but is safely available as a single "default" value.

Loading non-identifier keys would also be problematic for some things like a whitelist.json:

{
  "en-US": true
}

In addition, if we make values available as named properties and as a reference we might have to face some mutability confusion.

[ 0 , 1 ]
import {length}, array from './foo.json';
array.pop();
console.log(length);

or

{ x: 0 }
import obj, * as namespace from './foo.json';
obj.y = 0; // mutates the reference
namespace.y; // not defined

At least thats why it is the way it is today.

Was this page helpful?
0 / 5 - 0 ratings