如何在Node 8的Node.js REPL中导入ES模块?

27 浏览
0 Comments

如何在Node 8的Node.js REPL中导入ES模块?

我有一个 ES6 模块 right.mjs。将其作为参数传递给 node 执行可以正常工作:

$ node --version

v8.10.0

$ node --experimental-modules right.mjs

(node:4492) ExperimentalWarning: The ESM module loader is experimental.

执行 right 模块

`执行 right 模块` 是该模块的输出。

相比之下,REPL 中的以下输入需要等待进一步的输入:

$ node --experimental-modules

> (node:4526) ExperimentalWarning: The ESM module loader is experimental.

> import 'right.mjs';

...

我不明白为什么会这样。

同样的情况也发生在:

> import './right.mjs';

...

尝试使用 require 的结果是:

> require('./right.mjs');

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/xxx/right.mjs

at Object.Module._extensions..mjs (module.js:686:11)

at Module.load (module.js:565:32)

at tryModuleLoad (module.js:505:12)

at Function.Module._load (module.js:497:3)

at Module.require (module.js:596:17)

at require (internal/module.js:11:18)

那么,我如何在 Node.js REPL 中导入一个 ES 模块呢?

0
0 Comments

在Node.js的REPL中,我们想要导入一个ES模块,但是在Node 8版本中,这是不可能的。然而,在Node.js v14版本中,可以通过使用import函数来实现,而不是使用import语句。

以下是一个例子:

$ node
Welcome to Node.js v14.4.0.
Type ".help" for more information.
> let myModule;
undefined
> import("./my-module.js").then(module => { myModule = module });
Promise {  }
> myModule.foo();
"bar"

这段代码展示了如何在Node.js的REPL中导入一个ES模块。我们首先声明了一个变量myModule,然后使用import函数来导入my-module.js模块,并将其赋值给myModule变量。接着,我们可以通过myModule.foo()来访问模块的方法或属性。

然而,这种方法似乎无法处理包含export关键字的模块。如果你的模块中包含export关键字,你需要通过module.default来访问默认导出。

另外,如果你的文件中的导入语句没有指定文件扩展名(比如import something from './something';),那么会报错。目前还没有找到解决这个问题的方法。

然而,对于异步导入的问题,可以使用node --experimental-repl-await命令来解决。在导入模块时,可以使用await关键字来等待导入完成,比如const myModule = await import("./my-module.js")。此外,还可以使用--experimental-specifier-resolution=node参数来省略文件扩展名,或者使用自定义加载器(--experimental-loader)来解决这个问题。

,虽然在Node 8版本中无法直接在REPL中导入ES模块,但是在Node.js v14版本中,可以通过使用import函数来实现。然而,如果模块中包含export关键字,需要通过module.default来访问默认导出。目前还没有找到解决文件扩展名问题的方法。对于异步导入的问题,可以使用node --experimental-repl-await命令以及--experimental-specifier-resolution=node参数来解决。

0
0 Comments

问题:如何在Node.js REPL中导入一个ES模块(Node 8)?

原因:在Node.js的v16.9.1版本中,支持顶级等待(top level await),因此更加简单。

解决方法:

let { date } = await import('quasar') // module under node_modules, or your own one, etc.
date.getWeekOfYear(new Date())

这也是Node 18的正确答案。现在应该接受这个答案,但是发帖者已经消失了。

0
0 Comments

问题的原因是,ES模块应该从ES模块范围中导入,而REPL并不被认为是一个ES模块范围。这是因为ES模块的支持是实验性的,随着时间的推移,这种情况可能会改善。在Node.js模块实现中,使用require和import是互斥的,而REPL已经使用了require。从Node.js 13开始,REPL中支持动态导入(import)。通过使用node --experimental-repl-await命令,可以实现动态导入。在Node 16.6中,默认情况下REPL await已经打开,并且有不同的语法。在Node 18中,let { date } = await import('quasar')可以正常工作,无需任何标志。但是需要注意的是,这不是一个静态导入,因此并不能算是“正常工作”。可以看出,REPL在某种异步包装器的CJS模式下运行。考虑到REPL主要用于检查同步代码,这可能会导致不同的意外运行时行为。因此,当前的Node.js REPL无法在Node 8中导入ES模块的解决方法是使用Node.js 13及以上版本,并使用node --experimental-repl-await命令来启用动态导入(import)功能。

0