代码之家  ›  专栏  ›  技术社区  ›  Hao Wu

节点.js导出的行为与ES6模块不同

  •  3
  • Hao Wu  · 技术社区  · 4 年前

    • 索引.js
    import { foo, init } from "./foo";
    
    init();
    console.log(foo);  // 42
    
    export let foo;
    export const init = () => {
      foo = 42;
    };
    

    但是在节点.js,当我尝试同样的方法时 foo

    我怎么才能做这个 更新到 42 之后 init() 他跑了吗?

    • foo.js公司
    let foo;
    
    const init = () => {
        foo = 42;
    };
    
    module.exports = {
        init,
        foo
    };
    
    let { foo, init } = require('./foo');
    
    init();
    console.log(foo);  // undefined
    

    getFoo() 并返回更新的 ,但似乎不是很方便。

    在中导出变量的正确方法是什么节点.js以后可能会改变吗?

    1 回复  |  直到 4 年前
        1
  •  2
  •   CertainPerformance    4 年前

    这里的行为,您可以在ES6模块中看到:

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

    与JS的正常工作方式相比,应该会觉得很奇怪- foo 出现 作为本地标识符,但如果它恰好是来自另一个模块的导入,如果另一个模块的导出发生更改,则 无论它被导入到哪里,绑定都会发生变化。

    如果不使用ES6模块,就没有(合理的)方法使用单个标识符来复制这种行为。

    你呢 不过,如果需要,可以在Node中使用ES6模块。使用ES6模块语法的原始代码,然后运行:

    node --experimental-modules index.mjs
    

    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