いよいよ Babel 7 のリリースが近づいてきました。そこで、公式ブログから個人的に気になる変更点をまとめてみました 。
Nearing the 7.0 Release · Babel
https://babeljs.io/blog/2017/12/27/nearing-the-7.0-release
スコープ付きパッケージへの名前変更
個人的には、今回の Babel 7 で最大の変更点は、何と言ってもスコープ付きパッケージ方式(scoped packages 1)の採用だと考えます。簡単に言うと、パッケージ名が babel-*
から @babel/*
に変更された、ということです。以下、例です。
-
babel-cli
->@babel/cli
-
babel-core
->@babel/core
-
babel-preset-env
->@babel/preset-env
この変更により、package.json
の修正が必要となります。自動アップグレードツールを作ろうとする issue も上がっていますが、どうなるかは分かりません。手動で修正する場合は、次のようになるでしょう。
{
"dependencies": {
- "babel-core": "6.26.0"
+ "@babel/core": "7.0.0-beta.31"
}
}
{
- "presets": ["env"]
+ "presets": ["@babel/preset-env"]
}
変更の理由を、ブログより抜粋します(私訳ですので、読みづらい部分がありましたら遠慮なくリクエストください )。
名前付けは難しい: 他の誰かが自分のプラグインに私たちの命名規約を使うことを決めたかどうかを、私たちがチェックする必要はなくなります。
Naming is difficult: we won’t have to check if someone else decided to use our naming convention for their own plugin
- ときどき人々は、それが面白いからという理由で
babel-preset-20xx
やその他のパッケージを作ります。そして、私たちはそれを戻してもらうようにお願いするために issue やメールを作らなければなりません。- 人々は正当なパッケージをもちますが、私たちが呼びたかったものと同じ名前になることがあります。- 人々は(オプショナル・チェイニング、パイプライン演算子といった)新しい提案がマージされるのを見て、フォークすることを決め、同じ名前でそのバージョンを公開します。それから、私たちが公開するとき、そのパッケージはすでに公開されていると私たちに伝えてきます 🤔 。このとき、私は彼らのメールアドレスを探し、彼らと npm サポートの両方にそのパッケージを戻して再公開してくれるようにメールしなければなりません。
Similarly, package squatting
- Sometimes people create
babel-preset-20xx
or some other package because it’s funny, and then we have to make an issue/email to ask for it back.- People have a legit package, but it happens to be the same name as what we wanted to call it. - People see that a new proposal is merging (like optional chaining, pipeline operator) and decide to fork and publish a version of it under the same name. Then, when we publish, it tell us the package was already published 🤔. Then, I have to find their email and email both them and npm support to get the package back and republish.
「公式」パッケージとは何でしょうか、同じ名前をもつユーザー/コミュニティパッケージとは何でしょうか?私たちは間違った名前や非公式のパッケージを使っている人々から issue レポートを受けることがあります、なぜなら彼らはそれが Babel の一部であると考えたからです。これに関する例の一つは、
babel-env
が人々の.babelrc
ファイルを書き換えていたというレポートです、彼らがそれはbabel-preset-env
ではないと気付くまでにしばらくかかりました。 4What is an “official” package and what is a user/community package with the same name? We can get issue reports of people using misnamed or unofficial packages because they assumed it was part of Babel. One example of this was a report that
babel-env
was rewriting their.babelrc
file, and it took them a while to realize it wasn’tbabel-preset-env
.
以上の3つの理由から、scoped packages の採用を決めています。npm パッケージの命名は紳士協定のようなところもあるので、余計なトラブルを防止する目的が大きいようです。
Angular も scoped packages を採用しているので、比較的大きなエコシステムをもつパッケージでは、今後 scoped packages の採用が進むかもしれません(ESLint など)。
私たちユーザー側からも、公式・非公式の区別が明確になるので、余計な混乱は起こらなくなります。
ただし、名前の変更はかなり影響があると思いますので、サードパーティのパッケージが新しい名前に対応するまでに時間がかかる可能性もあります。そうなると、Babel 7 が浸透するまではしばらく時間がかかるかもしれません。
@babel/preset-env
(babel-preset-env
) の推奨
もう一つ大きな変更点は、babel-preset-es20xx
パッケージが非推奨となり、@babel/preset-env
が推奨となる、という点です。ECMAScript 仕様は年々アップデートされるので、年次を指定する必要性が徐々に薄れてきており、また preset-env
パッケージを使えば実行環境に合わせて自動で適切なプリセットを選んでくれます。またまた、ブログより抜粋してみます。
どの Babel プリセットを使うべきかを決めなければならないことよりも良いこととは何でしょうか?それは、 Babel があなたのために自動で決めてくれることです!
What’s better than you having to decide which Babel preset to use? Having it done for you, automatically!
データのリストを維持するための作業量は膨大だとしても — 再度、なぜ私たちは助けが必要なのでしょう — それは複数の問題を解決してくれます。それはユーザーが仕様を最新にしていることを確認してくれます。それは設定・パッケージの混乱を少なくします。それはアップグレードパスを簡単にします。そして、それは何が何だかに関する issue を減らします。
Even though the amount of work that goes into maintaining the lists of data is humongous — again, why we need help — it solves multiple issues. It makes sure users are up to date with the spec. It means less configuration/package confusion. It means an easier upgrade path. And it means less issues about what is what.
以上のように preset-env
を使うことのメリットをかなり強調していますね!現在の Babel 6 でも babel-preset-env
パッケージは使えるので、一旦 babel-preset-20xx
を babel-preset-env
に置き換えておいて、Babel 7 が安定してきたタイミングで @babel/preset-env
に変更する、という方法もアリかもしれません。
@babel/core
の peer dependency 化
@babel/core
パッケージが dependencies
から peerDependencies
に移動されました 5 。これにより、@babel/core
を明示的にインストールするよう package.json
の修正が必要になるかもしれません。必要な peer dependencies がインストールされていないと、npm install
で次のような警告メッセージが表示されます。
@babel/cli@7.0.0-beta.36
requires a peer of@babel/core@7.0.0-beta.36
but none is installed. You must install peer dependencies yourself.
{
"dependencies": {
- "babel-cli": "6.26.0"
+ "@babel/cli": "7.0.0-beta.36",
+ "@babel/core": "7.0.0-beta.36"
}
}
どのようなケースで修正が必要になるかを見るため、再度ブログを引用します(babel-loader
は以前から導入済み)。
私たちは
@babel/core
への peer dependency を導入しています、これはすべてのプラグイン(@babel/plugin-class-properties
)、プリセット(@babel/preset-env
)、そしてトップレベルパッケージ(@babel/cli
、babel-loader
)が対象です。We are introducing a peer dependencies on
@babel/core
for all the plugins (@babel/plugin-class-properties
), presets (@babel/preset-env
), and top level packages (@babel/cli
,babel-loader
).
gulp-babel
や rollup-plugin-babel
などの @babel/core
を dependencies
に指定しているサードパーティパッケージを使っている場合、すでに Beta 版がリリースされていますので、一緒にアップグレードする必要があります。
これらは Babel の作者からプルリクエストが投げられていますので、 Babel 7 リリースに合わせてすぐに対応してくれると考えられます。その他のパッケージについては、もしかしたら対応まで時間がかかるかもしれません。
-
gulp-babel@8.0.0-beta.0
... package.json -
rollup-plugin-babel@4.0.0-beta.0
... package.json
実際の変更例
自作ライブラリのリポジトリで Babel 7 へのアップグレードを試すプルリクエストを作ってみました。イメージがつかめるかと思います。
まとめ
以上、個人的に気になる Babel7 の3つの変更点を紹介しました。他にも .babelrc.js
のサポートなど、便利な新機能がありますので、気になる方は公式ブログや GitHub リポジトリをチェックしてみてください !
また、本記事内で気になる点や、間違っている点などがありましたら、お気軽にコメント/修正リクエストをお願いします !
-
scoped packages についての詳細は、こちらの npm 公式ドキュメントを参照してください。 ↩
-
「パッケージ不法占拠(package squatting)」については、こちらの npm 公式ドキュメントを参照してください。npm パッケージ名は基本的に早い者勝ちで取得できるので、このようなルールがあるようです。 ↩
-
「squatting」という単語については、今回初めて知りました 。どう訳していいか分からず「不法占拠」という語を与えましたがあまりピンとこないので、適切な訳語をご存知の方は教えてください 。 ↩
-
babel-env
は.babelrc
ファイルを書き換えるパッケージ。Babel 公式パッケージであるbabel-preset-env
とは別物。 ↩ -
peer dependencies についての詳細は、npm 公式ドキュメントおよび Node.js ブログを参照してください。その目的は、異なるバージョンの同一パッケージをインストールしてしまう問題を防ぐことです。 ↩