Node.js 导出行为与 ES6 模块不同
Node.js export behaves differently from ES6 modules
在 ES6 模块中,这按预期工作:
- index.js
import { foo, init } from "./foo";
init();
console.log(foo); // 42
- foo.js
export let foo;
export const init = () => {
foo = 42;
};
但是在 Node.js 中,当我尝试同样的操作时,foo
没有得到更新。
如何在 init()
为 运行 后将 foo
更新为 42
?
- index.js
let { foo, init } = require('./foo');
init();
console.log(foo); // undefined
- foo.js
let foo;
const init = () => {
foo = 42;
};
module.exports = {
init,
foo
};
我知道我可以导出函数 getFoo()
和 returns 更新后的 foo
,但似乎不太方便。
导出 Node.js 中可能会在之后发生变化的变量的正确方法是什么?
此处的行为,您可以在 ES6 模块中看到:
console.log(foo); // undefined
init();
console.log(foo); // 42
与 JS 通常的工作方式相比应该感觉很奇怪 - foo
似乎 是本地标识符,但如果它恰好是从另一个模块导入的,如果其他模块的导出更改,则 foo
绑定无论其导入何处都会更改。
如果不使用 ES6 模块,就没有(合理的)方法可以使用单个标识符复制这种行为。
不过,如果你愿意,你 可以 在 Node 中使用 ES6 模块。使用ES6模块语法的原始代码,然后运行:
node --experimental-modules index.mjs
像 Webpack 这样的构建系统也可以将 ES6 模块中编写的代码转换为 vanilla JS,尽管这种转换后的代码最终会将导入转换为命名空间对象。例如,这个:
import { foo, init } from "./foo";
init();
console.log(foo); // 42
会变成类似
的东西
const fooNamespace = __webpack_require__("./foo.js");
fooNamespace.init();
console.log(fooNamespace.foo);
这就像你有一个对象的引用,当调用其中的函数时,该对象会发生变化。如果你愿意,你可以实现这个。
const obj = {
foo: undefined,
init() { obj.foo = 42 }
};
module.exports = obj;
尽管 可以 使用 ES6 模块使导入的标识符看似自行重新分配,但请记住,由于此类代码可能会造成混淆,有些人更喜欢 avoid such patterns entirely.
在 ES6 模块中,这按预期工作:
- index.js
import { foo, init } from "./foo";
init();
console.log(foo); // 42
- foo.js
export let foo;
export const init = () => {
foo = 42;
};
但是在 Node.js 中,当我尝试同样的操作时,foo
没有得到更新。
如何在 init()
为 运行 后将 foo
更新为 42
?
- index.js
let { foo, init } = require('./foo');
init();
console.log(foo); // undefined
- foo.js
let foo;
const init = () => {
foo = 42;
};
module.exports = {
init,
foo
};
我知道我可以导出函数 getFoo()
和 returns 更新后的 foo
,但似乎不太方便。
导出 Node.js 中可能会在之后发生变化的变量的正确方法是什么?
此处的行为,您可以在 ES6 模块中看到:
console.log(foo); // undefined
init();
console.log(foo); // 42
与 JS 通常的工作方式相比应该感觉很奇怪 - foo
似乎 是本地标识符,但如果它恰好是从另一个模块导入的,如果其他模块的导出更改,则 foo
绑定无论其导入何处都会更改。
如果不使用 ES6 模块,就没有(合理的)方法可以使用单个标识符复制这种行为。
不过,如果你愿意,你 可以 在 Node 中使用 ES6 模块。使用ES6模块语法的原始代码,然后运行:
node --experimental-modules index.mjs
像 Webpack 这样的构建系统也可以将 ES6 模块中编写的代码转换为 vanilla JS,尽管这种转换后的代码最终会将导入转换为命名空间对象。例如,这个:
import { foo, init } from "./foo";
init();
console.log(foo); // 42
会变成类似
的东西const fooNamespace = __webpack_require__("./foo.js");
fooNamespace.init();
console.log(fooNamespace.foo);
这就像你有一个对象的引用,当调用其中的函数时,该对象会发生变化。如果你愿意,你可以实现这个。
const obj = {
foo: undefined,
init() { obj.foo = 42 }
};
module.exports = obj;
尽管 可以 使用 ES6 模块使导入的标识符看似自行重新分配,但请记住,由于此类代码可能会造成混淆,有些人更喜欢 avoid such patterns entirely.