CommonJS vs ES 模块执行顺序

问题描述 投票:0回答:0

我使用 npm init -y 启动一个节点项目,并将其配置为使用通用 js。我创建了两个文件,即index.js和app.js

index.js的内容

const {person2,greetingFromPerson2} = require('./app.js');

const person1 = 'Abraham';

module.exports = person1;

console.log(`${person1} greets ${person2}`);

greetingFromPerson2();

app.js 的内容

const person1 = require('./index.js');

const person2 = 'John';

const greetingFromPerson2 = () =>{
    console.log(`${person2} greets ${person1}`);
}

module.exports = {person2,greetingFromPerson2};

当我运行

node index.js
命令时,我得到的输出如下

Abraham greets John
Abraham greets John
John greets [object Object]
(node:3856) Warning: Accessing non-existent property 'Symbol(Symbol.toPrimitive)' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3856) Warning: Accessing non-existent property 'Symbol(Symbol.toStringTag)' of module exports inside circular d

如果像下面这样改变index.js的代码

let person1;

module.exports = person1;

const {person2,greetingFromPerson2} = require('./app.js');

person1 = 'Abraham';


console.log(`${person1} greets ${person2}`);

greetingFromPerson2();

然后运行

node index.js
,我得到以下输出

Abraham greets John
John greets undefined

所以我假设app.js的导入值就像index.js中需要app.js时那些person1变量状态的快照。这意味着当 app.js 导入到 index.js 中时,person1 没有定义和导出,因此在这种情况下,app.js 中 person1 的导入值变得未定义。如果 person1 变量声明、初始化和导出是在 app.js 导入到 index.js 之前进行的,那么 person1 在该导入时刻的值应该在 app.js 中可用。这个假设正确吗?

但是当我更改项目的 package.json 配置以使用 es 模块类型时 并将index.js的内容更改为以下代码

import { person2, greetingFromPerson2 } from './app.js';

let person1 = 'Abraham';

console.log(`${person1} greets ${person2}`);

export default person1;

greetingFromPerson2();

并更改了app.js的代码,如下所示

import person1 from './index.js';

export const person2 = 'John';

export const greetingFromPerson2 = () =>{
    console.log(`${person2} greets ${person1}`);
}

并运行

node index.js
,出现以下输出

Abraham greets John
John greets Abraham

我读到,在 es6 模块中,只有在运行导入文件之后,实际的根 JavaScript 才会运行,所以首先当 app.js 在 index.js 之前运行时,app.js 如何访问 index.js 中的 person1 变量。有人可以解释一下这是如何工作的以及为什么在使用 common.js 时,app.js 无法从 index.js 访问 person1 以及与 es 模块相比 commonjs 的执行顺序是什么以及第一个输出中的警告实际上意味着什么。

我认为如果有人能通过类比来详细说明常见js中的module.exports、export default和es模块中的export如何工作,这将是很好的资源。因为如果有人能够通过类比来创建答案,我认为这对其他人来说也将是有价值的答案。

javascript node.js es6-modules commonjs
© www.soinside.com 2019 - 2024. All rights reserved.