Babel 7 へのアップグレード
Babel 7 にアップグレードする際は、このドキュメントを参照してください。API/統合の変更については、こちらを確認してください。
すべての破壊的変更がすべてのプロジェクトに影響を与えるわけではないため、アップグレード時にテストが失敗する可能性の高い順にセクションを並べ替えました。
Babel全体
Node.js 0.10、0.12、4、および5のサポートは廃止されました #5025、#5041、#7755、#5186
以前のバージョンはメンテナンスされていないため、新しいバージョンの Node.js(LTS v8)を使用することを強く推奨します。詳細については、nodejs/LTSを参照してください。
これは、Babel *自体* が古いバージョンの Node.js では実行されないというだけのことです。古い Node バージョンで実行されるコードを *出力* することはできます。
設定ルックアップの変更
詳細については、6.x と 7.x の比較を参照してください。
Babelには、以前は `node_modules`、シンボリックリンク、モノレポの処理に問題がありました。この点を考慮していくつかの変更を行いました。Babelは、チェーンを検索するのではなく、`package.json`の境界で検索を停止します。モノレポでは、すべてのパッケージで設定を一元化する新しい `babel.config.js` ファイルを追加しました(あるいは、パッケージごとに設定を作成することもできます)。7.1では、必要に応じてさらにルックアップするための`rootMode`オプションを導入しました。
年間プリセットの非推奨化
「env」プリセットはすでに1年以上前から存在しており、以前から存在し推奨されていたプリセットの一部を完全に置き換えています。
babel-preset-es2015
babel-preset-es2016
babel-preset-es2017
babel-preset-latest
- 上記の組み合わせ ^
これらのプリセットは「env」プリセットに置き換える必要があります。
ステージプリセットの非推奨化
明示的なプロポーザルの使用を優先して、ステージプリセットを削除します。移行手順の詳細については、stage-0 READMEを確認してください。
これを自動的に行うには、npx babel-upgrade
を実行できます(PRはこちらに追加されています)。
@babel/polyfill
から提案のポリフィルを削除
同様の考え方に基づき、`@babel/polyfill`からポリフィル提案を削除しました。
現在、`@babel/polyfill`は主に `core-js` v2 のエイリアスです。ソース
以前は2つのインポートのみでした。
import "core-js/shim"; // included < Stage 4 proposals
import "regenerator-runtime/runtime";
提案を使用する場合は、これらを個別にインポートする必要があります。core-js
パッケージまたは npm の別のパッケージから直接インポートする必要があります。
例:
// for core-js v2:
import "core-js/fn/array/flat-map";
// for core-js v3:
import "core-js/features/array/flat-map";
以下は、`core-js` v2 の Stage < 3 の提案ポリフィルのリストです。
詳細
// core-js v2
// Stage 3
import "core-js/fn/string/trim-left";
import "core-js/fn/string/trim-right";
import "core-js/fn/string/match-all";
import "core-js/fn/array/flat-map";
import "core-js/fn/array/flatten"; // RENAMED
import "core-js/fn/global";
// Stage 1
import "core-js/fn/symbol/observable";
import "core-js/fn/promise/try";
import "core-js/fn/observable";
// Stage 1 Math Extensions
import "core-js/fn/math/clamp";
import "core-js/fn/math/deg-per-rad";
import "core-js/fn/math/degrees";
import "core-js/fn/math/fscale";
import "core-js/fn/math/iaddh";
import "core-js/fn/math/isubh";
import "core-js/fn/math/imulh";
import "core-js/fn/math/rad-per-deg";
import "core-js/fn/math/radians";
import "core-js/fn/math/scale";
import "core-js/fn/math/umulh";
import "core-js/fn/math/signbit";
// Stage 1 "of and from on collection constructors"
import "core-js/fn/map/of";
import "core-js/fn/set/of";
import "core-js/fn/weak-map/of";
import "core-js/fn/weak-set/of";
import "core-js/fn/map/from";
import "core-js/fn/set/from";
import "core-js/fn/weak-map/from";
import "core-js/fn/weak-set/from";
// Stage 0
import "core-js/fn/string/at";
// Nonstandard
import "core-js/fn/object/define-getter";
import "core-js/fn/object/define-setter";
import "core-js/fn/object/lookup-getter";
import "core-js/fn/object/lookup-setter";
// import "core-js/fn/map/to-json"; // Not available standalone
// import "core-js/fn/set/to-json"; // Not available standalone
import "core-js/fn/system/global";
import "core-js/fn/error/is-error";
import "core-js/fn/asap";
// Decorator metadata? Not sure of stage/proposal
import "core-js/fn/reflect/define-metadata";
import "core-js/fn/reflect/delete-metadata";
import "core-js/fn/reflect/get-metadata";
import "core-js/fn/reflect/get-metadata-keys";
import "core-js/fn/reflect/get-own-metadata";
import "core-js/fn/reflect/get-own-metadata-keys";
import "core-js/fn/reflect/has-metadata";
import "core-js/fn/reflect/has-own-metadata";
import "core-js/fn/reflect/metadata";
バージョニング/依存関係
ほとんどのプラグイン/トップレベルパッケージには、`@babel/core` の `peerDependency` が含まれるようになりました。
パッケージ名の変更
babylon
は ` @babel/parser` になりました
設定では、パッケージ名の短縮バージョン(`preset-` または `plugin-` を削除)を使用できますが、わかりやすくするためにパッケージ名全体を使用することにしました(それほど多くのタイピングを節約できないため、削除すべきかもしれません)。
{
- "presets": ["@babel/preset-react"],
+ "presets": ["@babel/react"], // this is equivalent
- "plugins": ["@babel/transform-runtime"],
+ "plugins": ["@babel/plugin-transform-runtime"], // same
}
スコープ付きパッケージ
最も重要な変更は、すべてのパッケージをスコープ付きパッケージに切り替えたことです(モノレポ内のフォルダー名は変更されていませんが、`package.json` 内の名前は変更されています)。
これは、意図しない/意図的な名前のスクワッティングの問題がなくなり、コミュニティプラグインからの明確な分離、およびよりシンプルな命名規則になることを意味します。
依存関係は次のように変更する必要があります
babel-cli
-> @babel/cli
。基本的に、`babel-` を ` @babel/` で置き換えることから始めました。
設定での使用
プリセットまたはプラグインを指定する短縮形を使用できます。ただし、スコープ付きパッケージへの切り替えのため、設定に追加する独自のプリセットの場合と同様に、`@babel/`を指定する必要があります。
module.exports = {
presets: ["@babel/env"], // "@babel/preset-env"
plugins: ["@babel/transform-arrow-functions"], // same as "@babel/plugin-transform-arrow-functions"
};
TC39提案には `-proposal-` に切り替え
これは、年次リリース(ES2015、ES2016など)に含まれていないプラグインは、 `-proposal` に名前を変更する必要があることを意味します。これにより、提案が正式に JavaScript に含まれていないことをより明確に示すことができます。
例
@babel/plugin-transform-function-bind
は@babel/plugin-proposal-function-bind
になりました(ステージ0)@babel/plugin-transform-class-properties
は@babel/plugin-proposal-class-properties
になりました(ステージ3)
これはまた、提案がステージ4に移行するときに、パッケージの名前を変更する必要があることを意味します。
パッケージ名から年を削除
一部のプラグインには、名前に `-es3-` または `-es2015-` が含まれていましたが、これらは不要でした。
@babel/plugin-transform-es2015-classes
は @babel/plugin-transform-classes
になりました。
CommonJSでの "use strict"
と this
Babel 6 の ES6 モジュールの変換は、処理対象として指定されたファイルであれば、そのファイルに実際に ES6 の import/export が含まれているかどうかを考慮することなく、無差別に実行されていました。これにより、ファイルスコープの `this` への参照が `undefined` に書き換えられ、Babel で処理されたすべての CommonJS モジュールの先頭に "use strict"
が挿入されていました。
// input.js
this;
// output.js v6
"use strict"; // assumed strict modules
undefined; // changed this to undefined
// output.js v7
this;
この動作は Babel 7 で制限され、`transform-es2015-modules-commonjs` 変換の場合、ファイルに ES6 の import または export が含まれている場合にのみファイルが変更されるようになりました。(編集者注:https://github.com/babel/babel/issues/6242 が実装された場合、これは再度変更される可能性があるため、公開前に再確認する必要があります)。
// input2.js
import "a";
// output.js v6 and v7
"use strict";
require("a");
Babel がすべての CommonJS モジュールに "use strict"
を自動的に挿入することに依存していた場合は、Babel 設定で `transform-strict-mode` プラグインを明示的に使用する必要があります。
React および Flow プリセットの分離
`babel-preset-react` には常に flow プラグインが含まれていました。これにより、タイプミスや `flow` 自体による型チェックを行わずに誤って `flow` 構文を使用するユーザーが多く、エラーが発生していました。
この問題は、TypeScript のサポートを決定したときに複雑化しました。React および TypeScript プリセットを使用したい場合は、ファイルタイプまたはディレクティブを介して、構文を自動的にオン/オフする方法を検討する必要がありました。結局、プリセットを完全に分離する方が簡単でした。
プリセットを使用すると、Babel は Flow / TypeScript(およびその他の言語/方言)によって提供される型を解析し、JavaScript にコンパイルするときにそれらを削除できます。
{
- "presets": ["@babel/preset-react"]
+ "presets": ["@babel/preset-react", "@babel/preset-flow"] // parse & remove flow types
+ "presets": ["@babel/preset-react", "@babel/preset-typescript"] // parse & remove typescript types
}
オプション解析
Babel の設定オプションは Babel 6 よりも厳格になりました。例えば、"presets": 'es2015, es2016'
のようにプリセットをカンマ区切りのリストで指定する方法は以前は技術的には機能していましたが、現在は失敗するため、配列に変更する必要があります #5463。
これは CLI には適用されないことに注意してください。--presets es2015,es2016
は引き続き機能します。
{
- "presets": "@babel/preset-env, @babel/preset-react"
+ "presets": ["@babel/preset-env", "@babel/preset-react"]
}
プラグイン/プリセットのエクスポート
すべてのプラグイン/プリセットは、一貫性を保つため、オブジェクトではなく関数をエクスポートする必要があります(babel/babel#6494 経由)。これはキャッシュに役立ちます。
文字列ベースの設定値の解決
Babel 6 では、(設定ファイルからではなく) Babel に直接渡された値は、コンパイルされるファイルからの相対パスで解決されていたため、多くの混乱を引き起こしていました。
Babel 7 では、値はそれらをロードした設定ファイルからの相対パス、またはワーキングディレクトリからの相対パスのいずれかで一貫して解決されます。
presets
および plugins
の値の場合、この変更により、CLI は次のようなケースで適切に動作するようになります。
babel --presets @babel/preset-env ../file.js
node_modules
フォルダが .
にあると仮定すると、Babel 6 では、プリセットが見つからないため、これは失敗していました。
この変更は only
および ignore
にも影響します。これについては後で詳しく説明します。
パスベースの only
および ignore
パターン
Babel 6 では、only
および ignore
はファイルパスの glob ではなく、一般的なマッチング文字列として扱われていました。これは、例えば *.foo.js
が ./**/*.foo.js
にマッチすることを意味し、ほとんどのユーザーにとって紛らわしく、驚きでした。
Babel 7 では、これらは相対パスまたは絶対パスのいずれかであるパスベースの glob パターンとして扱われるようになりました。これは、これらのパターンを使用していた場合は、パターンがディレクトリの奥深くまで一致するように、少なくとも **/
プレフィックスを追加する必要がある可能性が高いことを意味します。
only
および ignore
パターンは、ディレクトリにも引き続き機能するため、only: './tests'
を使用して tests
ディレクトリ内のファイルのみをコンパイルすることもできます。ネストされたすべてのファイルに一致させるために **/*.js
を使用する必要はありません。
Babel の CLI コマンド
Babel が処理方法を知らないディレクトリ内のすべてのファイルをコピーするように Babel に指示する babel
コマンドの --copy-files
引数も、only
/ignore
チェックに失敗したファイルをコピーするようになりました。以前は、無視されたすべてのファイルはサイレントにスキップされていました。
@babel/node
Babel 6 の babel-node
コマンドは、babel-cli
パッケージの一部でした。Babel 7 では、このコマンドは独自の @babel/node
パッケージに分割されたため、このコマンドを使用している場合は、この新しい依存関係を追加する必要があります。
@babel/runtime
、@babel/plugin-transform-runtime
ランタイムでの Babel のヘルパーを「ポリフィル」動作から分離しました。詳細については、PR を参照してください。
@babel/runtime
にはヘルパーのみが含まれるようになり、core-js
が必要な場合は、@babel/runtime-corejs2
と変換で提供されるオプションを使用できます。どちらの場合も、@babel/plugin-transform-runtime
が必要です。
ヘルパーのみ
# install the runtime as a dependency
npm install @babel/runtime
# install the plugin as a devDependency
npm install @babel/plugin-transform-runtime --save-dev
{
"plugins": ["@babel/plugin-transform-runtime"]
}
core-js
からのヘルパー + ポリフィル
したがって、transform-runtime
で core-js
のサポートが必要な場合は、corejs
オプションを渡して、@babel/runtime
の代わりに @babel/runtime-corejs2
依存関係を使用する必要があります。
# install the runtime as a dependency
npm install @babel/runtime-corejs2
# install the plugin as a devDependency
npm install @babel/plugin-transform-runtime --save-dev
{
"plugins": [
- ["@babel/plugin-transform-runtime"],
+ ["@babel/plugin-transform-runtime", {
+ "corejs": 2,
+ }],
]
}
仕様準拠
@babel/plugin-proposal-object-rest-spread
オブジェクト内の RestElement の後に末尾のカンマを置くことはできません #290
var {
- ...y, // trailing comma is a SyntaxError
+ ...y
} = { a: 1 };
Object Spread は新しいプロパティを定義し、
Object.assign
はそれらを設定するだけであるため、Babel はデフォルトの動作をより仕様に準拠するように変更しました。
// input
z = { x, ...y };
// v7 default behavior: ["proposal-object-rest-spread"]
function _objectSpread(target) { ... }
z = _objectSpread({
x
}, y);
// Old v6 behavior: ["proposal-object-rest-spread", { "loose": true }]
function _extends(target) { ... }
z = _extends({
x
}, y);
// Substitute for Object.assign: ["proposal-object-rest-spread", { "loose": true, "useBuiltIns": true }]
z = Object.assign(
{
x,
},
y
);
@babel/plugin-proposal-class-properties
デフォルトの動作は、以前はデフォルトで「spec」だったものに変更されました
// input
class Bork {
static a = "foo";
y;
}
// v7 default behavior: ["@babel/plugin-proposal-class-properties"]
var Bork = function Bork() {
Object.defineProperty(this, "y", {
enumerable: true,
writable: true,
value: void 0,
});
};
Object.defineProperty(Bork, "a", {
enumerable: true,
writable: true,
value: "foo",
});
// old v6 behavior: ["@babel/plugin-proposal-class-properties", { "loose": true }]
var Bork = function Bork() {
this.y = void 0;
};
Bork.a = "foo";
@babel/plugin-transform-export-extensions
を名前が変更された 2 つの提案に分割
これは長い間待望されていましたが、最終的に変更されました。
@babel/plugin-proposal-export-default-from
export v from "mod";
@babel/plugin-proposal-export-namespace-from
export * as ns from "mod";
@babel/plugin-transform-template-literals
テンプレートリテラルの改訂が更新されました #5523
テンプレートリテラルの改訂の提案を参照してください。
Babel 6 では、Bad character escape sequence (5:6)
がスローされます。
tag`\unicode and \u{55}`;
これは Babel 7 で修正され、次のようなものが生成されます。
// default
function _taggedTemplateLiteral(strings, raw) {
return Object.freeze(
Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })
);
}
var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral(
[void 0],
["\\unicode and \\u{55}"]
);
tag(_templateObject);
// loose mode
function _taggedTemplateLiteralLoose(strings, raw) {
strings.raw = raw;
return strings;
}
var _templateObject = /*#__PURE__*/ _taggedTemplateLiteralLoose(
[void 0],
["\\unicode and \\u{55}"]
);
tag(_templateObject);
通常のテンプレートリテラルでは、以前の「spec」モードをデフォルトとする
// input
`foo${bar}`;
// default v7 behavior: ["@babel/plugin-transform-template-literals"]
"foo".concat(bar);
// old v6 behavior: ["@babel/plugin-transform-template-literals", { "loose": true }]
"foo" + bar;
@babel/plugin-proposal-decorators
新しい decorators の提案の実装を見越して、それを新しいデフォルトの動作にすることにしました。つまり、現在の decorators の構文/動作を継続して使用するには、legacy
オプションを true
に設定する必要があります。
{
"plugins": [
- "@babel/plugin-proposal-decorators"
+ ["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
注: このプラグインを含む
@babel/preset-stage-0
または@babel/preset-stage-1
を使用している場合は、decoratorsLegacy
オプションを渡す必要があります。
@babel/plugin-proposal-pipeline-operator
流動的な新しい提案は、デフォルトでエラーとなり、すべての人が Stage 2 未満の間は特定の提案をオプトインする必要があります。これについては、この投稿で詳しく説明されています。
{
"plugins": [
- "@babel/plugin-proposal-pipeline-operator"
+ ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }]
]
}
babel-plugin-transform-class-constructor-call
を削除しました
babel-plugin-transform-class-constructor-call が削除されました #5119
TC39 はこの提案を破棄することに決定しました。ロジックをコンストラクターまたは static メソッドに移動できます。
詳細については、/docs/plugins/transform-class-constructor-call/ を参照してください。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
- call constructor(x, y) {
+ static secondConstructor(x, y) {
return new Point(x, y);
}
}
let p1 = new Point(1, 2);
- let p2 = Point(3, 4);
+ let p2 = Point.secondConstructor(3, 4);
@babel/plugin-async-to-generator
babel-plugin-transform-async-to-module-method
をオプションにするだけで、通常の async プラグインにマージしました。
{
"plugins": [
- ["@babel/transform-async-to-module-method"]
+ ["@babel/transform-async-to-generator", {
+ "module": "bluebird",
+ "method": "coroutine"
+ }]
]
}
babel
babel
パッケージの削除 #5293
このパッケージは現在、v6 で babel-cli
を代わりにインストールするようにエラーメッセージを表示します。この名前で何か面白いことができると思います。
@babel/register
babel-core/register.js
が削除されました #5132
非推奨の babel-core/register
の使用は Babel 7 で削除されました。代わりにスタンドアロン パッケージ @babel/register
を使用してください。
新しい依存関係として @babel/register
をインストールします
- npm
- Yarn
- pnpm
npm install --save-dev @babel/register
yarn add --dev @babel/register
pnpm add --save-dev @babel/register
Mocha を使用したアップグレード
- mocha --require babel-core/register
+ mocha --require @babel/register
@babel/register
は、現在のワーキングディレクトリ内のファイルのみをコンパイルするようにもなりました(シンボリックリンクの問題を修正するために行われました)。
@babel/register
オプションはマージされるのではなく、置き換えられるようになりました
@babel/generator
quotes
オプションの削除 #5154]
コンパイルされた出力のフォーマットが必要な場合は、recast/prettier/escodegen/fork babel-generator を使用できます。
このオプションは、v6.18.0 で parserOpts
および generatorOpts
を公開するまで、babel-generator
を明示的に介してのみ使用可能でした。そのリリースにバグがあったため、Babel 自体でこのオプションを使用した人はいないはずです。
flowUsesCommas
オプションの削除 #5123
現在、Flow Object Types では 2 つのサポートされている構文 (,
および ;
) があります。
この変更により、babel-generator は ;
の代わりに ,
を出力するだけです。
@babel/core
babel-core/src/api/browser.js
の削除 #5124
babel-browser
は 6.0 で既に削除されています。ブラウザーまたは非 Node 環境で Babel を使用する必要がある場合は、@babel/standalone を使用してください。
Babel は filename
を絶対パスとして返します #8044
@babel/preset-env
loose
モードでは、typeof-symbol
変換が自動的に除外されるようになりました(loose モードを使用している多くのプロジェクトがこれを行っていました)。