babel-loader

免責事項 babel-loaderは、コミュニティメンバーによって維持されているサードパーティパッケージです。Webpackと同じサポート、セキュリティポリシー、またはライセンスがない可能性があり、Webpackによって維持されているわけではありません。

このREADMEは、Babel v7を使用するbabel-loader v8 / v9用です。レガシーBabel v6を使用している場合は、7.xブランチのドキュメントを参照してください。

NPM Status codecov

このパッケージを使用すると、Babelwebpackを使用してJavaScriptファイルをトランスパイルできます。

注記:出力に関する問題は、BabelのIssuesトラッカーに報告してください。

インストール

babel-loaderサポートされているWebpackバージョンサポートされているBabelバージョンサポートされているNode.jsバージョン
8.x4.xまたは5.x7.x>= 8.9
9.x5.x^7.12.0>= 14.15.0
npm install -D babel-loader @babel/core @babel/preset-env webpack

使用方法

webpackドキュメント:ローダー

webpack設定オブジェクト内で、babel-loaderをモジュールのリストに追加する必要があります。次のようになります。

module: {
  rules: [
    {
      test: /\.(?:js|mjs|cjs)$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            ['@babel/preset-env', { targets: "defaults" }]
          ]
        }
      }
    }
  ]
}

オプション

babelオプションを参照してください。

optionsプロパティを使用して、ローダーにオプションを渡すことができます。

module: {
  rules: [
    {
      test: /\.(?:js|mjs|cjs)$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            ['@babel/preset-env', { targets: "defaults" }]
          ],
          plugins: ['@babel/plugin-proposal-class-properties']
        }
      }
    }
  ]
}

このローダーは、次のローダー固有のオプションもサポートしています。

  • cacheDirectory:デフォルトはfalseです。設定すると、指定されたディレクトリがローダーの結果のキャッシュに使用されます。将来のwebpackビルドでは、キャッシュから読み取ろうとすることで、コストの高いBabelの再コンパイルプロセスを毎回実行する必要がなくなります。オプションで値をtrueに設定すると({cacheDirectory: true})、ローダーはnode_modules/.cache/babel-loaderのデフォルトのキャッシュディレクトリを使用するか、ルートディレクトリにnode_modulesフォルダーが見つからない場合は、デフォルトのOS一時ファイルディレクトリにフォールバックします。

  • cacheIdentifier:デフォルトは、@babel/coreのバージョン、babel-loaderのバージョン、存在する場合は.babelrcファイルの内容、および環境変数BABEL_ENVの値(NODE_ENV環境変数にフォールバック)で構成される文字列です。識別子が変更された場合にキャッシュの破棄を強制するには、カスタム値に設定できます。

  • cacheCompression:デフォルトはtrueです。設定すると、各Babel変換出力はGzipで圧縮されます。キャッシュ圧縮をオプトアウトする場合は、falseに設定します。数千個のファイルをトランスパイルする場合、プロジェクトはこの設定から恩恵を受ける可能性があります。

  • customize:デフォルトはnullです。.custom()に渡すようなcustomコールバックをエクスポートするモジュールのパスです。これは新しいファイルを作成する必要があるため、代わりに.customを使用してラッパーローダーを作成することをお勧めします。 babel-loaderを直接使用する必要があるが、それでもカスタマイズしたい場合にのみ、これを使用してください。

  • metadataSubscribers:デフォルトは[]です。コンテキスト関数名の配列を取ります。たとえば、`['myMetadataPlugin']`を渡すと、Webpackプラグインのフック内で`context.myMetadataPlugin`にサブスクライバー関数を割り当て、その関数は`metadata`で呼び出されます。

トラブルシューティング

babel-loaderが遅い!

変換するファイル数をできる限り少なくするようにしてください。おそらく`/\.m?js$/`にマッチしているため、`node_modules`フォルダやその他の不要なソースを変換している可能性があります。

`node_modules`を除外するには、上記で説明されているように、`loaders`設定の`exclude`オプションを参照してください。

`cacheDirectory`オプションを使用することで、babel-loaderの速度を最大2倍向上させることができます。これにより、変換がファイルシステムにキャッシュされます。

私のnode_modules内の一部のファイルがIE 11向けにトランスパイルされていません

