v1 から v2 または v3 へ

以下のセクションでは、webpack 1 から 2 への主な変更点について説明します。

resolve.root、resolve.fallback、resolve.modulesDirectories

これらのオプションは、単一のオプション `resolve.modules` に置き換えられました。詳細な使用方法については、解決を参照してください。

  resolve: {
-   root: path.join(__dirname, "src")
+   modules: [
+     path.join(__dirname, "src"),
+     "node_modules"
+   ]
  }

resolve.extensions

このオプションでは、空の文字列を渡す必要がなくなりました。この動作は `resolve.enforceExtension` に移動しました。詳細な使用方法については、解決を参照してください。

resolve.*

ここではいくつかの API が変更されました。一般的に使用されていないため、詳細には記載されていません。詳細については、解決を参照してください。

module.loaders は module.rules になりました

古いローダー設定は、ローダーなどを設定できる、より強力なルールシステムに取って代わられました。互換性のために、古い `module.loaders` 構文はまだ有効であり、古い名前が解析されます。新しい命名規則は理解しやすく、設定を `module.rules` を使用するようにアップグレードする良い理由となります。

  module: {
-   loaders: [
+   rules: [
      {
        test: /\.css$/,
-       loaders: [
-         "style-loader",
-         "css-loader?modules=true"
+       use: [
+         {
+           loader: "style-loader"
+         },
+         {
+           loader: "css-loader",
+           options: {
+             modules: true
+           }
+         }
        ]
      },
      {
        test: /\.jsx$/,
        loader: "babel-loader", // Do not use "use" here
        options: {
          // ...
        }
      }
    ]
  }

ローダーのチェーン

webpack 1 と同様に、ローダーをチェーンしてローダーからローダーに結果を渡すことができます。rule.use 設定オプションを使用すると、`use` をローダーの配列に設定できます。webpack 1 では、ローダーは一般的に `!` でチェーンされていました。このスタイルは、レガシーオプション `module.loaders` を使用する場合にのみサポートされます。

  module: {
-   loaders: [{
+   rules: [{
      test: /\.less$/,
-     loader: "style-loader!css-loader!less-loader"
+     use: [
+       "style-loader",
+       "css-loader",
+       "less-loader"
+     ]
    }]
  }

自動 `-loader` モジュール名拡張子が削除されました

ローダーを参照するときに `-loader` 拡張子を省略することはできなくなりました

  module: {
    rules: [
      {
        use: [
-         "style",
+         "style-loader",
-         "css",
+         "css-loader",
-         "less",
+         "less-loader",
        ]
      }
    ]
  }

`resolveLoader.moduleExtensions` 設定オプションを使用して古い動作を選択することもできますが、これはお勧めしません。

+ resolveLoader: {
+   moduleExtensions: ["-loader"]
+ }

この変更の理由については、#2986 を参照してください。

json-loader はもう必要ありません

JSON ファイルにローダーが設定されていない場合、webpack は自動的に`json-loader`を使用して JSON ファイルのロードを試みます。

  module: {
    rules: [
-     {
-       test: /\.json/,
-       loader: "json-loader"
-     }
    ]
  }

webpack、node.js、browserify 間の環境の違いを解消するために、これを行うことにしました

設定内のローダーは context を基準に解決されます

**webpack 1** では、設定されたローダーは一致するファイルを基準に解決されます。ただし、**webpack 2** では、設定されたローダーは `context` オプションを基準に解決されます。

これは、`npm link` を使用したり、`context` の外部のモジュールを参照したりすると、ローダーによって発生するモジュールの重複に関する問題を解決します。

この問題を回避するために行っていたハックを削除できる場合があります

  module: {
    rules: [
      {
        // ...
-       loader: require.resolve("my-loader")
+       loader: "my-loader"
      }
    ]
  },
  resolveLoader: {
-   root: path.resolve(__dirname, "node_modules")
  }

module.preLoaders と module.postLoaders は削除されました:

  module: {
-   preLoaders: [
+   rules: [
      {
        test: /\.js$/,
+       enforce: "pre",
        loader: "eslint-loader"
      }
    ]
  }

UglifyJsPlugin sourceMap

`UglifyJsPlugin` の `sourceMap` オプションは、`true` ではなく `false` がデフォルトになりました。つまり、最小化されたコードにソースマップを使用している場合、または uglifyjs 警告の正しい行番号が必要な場合は、`UglifyJsPlugin` に `sourceMap: true` を設定する必要があります。

  devtool: "source-map",
  plugins: [
    new UglifyJsPlugin({
+     sourceMap: true
    })
  ]

UglifyJsPlugin 警告

`UglifyJsPlugin` の `compress.warnings` オプションは、`true` ではなく `false` がデフォルトになりました。つまり、uglifyjs 警告を表示する場合は、`compress.warnings` を `true` に設定する必要があります。

  devtool: "source-map",
  plugins: [
    new UglifyJsPlugin({
+     compress: {
+       warnings: true
+     }
    })
  ]

UglifyJsPlugin ローダーの最小化

`UglifyJsPlugin` は、ローダーを最小化モードに切り替えなくなりました。`minimize: true` 設定は、長期的にはローダーオプションを介して渡す必要があります。関連するオプションについては、ローダーのドキュメントを参照してください。

ローダーの最小化モードは、webpack 3 以降で削除されます。

古いローダーとの互換性を維持するために、プラグインを介してローダーを最小化モードに切り替えることができます

  plugins: [
+   new webpack.LoaderOptionsPlugin({
+     minimize: true
+   })
  ]

DedupePlugin は削除されました

`webpack.optimize.DedupePlugin` はもう必要ありません。設定から削除してください。

BannerPlugin - 破壊的変更

BannerPlugin は、2つのパラメータではなく、単一のオプションオブジェクトを受け取るようになりました。

  plugins: [
-    new webpack.BannerPlugin('Banner', {raw: true, entryOnly: true});
+    new webpack.BannerPlugin({banner: 'Banner', raw: true, entryOnly: true});
  ]

OccurrenceOrderPlugin はデフォルトで有効になりました

OccurrenceOrderPlugin はデフォルトで有効になり、名前が変更されました(webpack 1 では OccurenceOrderPlugin)。そのため、設定からプラグインを削除してください。

  plugins: [
    // webpack 1
-   new webpack.optimize.OccurenceOrderPlugin()
    // webpack 2
-   new webpack.optimize.OccurrenceOrderPlugin()
  ]

ExtractTextWebpackPlugin - 破壊的変更

ExtractTextPlugin を webpack 2 で使用するには、バージョン 2 が必要です。

npm install --save-dev extract-text-webpack-plugin

このプラグインの設定変更は、主に構文的なものです。

ExtractTextPlugin.extract

module: {
  rules: [
    {
      test: /.css$/,
-      loader: ExtractTextPlugin.extract("style-loader", "css-loader", { publicPath: "/dist" })
+      use: ExtractTextPlugin.extract({
+        fallback: "style-loader",
+        use: "css-loader",
+        publicPath: "/dist"
+      })
    }
  ]
}

new ExtractTextPlugin({options})

plugins: [
-  new ExtractTextPlugin("bundle.css", { allChunks: true, disable: false })
+  new ExtractTextPlugin({
+    filename: "bundle.css",
+    disable: false,
+    allChunks: true
+  })
]

完全動的な require はデフォルトで失敗するようになりました

式のみの依存関係(例:require(expr))は、完全なディレクトリのコンテキストではなく、空のコンテキストを作成するようになりました。

このようなコードは、ES2015 モジュールでは動作しないため、リファクタリングする必要があります。これが不可能な場合は、ContextReplacementPlugin を使用して、コンパイラに正しい解決策を指示することができます。

CLI と設定でカスタム引数を使用する

以下のように、CLI を悪用して設定にカスタム引数を渡していた場合

webpack --custom-stuff

// webpack.config.js
var customStuff = process.argv.indexOf('--custom-stuff') >= 0;
/* ... */
module.exports = config;

これは許可されなくなったことに注意してください。CLI はより厳格になりました。

代わりに、設定に引数を渡すためのインターフェースがあります。代わりにこれを使用する必要があります。将来のツールはこれに依存する可能性があります。

webpack --env.customStuff

module.exports = function (env) {
  var customStuff = env.customStuff;
  /* ... */
  return config;
};

CLI を参照してください。

require.ensure と AMD require は非同期です

これらの関数は、チャンクが既にロードされている場合にコールバックを同期的に呼び出すのではなく、常に非同期になりました。

require.ensure はネイティブの Promise に依存するようになりました。require.ensure を使用している環境にそれらがない場合は、ポリフィルが必要です。

ローダーの設定は options を介して行います

webpack.config.js のカスタムプロパティを使用してローダーを設定することはできなくなりました。options を介して行う必要があります。ts プロパティを使用した以下の設定は、webpack 2 では無効です。

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
      },
    ],
  },
  // does not work with webpack 2
  ts: { transpileOnly: false },
};

options とは何ですか?

良い質問です。厳密に言うと、それは2つの可能性のあるものです。どちらも webpack ローダーを設定する方法です。従来、optionsquery と呼ばれ、ローダーの名前に追加できる文字列でした。クエリ文字列によく似ていますが、実際には より強力です

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader?' + JSON.stringify({ transpileOnly: false }),
      },
    ],
  },
};

