for (const x of [1, 2, 3]) { console.log(x); }これを↓以下のような
.babelrc
の設定↓で変換してみましょう。
[ "@babel/preset-env", { "targets": { "node": "8.5.0" }, "useBuiltIns": "usage", "corejs": 3, "modules": false } ]すると↓こうなります↓。
import "core-js/modules/es.array.iterator"; for (const x of [1, 2, 3]) { console.log(x); }
何か問題ある?
ありません。Node.js v11以前では。試しにv8.5で実行してみましょう。
$ node --experimental-modules example.mjs (node:5717) ExperimentalWarning: The ESM module loader is experimental. 1 2 3最初の
ExperimentalWarning
は、実験的機能のES Modulesを使っているよという警告なので特に気にしなくてもOKです。ところが、v12で実行するとこうなります。
$ node --experimental-modules example.mjs (node:5693) ExperimentalWarning: The ESM module loader is experimental. internal/modules/esm/default_resolve.js:79 let url = moduleWrapResolve(specifier, parentURL); ^ Error: Cannot find module /path/to/example/node_modules/core-js/modules/es.array.iterator imported from /path/to/example/dist/example.mjs at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:79:13) at Loader.resolve (internal/modules/esm/loader.js:73:33) at Loader.getModuleJob (internal/modules/esm/loader.js:152:40) at ModuleWrap.エラーが出てしまいました。(internal/modules/esm/module_job.js:43:40) at link (internal/modules/esm/module_job.js:42:36) { code: 'ERR_MODULE_NOT_FOUND' }
何が原因?
前回の記事に書きましたが、Node.js v12からES Modulesで拡張子が必須になったことが原因です。つまり、core-jsパッケージ内の
modules/es.array.iterator.js
を拡張子なしでimportしたのでNode.js v12の制約にひっかかったのです。どうすりゃいい?
前回の記事でも書いたとおり、とりあえず--es-module-specifier-resolution=node
オプションを指定すれば回避できます。でも、今後はNode.js v12とES Modulesが標準になっていくでしょうし、毎回
--es-module-specifier-resolution=node
をつけるのはイヤですよね。Babel側でちゃんと対応してくれればいいのですが。
救いの神登場
なんと、つい先日BabelにこんなIssueとPull Requestが登場しました。- Generated code by preset-env causes error on Node.js v12 and ES Modules
- Add ".js" extension to polyfill #10548
Babelの開発体制は1つのPull Requestに対して2人の承認が必要のようで、1人はすでに承認しているのであと1人がOKを出せば取り込まれます。
取り込まれるまでは
--es-module-specifier-resolution=node
をつけて我慢しましょう。そんな救いの神とは…
\ ヽ | / / \ ヽ | / / \ / _ わ た し で す _ / ̄\ ― |^o^| ― \_/  ̄  ̄ / \ / / | ヽ \ / / | ヽ \
0 件のコメント:
コメントを投稿