在一个文件中对进程模块的更改在另一个文件中未显示。

huangapple go评论67阅读模式
英文:

Changes to process module in one file don't show up in another

问题

The process模块在NodeJS中似乎不是全局的。换句话说,在一个模块中对它的更改不会在其他模块中显示出来。

我写了一小段代码来确认我的发现。以下是代码:

server.js

import app from "./app.js";

process.on("uncaughtException", (err) => {
  console.log("UNCAUGHT EXCEPTION: shutting down ...");
  console.log(err.name, err.message);
  process.exit(1);
});

// 服务器
const port = process.env.PORT || 3000;
const server = app.listen(port, () => {
  console.log(`App running on port ${port}...`);
});

app.js

import express from 'express';

const app = express();

console.log(y);

export default app;

当我用node server.js运行代码时,我得到以下错误:

file:///tmp/node-test/app.js:5
console.log(y);
            ^

ReferenceError: y is not defined
    at file:///tmp/node-test/app.js:5:13
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)

然而,当我把console.log(y)移到server.js中时,我得到了一个错误,看起来像这样:

UNCAUGHT EXCEPTION: shutting down ...
ReferenceError y is not defined

这就是我在app.js中放置console.log(y)时期望看到的。看起来我在server.js中对process进行的更改在app.js中并不起作用。我尝试在网上找到答案,但没有结果。我的搜索技能不够好。

有人知道发生了什么,我该如何解决吗?由于编码标准的原因,我不能使用require,必须使用import

英文:

The process module in NodeJS doesn't seem to be global. In other words, the changes I make to it in one module don't show up in other modules.

I wrote a small piece of code to confirm demo my findings. Here is the code:

server.js

import app from "./app.js";
 
process.on("uncaughtException", (err) => {
  console.log("UNCAUGHT EXCEPTION: shutting down ...");
  console.log(err.name, err.message);
  process.exit(1);
});
 
// Server
const port = process.env.PORT || 3000;
const server = app.listen(port, () => {
  console.log(`App running on port ${port}...`);
});

app.js

import express from 'express'
 
const app = express();
 
console.log(y)    
 
export default app;

When I run the code with node server.js, I get a following error:

file:///tmp/node-test/app.js:5
console.log(y);
            ^
 
ReferenceError: y is not defined
    at file:///tmp/node-test/app.js:5:13
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)

However when I move a line console.log(y) into server.js I get an error that looks like this:

UNCAUGHT EXCEPTION: shutting down ...
ReferenceError y is not defined

Which is what I expected to see when console.log(y) was in app.js.

It looks like changes I made in server.js with respect to process don't show up in app.js. I tried to find an answer online, but came up empty. My search foo wasn't good enough.

Does anyone know what's going on and how do I fix it? Because of coding standards I cannot use require, I must use import

答案1

得分: 1

以下是翻译好的内容:

当您使用以下命令启动程序时:

node server.js

接下来发生的是server.js被编译(如果它有语法错误,即使在程序的末尾通过添加明显无法解析的内容,比如闭合括号而没有打开括号,如)))),那么它会在此处以错误Uncaught SyntaxError: Unexpected token '')'或类似的错误结束。但是语法是正确的。谁知道,在实际执行时,全局变量y可能已经被定义。

然后,有一个导入语句:

import app from "./app.js";

所以现在app.js被编译。它在语法上没问题,所以它被执行。只有在执行完app.js之后,server.js的剩余部分才能继续执行。但是,app.js引用了一个未定义的y的引用,因此会抛出异常,整个过程都会退出。

这就是执行的结束。所以在文件server.js的导入语句下面的部分都不会被执行(您可以通过在导入语句下方添加控制台日志进行确认),包括process.on()命令

注意:

对于使用ES模块(使用import)的情况,执行顺序如下:

  1. 你运行 node foo
  2. foo.jsimport {} from './bar'(在编译时可以静态验证)
  3. foo的第一行甚至执行之前,bar模块被编译和执行
  4. 只有在bar模块被执行完毕后,foo模块才会被执行

对于使用CommonJS(使用require)的情况,执行顺序是:

  1. 你运行 node foo
  2. foo.js 被编译
  3. 如果编译没有问题,foo开始执行
  4. 有一个 require('./bar')
  5. 现在 bar 开始执行
  6. bar 完成后,foo 继续执行(require之后的命令)

您可以在简单的示例中验证它:

ES 模块:

foo.js:

console.log('foo 1');
import {} from './bar.js';
console.log('foo 2');

bar.js:

console.log('bar 1');
export const x = {};
console.log('bar 2');

CommonJS:

foo.js:

console.log('foo 1');
require('./bar.js');
console.log('foo 2');

bar.js:

console.log('bar 1');
module.exports = {};
console.log('bar 2');

对于 ES 模块运行 node foo.js 输出:

bar 1
bar 2
foo 1
foo 2

对于 CommonJS 运行 node foo.js 输出:

foo 1
bar 1
bar 2
foo 2

您可以进行实验并添加不同类型的编译时和运行时错误,看看最后会打印出什么。

英文:

When you start your program with this command:

node server.js

Then what happens is that server.js got compiled (so if it had a syntax error even at the end of the program by adding something obviously impossible to parse, like closing parens without opening ones like )))) then it would end at this point with error Uncaught SyntaxError: Unexpected token ')' or something like this. But syntax is fine. Who knows, a global variable y could be defined at the time it is actually executed.

Then, there is an import:

import app from "./app.js";

So now the app.js gets compiled. It is syntactically ok so it is executed. Only after it is executed then the rest of server.js could continue being executed. But app.js references a reference to y that is not defined, so the exception is thrown and the entire process exits.

This is the end of executing anything. So nothing below the import in file server.js gets executed (you can confirm it by adding console logs below the import), including the process.on() command.

Note:

For using ES modules (with import) the order of execution is:

  1. you run node foo
  2. foo.js has `import {} from './bar' (can be verified statically at compile time)
  3. before even the first like of foo gets executed, the bar module is compiled and executed
  4. only then the foo module gets executed

For using CommonJS (with require) the order of execution is:

  1. you run node foo
  2. foo.js gets compiled
  3. if the compilation was ok foo starts getting executed
  4. there is require('./bar')
  5. so now bar starts getting executed
  6. when bar finishes then foo continues getting executed (commands after require)

You can verify it on simple examples:

ES Modules:

foo.js:

console.log('foo 1');
import {} from './bar.js';
console.log('foo 2');

bar.js:

console.log('bar 1');
export const x = {};
console.log('bar 2');

CommonJS:

foo.js:

console.log('foo 1');
require('./bar.js');
console.log('foo 2');

bar.js:

console.log('bar 1');
module.exports = {};
console.log('bar 2');

Running node foo.js for ES Modules prints:

bar 1
bar 2
foo 1
foo 2

Running node foo.js for CommonJS prints:

foo 1
bar 1
bar 2
foo 2

You can play with it and add different kinds of compile time and run time errors and whaat is printed last.

huangapple
  • 本文由 发表于 2023年4月20日 00:52:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76057039.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定