概要
ここに 2 つの JavaScript ファイルがあります。
const magica = {
madoka: '鹿目 まどか',
sayaka: '美樹 さやか',
mami: '巴 マミ',
kyoko: '佐倉 杏子',
homura: '暁美 ほむら'
};
export default magica;
import { mami, sayaka } from './magica.js';
console.log(mami); // 巴 マミ
console.log(sayaka); // 美樹 さやか
$ babel-node --version
5.8.23
$ babel-node kyubey.js
巴 マミ
美樹 さやか
この kyubey.js の import
文ですが、オブジェクトを分割代入するときのように1、オブジェクトから任意の値だけを取り出せるので、便利でよく使っていました。次のようなイメージです。
const magica = {
madoka: '鹿目 まどか',
sayaka: '美樹 さやか',
mami: '巴 マミ',
kyoko: '佐倉 杏子',
homura: '暁美 ほむら'
};
({ mami, sayaka } = magica);
console.log(mami); // 巴 マミ
console.log(sayaka); // 美樹 さやか
ところが、Babel 6 に更新したところ kyubey.js がシンタックスエラーで動かなくなてしまいました。
$ babel-node --version
6.22.2
$ babel-node kyubey.js
undefined
undefined
undefined
…こんなのってあんまりだよ
原因
最初はバージョンアップを間違って Babel 環境がおかしくなってしまったのかと思いましたが、そうではありませんでした。どうやら、先ほど紹介した import
文の書き方が ECMASCript の仕様に背いた書き方だったようです。
Babel 6 でこの書き方が取り除かれるまでの経緯が以下の公式 issue にありました。
解決策
default export を使う場合
const magica = {
madoka: '鹿目 まどか',
sayaka: '美樹 さやか',
mami: '巴 マミ',
kyoko: '佐倉 杏子',
homura: '暁美 ほむら'
};
export default magica;
import magica from './magica.js';
const { mami, sayaka } = magica;
console.log(mami);
console.log(sayaka);
$ babel-node --version
6.22.2
$ babel-node kyubey.js
巴 マミ
美樹 さやか
いったんオブジェクトに import
してから、変数に分割代入します。
named export を使う場合
const madoka = '鹿目 まどか';
const sayaka = '美樹 さやか';
const mami = '巴 マミ';
const kyoko = '佐倉 杏子';
const homura = '暁美 ほむら';
export { madoka, sayaka, mami, kyoko, homura };
import { mami, sayaka } from './magica.js';
console.log(mami);
console.log(sayaka);
$ babel-node --version
6.22.2
$ babel-node kyubey.js
巴 マミ
美樹 さやか
あるいは export
したものを全て読み込む場合は、
import * as magica from './magica.js';
const { mami, sayaka } = magica;
console.log(mami);
console.log(sayaka);
$ babel-node --version
6.22.2
$ babel-node kyubey.js
巴 マミ
美樹 さやか
まとめ
Babel 5 で export default
したオブジェクトを分割代入の記法で import
しているコードを書いていると Babel 6 で挙動が変わるので、もし古いバージョンの Babel を使っている場合は書き換えましょう。
参考
- Misunderstanding ES6 Modules, Upgrading Babel, Tears, and a Solution – Medium
- babel/babel > Issues > #2212 Kill CommonJS default export behaviour
-
babel/babel > Issues > #3049 で "That's not destructuring, it just has similar syntax. It's an ImportsList." と言及されていました。 ↩