通常は`node_modules`をコンパイルしないことをお勧めしますが、IE 11またはレガシーターゲットをサポートしていないライブラリを使用する場合は、コンパイルが必要になる場合があります。

そのためには、`test`と`not`を組み合わせて使用するか、関数を渡すことができます。`exclude`オプションに。また、こちらで提案されているネガティブ・ルックアヘッド正規表現を使用することもできます。

{
    test: /\.(?:js|mjs|cjs)$/,
    exclude: {
      and: [/node_modules/], // Exclude libraries in node_modules ...
      not: [
        // Except for a few of them that needs to be transpiled because they use modern syntax
        /unfetch/,
        /d3-array|d3-scale/,
        /@hapi[\\/]joi-date/,
      ]
    },
    use: {
      loader: 'babel-loader',
      options: {
        presets: [
          ['@babel/preset-env', { targets: "ie 11" }]
        ]
      }
    }
  }

Babelが各ファイルにヘルパーを挿入してコードが肥大化しています!

Babelは、`_extend`などの一般的な関数に対して非常に小さなヘルパーを使用します。デフォルトでは、これが必要とするすべてのファイルに追加されます。

代わりに、Babelランタイムを個別のモジュールとして読み込むことで、重複を避けることができます。

次の設定により、Babelでのファイルごとのランタイムの自動挿入が無効になり、代わりに`@babel/plugin-transform-runtime`が必要になり、すべてのヘルパー参照がそれを使用するようになります。

詳細については、ドキュメントを参照してください。

注記: プロジェクトにこれを含めるには`npm install -D @babel/plugin-transform-runtime`を実行し、`npm install @babel/runtime`で依存関係として`@babel/runtime`自体をインストールする必要があります。

rules: [
  // the 'transform-runtime' plugin tells Babel to
  // require the runtime instead of inlining it.
  {
    test: /\.(?:js|mjs|cjs)$/,
    exclude: /node_modules/,
    use: {
      loader: 'babel-loader',
      options: {
        presets: [
          ['@babel/preset-env', { targets: "defaults" }]
        ],
        plugins: ['@babel/plugin-transform-runtime']
      }
    }
  }
]

注記: transform-runtimeとカスタムポリフィル(例:Promiseライブラリ)

@babel/plugin-transform-runtimeには、カスタムregenerator-runtimecore-jsを含むポリフィルが含まれているため、`webpack.ProvidePlugin`を使用する次の通常のシミング方法は機能しません。

// ...
        new webpack.ProvidePlugin({
            'Promise': 'bluebird'
        }),
// ...

次の方法も機能しません。

require('@babel/runtime/core-js/promise').default = require('bluebird');

var promise = new Promise;

(`runtime`を使用して)出力されるのは

'use strict';

var _Promise = require('@babel/runtime/core-js/promise')['default'];

require('@babel/runtime/core-js/promise')['default'] = require('bluebird');

var promise = new _Promise();

以前の`Promise`ライブラリは、上書きされる前に参照され、使用されています。

1つの方法は、アプリケーションに「ブートストラップ」ステップを設け、アプリケーションの前にデフォルトのグローバル変数を最初に上書きすることです。

// bootstrap.js

require('@babel/runtime/core-js/promise').default = require('bluebird');

// ...

require('./app');

babelのNode.js APIはbabel-coreに移行されました。

このメッセージが表示されるということは、npmパッケージ`babel`がインストールされており、webpack設定でローダーの省略表記を使用していることを意味します(webpack 2.x以降では無効です)。

  {
    test: /\.(?:js|mjs|cjs)$/,
    loader: 'babel',
  }

webpackは、`babel-loader`ではなく`babel`パッケージの読み込みを試みます。

これを修正するには、Babel v6では非推奨となっているため、npmパッケージ`babel`をアンインストールする必要があります。(代わりに`@babel/cli`または`@babel/core`をインストールしてください。)依存関係の1つが`babel`をインストールしていて、自分でアンインストールできない場合は、webpack設定でローダーの完全な名前を使用してください。

  {
    test: /\.(?:js|mjs|cjs)$/,
    loader: 'babel-loader',
  }

トランスパイルしないライブラリを除外する

core-jswebpack/buildinは、Babelでトランスパイルするとエラーが発生します。

