web-dev-qa-db-ja.com

「ModuleConcatenation救済:モジュールはECMAScriptモジュールではない」救済メッセージでモジュールを修正する方法

Webpack3にはModuleConcatenationプラグインが付属しており、--display-optimization-bailoutフラグとともに使用すると、救済の理由がわかります。

救済メッセージはそれほど簡単ではなく、特定のモジュールで発生した理由を理解するのは困難です。

プロジェクトの非常に単純化されたバージョンでのwebpackコマンドの出力は次のとおりです。

> webpack --bail --display-optimization-bailout

Hash: 4a9a55dc2883e82a017e
Version: webpack 3.4.1
Child client:
    Hash: 4a9a55dc2883e82a017e
    Time: 594ms
                                   Asset       Size  Chunks                    Chunk Names
        a.d3ade61d21d5cb8dd426.bundle.js  712 bytes       0  [emitted]         a
    a.d3ade61d21d5cb8dd426.bundle.js.map    6.57 kB       0  [emitted]         a
                           manifest.json  102 bytes          [emitted]         
                              index.html     299 kB          [emitted]  [big]  
       [0] multi ./src/client/bootstrap/ErrorTrap.js 28 bytes {0} [built]
           ModuleConcatenation bailout: Module is not an ECMAScript module
       [1] ./src/client/bootstrap/ErrorTrap.js 199 bytes {0} [built]
           ModuleConcatenation bailout: Module is not an ECMAScript module

./src/client/bootstrap/ErrorTrap.jsの内容をできる限り簡素化しましたが、ModuleConcatenation bailout: Module is not an ECMAScript moduleは引き続き取得できます。その内容は次のとおりです。

class ErrorTrap {
}

export default ErrorTrap;

私はこの救済メッセージを理解しましたが、それが起こる理由の1つは、 https://github.com/webpack/webpack/blob/93ac8e9c3699bf704068eaccaceec57b3dd45a14/で見られるように、モジュールにインポートまたはエクスポートがない場合ですlib/dependencies/HarmonyDetectionParserPlugin.js#L12-L14 、しかし、このモジュールがECMAScriptモジュールと見なされない理由はわかりません。

。babelrc

{
  "presets": [
    "es2015"
  ]
}

webpack.config.js表現:

{ target: 'web',
  devtool: 'source-map',
  entry: { a: [ './src/client/bootstrap/ErrorTrap.js' ] },
  output:
   { path: '/project/build/client/assets',
     filename: '[name].[chunkhash].bundle.js',
     chunkFilename: '[name].[chunkhash].chunk.js',
     publicPath: '/assets/' },
  module: { rules: [ [Object], [Object], [Object], [Object], [Object] ] },
  resolve: { alias: { 'lodash.defaults': 'lodash' } },
  plugins:
   [ ModuleConcatenationPlugin { options: {} },
     CommonsChunkPlugin {
       chunkNames: [Object],
       filenameTemplate: undefined,
       minChunks: Infinity,
       selectedChunks: undefined,
       children: undefined,
       async: undefined,
       minSize: undefined,
       ident: '/project/node_modules/webpack/lib/optimize/CommonsChunkPlugin.js0' },
     ManifestPlugin { opts: [Object] },
     ChunkManifestPlugin {
       manifestFilename: 'chunk-manifest.json',
       manifestVariable: 'webpackManifest',
       inlineManifest: false },
     OccurrenceOrderPlugin { preferEntry: undefined },
     DefinePlugin { definitions: [Object] },
     VisualizerPlugin { opts: [Object] },
     ExtractTextPlugin { filename: '[name].[contenthash].css', id: 1, options: {} },
     UglifyJsPlugin { options: [Object] },
     LoaderOptionsPlugin { options: [Object] } ],
  name: 'client' }
15
fabiomcosta

Babelを使用してJavaScriptファイルを変換し、デフォルトでes2015プリセットはESモジュール(import/export)をCommonJS(what Node使用、require)に変換します。WebpackはCommonJSモジュールを受け取りますただし、ModuleConcatenationPluginはESモジュールに依存します。 modulesオプション を使用して、モジュールを変換しないようにBabelを設定できます。

{
  "presets": [
    ["es2015", { "modules": false }]
  ]
}

Webpack 2+はそのままESモジュールをサポートしますが、 Tree Shaking などの機能を有効にするため、Webpackに残すのが最善です。

20
Michael Jungo

現代の@babel/preset-env

{
  "presets": [
    ["@babel/preset-env",{
      "targets": {
        ...
      },
      "modules": false
    }],
    "@babel/preset-react"
  ],
  "plugins": [...
}

しかし、悪いこと(しかし重要ではない)は、その後、以前のようにwebpack構成ファイルでESモジュールを使用できないため、webpack.config.babel.js

import webpack from 'webpack';

次のように変更する必要があります。

const webpack = require('webpack');
4
basil