gpt4 book ai didi

javascript - Node.js 导出行为不同于 ES6 模块

转载 作者:行者123 更新时间:2023-12-03 12:18:17 26 4
gpt4 key购买 nike

在 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() 并返回更新后的 foo,但似乎不太方便。

在 Node.js 中导出变量的正确方法是什么?

最佳答案

此处的行为,您可以在 ES6 模块中看到:

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

与 JS 通常的工作方式相比应该感觉很奇怪 - foo 看起来 是一个本地标识符,但如果它恰好是从另一个模块导入的,如果其他模块的导出发生变化,foo 绑定(bind)在任何导入位置也会发生变化。

如果不使用 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 .

关于javascript - Node.js 导出行为不同于 ES6 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65606356/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com