Why are static and dynamic imports in node.js treated differently wrt read-only?

Viewed 696

Why would node.js 15.4.0 treat static and dynamic imports differently wrt to their read-only behavior?

I have a file test.mjs which reads

let a = {x: 1};
export default a;

When i use this in a dynamic import:

async function run () {
  var m = await import ("./test.mjs");
  m.d=45;
  console.log (m);
}
run();

it complains that the object is not extensible (and this conforms to my reading of the standard that imports provide read-only bindings).

However, when I use this statically as in

import m from './test.mjs';
m.d = 44;
console.log (m);

this works nicely and outputs {x:1, d:44}.

Why does this work? Is this not in violation of the standard?

The question is of particular importance for a design decision to be taken now and I am afraid eventually node would also treat static imports as read-only.

1 Answers

The same assignment works for the dynamic import:

(async function() {
  const { default: m } = await import("./test.mjs");
//      ^^^^^^^^^^^^^^
  m.d = 45;
  console.log(m);
})();

You need to add the property to the default-exported object, not to the immutable namespace.

You'd get the same error when using a static namespace import:

import * as m from './test.mjs';
m.d = 44;
//  ^ ReferenceError
Related