しかし、ローダーと一緒に提供される個別に指定されたオブジェクトにすることもできます。

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        options: { transpileOnly: false },
      },
    ],
  },
};

LoaderOptionsPlugin コンテキスト

一部のローダーはコンテキスト情報が必要で、設定からそれらを読み取ります。これは、長期的にローダーオプションを介して渡す必要があります。関連するオプションについては、ローダーのドキュメントを参照してください。

古いローダーとの互換性を維持するために、この情報はプラグインを介して渡すことができます。

  plugins: [
+   new webpack.LoaderOptionsPlugin({
+     options: {
+       context: __dirname
+     }
+   })
  ]

デバッグ

webpack 1 では、debug オプションはローダーをデバッグモードに切り替えました。これは、長期的にローダーオプションを介して渡す必要があります。関連するオプションについては、ローダーのドキュメントを参照してください。

ローダーのデバッグモードは、webpack 3 以降で削除されます。

古いローダーとの互換性を維持するために、プラグインを介してローダーをデバッグモードに切り替えることができます。

- debug: true,
  plugins: [
+   new webpack.LoaderOptionsPlugin({
+     debug: true
+   })
  ]

ES2015 でのコード分割

webpack 1 では、require.ensure() を使用して、アプリケーションのチャンクを遅延ロードできました。

