web-dev-qa-db-ja.com

Webpack 3、BabelとTreeの揺れが機能しない

私はモジュールをツリーシェイクし、WebpackでBabelを使用する方法を見つけようとしています。

Webpackのドキュメント( https://webpack.js.org/guides/tree-shaking/ )からサンプルコードを取得して実行すると、使用されていないモジュール/関数/その他のエクスポート未使用の調和エクスポートとしてマークされます。これは予想される結果です。 -p引数(本番環境)を指定してwebpackを実行した後、webpackはUglifyJSを使用して、不要な未使用のコードを削除します(ツリーシェイクするため)。

これで、webpack設定ファイルにbabel-loaderを追加すると、ES2015モジュールが変換されますが、未使用のエクスポートとしてマークされなくなりました。

だから例えば:

math.js

export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}

app.js(私のエントリファイル)

import {square} from './math.js'

これをwebpack[〜#〜] [〜#〜]なしで実行すると、cube関数は未使用としてマークされます本番用にコンパイルした後に削除されます(-p)。

これをwebpack[〜#〜] [〜#〜]で実行すると、cube関数は次のようにマークされません。未使用で、コンパイルされたバンドルに残ります。

何が欠けていますか?

編集する

これは、状況を再現できるデモリポジトリです。

https://github.com/Milanzor/babel-and-treeshaking-question

更新

.babelrcを追加した場合:

{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "entry",
      "debug": true,
      "targets": {
        "browsers": ["last 2 versions"]
      }
    }]
  ]
}

同じ結果が得られますが、modules: falseをpreset-envオプションに追加すると、BabelはモジュールをES5にコンパイルせず、Webpackはモジュールを再び未使用としてマークします。

結論

私のモジュールがBabelでトランスパイルされていることをWebpackに通知する方法を見つける必要があります。または、未使用のコード自体をスキャンするようBabelに通知する方法を見つける必要があります。

12
Milanzor

Webpackの組み込みツリーシェーキングは、ES6モジュールの構文でのみ機能します。 Babelのデフォルト設定を使用している場合、BabelはES6モジュールをCommonJSモジュールにコンパイルし、Webpackで使用できるものは何も残しません。

一般に、Webpackを使用している人はmodules: falseをES6に使用しているプリセットに設定します(おそらくpreset-env?)、こうして

{
  presets: [
    ['env', { modules: false }],
  ],
}

または、 https://github.com/indutny/webpack-common-shake のようなプラグインを使用してCommonJSモジュールのツリーシェーキングを有効にすることを検討できます。

更新

Babel 7を使用している場合(したがって@babel/preset-env)、modulesオプションがWebpackで使用されると自動的にfalseになるため、この明示的な構成は不要になります。

29
loganfsmyth