Webpack 4におけるbabelの設定(2020年5月)
【レポジトリ】
templateとして使ってください。そして何かあればコメント下さい。フォークしてプルリク作ってくれるとありがたいです。
- JavaScriptバージョン
- TypeScriptバージョン
【関連記事】
【概要】
Babelの設定。簡単と見せかけてTSとJSで挙動が違った。あれこれ調べたが、最終的な設定はこれだけでよい。
トランスパイル
JSもTSもwebpackのbabel-loaderで行う。
// webpack.common.jsmodule.exports = ({ outputFile, assetFile, envFilePath, assetPath }) => {
return { ... module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
use: 'eslint-loader',
exclude: /node_modules/,
},
{
test: /\.js$/,
// transpile
use: 'babel-loader',
exclude: /node_modules/,
}, ...
babel-loaderを実行する前にeslint-loaderで構文チェックを行なっている。これはローカル開発環境でもビルド環境でも共通。pre-commitやpre-pushで構文チェックを行う設定はしていないので、ローカル開発で発生していたlintエラーに気がつかずに自動ビルドでこけることが予想出来るが、それでいいと思う。
browserslist
で対応するブラウザを指定する
babelで対応ブラウザを指定することもできるが、browserslistに選定を一任することで、autoprefixerと合わせて対応ブラウザを決められる。シェア何%以上や、最新何バージョンなどの対応も出来るのでこれを使う。
// .browserslistrc# 対応するブラウザを指定する。bable(JSの構文変換), postcssでautoprefixer(cssの構文変換)で読み込まれている。
# 通常はdefaults。詳しくはhttps://github.com/browserslist/browserslist#best-practicesdefaults# defaults以外を指定したい場合はこちらを参照。cover99.5%でダメなら多分コードを変えないとダメ。 https://github.com/browserslist/browserslist#full-list
# cover 99.5%
to C向けの案件あまりやらないのでそこまで気にすることはないが、パフォーマンスよりもとりあえず動くことが大事なので、お任せするに越したことはないという考え。
ほとんどのuserはdefaultsでいいでしょう。とされているので素直に従う。defaultsは > 0.5%, last 2 versions, Firefox ESR, not dead
とのこと。
babelの設定
インストールしたモジュールは、
@babel/core
バベル本体的な存在と思われる@babel/preset-env
こちらも必須とと思われる。babelの設定をまるっと行なってくれる。
の2つに加えて、
TSでは
@babel/preset-typescript
TS TypeScriptの変換には必須。
JSでは
core-js
バージョン3を使用。特定の構文変換で使用。
@babel/cli
はいらないと思ったので入れなかった。
.babelrc の設定
browserslist
との連携はtargetsなどを個別に指定しなければ babel/preset-env
が暗黙的に行なってくれる。 なのでここでは指定しない。
TSの場合はこれだけ。async/awaitで書いたコードが正常に動作する。
// .babelrc{
"presets": ["@babel/preset-typescript"]
}
JSの場合は corejs
が必要。これがないと動かなかった。
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": { "version": 3, "proposals": false }
}
]
]
}
- useBuiltIns これがpolyfillをどう扱うかの設定。async/awaitの変換にはcore-jsが必要だった。
version7.4からは@babel/polyfill
を使わないことが推奨されているので注意。両方入れるとバグるらしい。usage
はそれぞれのファイルでポリフィルが使われる時に特定のポリフィルを使用する。jsのコードでインポートする必要はない。entry
と指定する場合は、使用するファイルでcore-js
をインポートする必要がある。今回はとにかくコードだけを書けば実装を進められるのがコンセプトなので、迷わずusage
を選択。
TSで使用している @babel/preset-typescript
ではcore-jsについて何も明記されていないし、@babel/preset-typescript
が包括している@babel/plugin-transform-typescript
にも書いていないのでよくわからなかった。
【追記】
optional chainingを利用するためにはtype-scriptでもcore-jsが必要だった。
// .babelrc{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": { "version": 3, "proposals": false }
}
],
"@babel/preset-typescript"
]
}document.addEventListener('DOMContentLoaded', () => {
const testGetButton = document.getElementById('testGet');testGetButton?.addEventListener('click', async () => {
try {
const { data } = await commonApi.get(endPoints.testArray);
alert(JSON.stringify(data));
} catch (error) {
console.error(error);
}
});...
TSの注意事項
@babel/plugin-transform-typescript
に ある注意事項をいくつかピックアップする。
- const enumはサポートしていないので、使う場合はbabel-plugin-const-enumが必要。
export =
とimport =
はES nextにコンパイル出来ないのでサポートしていない。- tsconfig.jsonの変更はバベルに反映されない。ビルドプロセスでは
isolatedModules
がオンになるが、対処はできる。 - export let, var はサポートしていない。
などなど書いてあった。
まとめ
- browserslistで対応ブラウザを指定
- babelの設定箇所ではブラウザを指定しない。(browserslistの設定を読みにいかなくなる。)
@babel/polyfill
は古いので、今は使わない。core-jsを使う。- TypeScriptを使う時は注意が必要な箇所もある。
【感想】
babel polyfillは今は推奨されていない。とよく読むと書いてあるが、公式ドキュメントの中でpolyfillがサイドバーメニューにあったりでわかりにい部分があった。こちらもググって古い情報を見つけてしまうとややこしくなるので、時間をかけてドキュメントを読めてよかった。