英文:
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
)的情况,执行顺序如下:
- 你运行
node foo
foo.js
有import {} from './bar'
(在编译时可以静态验证)- 在
foo
的第一行甚至执行之前,bar
模块被编译和执行 - 只有在
bar
模块被执行完毕后,foo
模块才会被执行
对于使用CommonJS(使用require
)的情况,执行顺序是:
- 你运行
node foo
foo.js
被编译- 如果编译没有问题,
foo
开始执行 - 有一个
require('./bar')
- 现在
bar
开始执行 - 当
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:
- you run
node foo
foo.js
has `import {} from './bar' (can be verified statically at compile time)- before even the first like of
foo
gets executed, thebar
module is compiled and executed - only then the
foo
module gets executed
For using CommonJS (with require
) the order of execution is:
- you run
node foo
foo.js
gets compiled- if the compilation was ok
foo
starts getting executed - there is
require('./bar')
- so now
bar
starts getting executed - when
bar
finishes thenfoo
continues getting executed (commands afterrequire
)
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论