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

Min*_*eet 5 import module node.js

我有一个ES6模块right.mjs。将其作为参数执行即可node

$ node --version
v8.10.0
$ node --experimental-modules right.mjs
(node:4492) ExperimentalWarning: The ESM module loader is experimental.
executing right module
Run Code Online (Sandbox Code Playgroud)

executing right module 是模块的输出。

与此相反,REPL中的以下输入等待进一步的输入:

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

> import 'right.mjs';
... 
Run Code Online (Sandbox Code Playgroud)

我不明白为什么。

与:

> import './right.mjs';
... 
Run Code Online (Sandbox Code Playgroud)

尝试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)
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*hal 43

使用支持顶级等待的 Node.js v16.9.1,它变得更加简单:

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


dia*_*lic 32

在 Node 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 { <pending> }
> myModule.foo();
"bar"
Run Code Online (Sandbox Code Playgroud)

  • @hallo 它对我来说适用于命名导出和默认导出,但请记住,您必须访问“module.default”中的默认导出。 (4认同)
  • 该扩展现在是强制性的:https://nodejs.org/api/esm.html#esm_mandatory_file_extensions - 我不知道有什么办法解决这个问题。 (2认同)

jak*_*b.g 8

不完全是询问的内容(不是真正的 REPL),但是(使用node 12.6.0),可以通过--eval以下方式从命令行执行 ESM 代码:

  1. 首先,如果您的 ES 模块有.js扩展名而不是.mjs,请"type": "module"输入package.json(参见https://nodejs.org/api/esm.html#esm_enabling)以允许节点将 JS 文件视为模块
  2. node --experimental-modules --input-type=module --eval 'code here'

您可以将其别名esmeval为例如:

alias esmeval='node --experimental-modules --input-type=module --eval'

然后你可以将它用作:

esmeval 'import { method } from "./path/to/utils.js"; console.log(method("param"))'

如果您还不能将 node 12 用作主要版本,但可以通过 安装nvm,请将别名指向 v12 安装:

alias esmeval='/c/software/nvm/v12.6.0/node.exe --experimental-modules --input-type=module --eval'


Est*_*ask 7

目前这是不可能的。ES模块应该从ES模块范围导入,而REPL不被认为是其中之一。随着时间的推移,这会有所改善,因为ES模块的支持是实验性的。在节点模块实现中require和的使用import是互斥的,REPL已使用require

importREPL中期望对动态的支持,但尚不支持动态,最新的Node 11版本会导致错误:

TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]:未指定动态导入回调。

  • 从 Node 16.6 开始,REPL wait 默认打开,并且功能标志具有[不同的语法](https://nodejs.org/api/cli.html#--no-experimental-repl-await)。 (4认同)
  • 我相信现在正在 https://github.com/nodejs/node/issues/33369 中跟踪此问题 (3认同)
  • 这需要更新。`let { date } = wait import('quasar')` 在 Node 18 中运行良好,无需任何标志。 (2认同)