Как импортировать модуль ES в Node.js REPL?

У меня есть модуль 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

executing right module это выход модуля.

В отличие от этого, следующий вход в 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)

Итак, как импортировать модуль ES в Node.js REPL?

5 ответов

Решение

В настоящее время это невозможно. Предполагается, что модули ES импортируются из области действия модуля ES, а REPL не считается таковым. Это может улучшиться со временем, потому что поддержка модулей ES является экспериментальной. Использование require а также import является взаимоисключающим в реализации модуля Node, REPL уже использует require,

Поддержка динамического import ожидается в REPL, пока не поддерживается, последняя версия Node 11 вызывает ошибку:

Ошибка типа [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: динамический обратный вызов импорта не был указан.

Это возможно в 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"

С узлом v16.9.1, который поддерживает ожидание верхнего уровня, это еще проще:

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

Не совсем то, о чем спрашивали (не совсем REPL), но (используя node 12.6.0), можно выполнить код ESM из командной строки через --eval:

  1. Во-первых, если в ваших модулях ES есть .js расширение вместо .mjs, положить "type": "module" в package.json(см. https://nodejs.org/api/esm.html), чтобы разрешить узлу обрабатывать файлы 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"))'

Если вы еще не можете использовать узел 12 в качестве основной версии, но можете установить через nvm, сделайте так, чтобы псевдоним указывал на установку v12:

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

Некоторые поиски в Google по использованию модуля в REPL привели меня сюда, и вот что мне помогло:

      npm install -g libphonenumber-js​
node​
> let lib = require('/opt/homebrew/lib/node_modules/libphonenumber-js')
> lib.isValidPhoneNumber('+97412345678')
false
> lib.isValidPhoneNumber('+15625551234')
true
Другие вопросы по тегам