🏝️

Webpack ✖️ TypeScriptで新しいJavaScript構文に対応させる

2023/12/25に公開

JavaScriptでは毎年のように新しい構文が利用可能になり、各種ブラウザの対応も進むことでネイティブで利用できる便利な構文はどんどん増えていきます。それと同時にTypeScriptでも同様に便利な構文が利用できます。

例えば、以下のような構文はどちらもすでにChromeでは実装されているため、ブラウザで実行するのであれば、何の変換も必要なくすでに利用することができます。

Nullish Coalescing
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing

const foo = null ?? 'default string';
console.log(foo);

Optional Chaining
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah',
  },
};

const dogName = adventurer.dog?.name;
console.log(dogName);

※ これらは TypeScript@3.7(もう4年も前ですね・・)でも対応しているため、当然のように利用できると錯覚していました。

しかし、Webpack@4を利用しているのであれば、(そしてbabel-loaderで変換をしているのであれば)少し注意が必要です。

Webpackで babel-loader を用いてい変換を行っている場合、 babelではpreset-envによって、適切なターゲット(ブラウザバージョンなど)に必要なtranspileを行います。
上述した構文は、すでに多くのブラウザで対応しているのですが、

  • babelはブラウザで利用可能だと判断して変換しない
  • Webpack@4はその構文が理解できずにエラーがおこる

という逆転現象が起き、そのままだとWebpackでバンドル処理でエラーになってしまいます。WebpackはJavaScriptをモジュール化してバンドルするためにJavaScriptの構文を理解できる必要があるためです。
ということで、これらの記述をbabel-loaderを用いて利用するには以下のようにpluginを入れる必要があります。

      {
        test: /\.tsx?$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              cwd: __dirname,
              plugins: [
                '@babel/plugin-transform-nullish-coalescing-operator',
                '@babel/plugin-transform-optional-chaining',
              ],
            },
          },
        ],
        include: path.join(__dirname, 'src'),
      },

理想的にはWebpackのバージョンをあげればよいので最新にしたいのですが、4を使う必要がある場合、新しい構文については上記のようなケースを気をつける必要があるんですね。babel/core-jsが対応しているからと、盲点でした。

OPENLOGI Tech Blog

Discussion