require.ensure([], function (require) {
  var foo = require('./module');
});

ES2015 ローダースペックは、import() を、実行時に ES2015 モジュールを動的にロードする方法として定義しています。Webpack は import() を分割点として扱い、要求されたモジュールを別のチャンクに配置します。import() はモジュール名を引数に取り、Promise を返します。

function onClick() {
  import('./module')
    .then((module) => {
      return module.default;
    })
    .catch((err) => {
      console.log('Chunk loading failed');
    });
}

朗報です。チャンクの読み込みに失敗した場合でも、Promise ベースであるため、処理できるようになりました。

動的式

import() に部分式を渡すことができます。これは、CommonJS の式と同様に処理されます(webpack は、可能なすべてのファイルを含む コンテキスト を作成します)。

import() は、可能なモジュールごとに個別のチャンクを作成します。

function route(path, query) {
  return import(`./routes/${path}/route`).then(
    (route) => new route.Route(query)
  );
}
// This creates a separate chunk for each possible route

ES2015 と AMD および CommonJS の混在

AMD と CommonJS については、3つすべてのモジュールタイプを(同じファイル内でも)自由に混在させることができます。Webpack は、この場合、babel や node-eps と同様に動作します。

// CommonJS consuming ES2015 Module
var book = require('./book');

book.currentPage;
book.readPage();
book.default === 'This is a book';
// ES2015 Module consuming CommonJS
import fs from 'fs'; // module.exports map to default
import { readFileSync } from 'fs'; // named exports are read from returned object+

typeof fs.readFileSync === 'function';
typeof readFileSync === 'function';

Webpack がそれらを使用できるように、Babel にこれらのモジュール記号を解析しないように指示することが重要です。これは、.babelrc または babel-loader オプションで以下を設定することで実行できます。

.babelrc

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

ヒント

変更する必要はありませんが、機会があります。

テンプレート文字列

Webpack は、式でテンプレート文字列をサポートするようになりました。つまり、webpack コンストラクトでそれらを使用し始めることができます。

- require("./templates/" + name);
+ require(`./templates/${name}`);

設定 Promise

Webpack は、設定ファイルから Promise を返すことをサポートするようになりました。これにより、設定ファイルで非同期処理が可能になります。

webpack.config.js

module.exports = function () {
  return fetchLangs().then((lang) => ({
    entry: '...',
    // ...
    plugins: [new DefinePlugin({ LANGUAGE: lang })],
  }));
};

高度なローダーマッチング

Webpack は、ローダーのマッチング対象をより多くサポートするようになりました。

module.exports = {
  //...
  module: {
    rules: [
      {
        resource: /filename/, // matches "/path/filename.js"
        resourceQuery: /^\?querystring$/, // matches "?querystring"
        issuer: /filename/, // matches "/path/something.js" if requested from "/path/filename.js"
      },
    ],
  },
};

その他の CLI オプション

使用できる新しい CLI オプションがいくつかあります。

--define process.env.NODE_ENV="production" DefinePlugin を参照してください。

--display-depth は、各モジュールのエントリポイントまでの距離を表示します。

--display-used-exports は、モジュールで使用されているエクスポートに関する情報を表示します。

--display-max-modules は、出力に表示されるモジュールの数を設定します(デフォルトは 15)。

-pprocess.env.NODE_ENV"production" に定義するようになりました。

ローダーの変更

ローダーの作成者にのみ関連する変更。

キャッシュ可能

ローダーはデフォルトでキャッシュ可能になりました。キャッシュできない場合は、ローダーはオプトアウトする必要があります。

  // Cacheable loader
  module.exports = function(source) {
-   this.cacheable();
    return source;
  }
  // Not cacheable loader
  module.exports = function(source) {
+   this.cacheable(false);
    return source;
  }

複雑なオプション

webpack 1 は、ローダーの JSON.stringify 可能なオプションのみをサポートしています。

webpack 2 は、JS オブジェクトをローダーオプションとしてサポートするようになりました。

webpack 2.2.1 より前(つまり、2.0.0 から 2.2.0 まで)は、複雑なオプションを使用するには、他のローダーから参照できるように options オブジェクトに ident を使用する必要がありました。**これは 2.2.1 で削除されました**。そのため、現在の移行では ident キーを使用する必要はありません。

{
  test: /\.ext/
  use: {
    loader: '...',
    options: {
-     ident: 'id',
      fn: () => require('./foo.js')
    }
  }
}

14 貢献者

sokrajhnnsgrgurdomfarolinojohnnyreillyjouni-kantolafrederikprijckchrisVillanuevabebrawhowdy39selbekkndelangenEugeneHlushkobyzyk