3

In ES6 modules, this works as expected:

  • index.js
import { foo, init } from "./foo";

init();
console.log(foo);  // 42
  • foo.js
export let foo;
export const init = () => {
  foo = 42;
};

However in Node.js, when I tried the same thing, the foo didn't get updated.

How can I make the foo updates to 42 after init() is run?

  • index.js
let { foo, init } = require('./foo');

init();
console.log(foo);  // undefined
  • foo.js
let foo;

const init = () => {
    foo = 42;
};

module.exports = {
    init,
    foo
};

I know I could export a function getFoo() and returns the updated foo, but it seems not very convenient.

What's the proper way to export a variable in Node.js that may change after?

1 Answer 1

2

The behavior here, which you can see in ES6 modules:

console.log(foo);  // undefined
init();
console.log(foo);  // 42

should feel pretty odd in comparison to how JS normally works - foo appears to be a local identifier, but if it happens to be an import from another module, if the other module's export changes, the foo binding wherever it's imported will change as well.

Without using ES6 modules, there is no (reasonable) way to replicate that sort of behavior using a single identifier.

You can use ES6 modules in Node if you want, though. Use the original code with the ES6 module syntax, and then run:

node --experimental-modules index.mjs

Build systems like Webpack can also transpile code written in ES6 modules into vanilla JS, though such transpiled code ends up turning the imports into a namespace object. Eg, this:

import { foo, init } from "./foo";

init();
console.log(foo);  // 42

will turn into something like

const fooNamespace = __webpack_require__("./foo.js");
fooNamespace.init();
console.log(fooNamespace.foo);

It's just like if you had a reference to an object which, when a function inside it is called, mutates the object. You could implement this if you wanted.

const obj = {
  foo: undefined,
  init() { obj.foo = 42 }
};
module.exports = obj;

Although one can use ES6 modules to make imported identifiers seemingly reassign themselves on their own, keep in mind that, since such code is potentially confusing, some prefer to avoid such patterns entirely.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.