babel-loaderから除外する必要があります。

{
  "loader": "babel-loader",
  "options": {
    "exclude": [
      // \\ for Windows, / for macOS and Linux
      /node_modules[\\/]core-js/,
      /node_modules[\\/]webpack[\\/]buildin/,
    ],
    "presets": [
      "@babel/preset-env"
    ]
  }
}

トップレベル関数(IIFE)はWebpack 5でもアロー関数です

その関数は、`babel-loader`の実行後、Webpack自体によって挿入されます。デフォルトでは、Webpackはターゲット環境が一部のES2015機能をサポートすると想定していますが、`output.environment`Webpackオプションを使用してこの動作を上書きできます(ドキュメント)。

トップレベルのアロー関数を回避するには、`output.environment.arrowFunction`を使用します。

// webpack.config.js
module.exports = {
  // ...
  output: {
    // ...
    environment: {
      // ...
      arrowFunction: false, // <-- this line does the trick
    },
  },
};

Webpackターゲットに基づいて設定をカスタマイズする

Webpackは、複数のターゲットのバインドをサポートしています。各ターゲット(`web`と`node`など)で異なるBabel設定が必要になる場合、このローダーはBabelのcaller APIを介して`target`プロパティを提供します。

たとえば、Webpackターゲットに基づいて`@babel/preset-env`に渡される環境ターゲットを変更するには

// babel.config.js

module.exports = api => {
  return {
    plugins: [
      "@babel/plugin-proposal-nullish-coalescing-operator",
      "@babel/plugin-proposal-optional-chaining"
    ],
    presets: [
      [
        "@babel/preset-env",
        {
          useBuiltIns: "entry",
          // caller.target will be the same as the target option from webpack
          targets: api.caller(caller => caller && caller.target === "node")
            ? { node: "current" }
            : { chrome: "58", ie: "11" }
        }
      ]
    ]
  }
}

カスタマイズされたローダー

babel-loaderは、処理する各ファイルのBabelの設定をユーザーがカスタム処理に追加できるローダービルダーユーティリティを提供します。

`.custom`は、ローダーの`babel`インスタンスで呼び出されるコールバックを受け入れます。これにより、ツールはローダー自体とまったく同じ`@babel/core`インスタンスを使用していることを確認できます。

ファイルを呼び出して`.custom`を持たずにカスタマイズしたい場合は、`customize`オプションを、`custom`コールバック関数をエクスポートするファイルを指す文字列で渡すこともできます。

// Export from "./my-custom-loader.js" or whatever you want.
module.exports = require("babel-loader").custom(babel => {
  // Extract the custom options in the custom plugin
  function myPlugin(api, { opt1, opt2 }) {
    return {
      visitor: {},
    };
  }

  return {
    // Passed the loader options.
    customOptions({ opt1, opt2, ...loader }) {
      return {
        // Pull out any custom options that the loader might have.
        custom: { opt1, opt2 },

        // Pass the options back with the two custom options removed.
        loader,
      };
    },

    // Passed Babel's 'PartialConfig' object.
    config(cfg, { customOptions }) {
      if (cfg.hasFilesystemConfig()) {
        // Use the normal config
        return cfg.options;
      }

      return {
        ...cfg.options,
        plugins: [
          ...(cfg.options.plugins || []),

          // Include a custom plugin in the options and passing it the customOptions object.
          [myPlugin, customOptions],
        ],
      };
    },

    result(result) {
      return {
        ...result,
        code: result.code + "\n// Generated by some custom loader",
      };
    },
  };
});
// And in your Webpack config
module.exports = {
  // ..
  module: {
    rules: [{
      // ...
      loader: path.join(__dirname, 'my-custom-loader.js'),
      // ...
    }]
  }
};

customOptions(options: Object): { custom: Object, loader: Object }

ローダーのオプションが与えられた場合、`babel-loader`のオプションからカスタムオプションを分割します。

config(cfg: PartialConfig, options: { source, customOptions }): Object

Babelの`PartialConfig`オブジェクトが与えられた場合、`babel.transform`に渡す必要がある`options`オブジェクトを返します。

result(result: Result): Result

Babelの結果オブジェクトが与えられた場合、ローダーはそれに追加の調整を加えることができます。

ライセンス

MIT