以下のセクションでは、webpack 1 から 2 への主な変更点について説明します。
これらのオプションは、単一のオプション `resolve.modules` に置き換えられました。詳細な使用方法については、解決を参照してください。
resolve: {
- root: path.join(__dirname, "src")
+ modules: [
+ path.join(__dirname, "src"),
+ "node_modules"
+ ]
}
このオプションでは、空の文字列を渡す必要がなくなりました。この動作は `resolve.enforceExtension` に移動しました。詳細な使用方法については、解決を参照してください。
ここではいくつかの API が変更されました。一般的に使用されていないため、詳細には記載されていません。詳細については、解決を参照してください。
古いローダー設定は、ローダーなどを設定できる、より強力なルールシステムに取って代わられました。互換性のために、古い `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` 拡張子を省略することはできなくなりました
module: {
rules: [
{
use: [
- "style",
+ "style-loader",
- "css",
+ "css-loader",
- "less",
+ "less-loader",
]
}
]
}
`resolveLoader.moduleExtensions` 設定オプションを使用して古い動作を選択することもできますが、これはお勧めしません。
+ resolveLoader: {
+ moduleExtensions: ["-loader"]
+ }
この変更の理由については、#2986 を参照してください。
JSON ファイルにローダーが設定されていない場合、webpack は自動的に`json-loader`を使用して JSON ファイルのロードを試みます。
module: {
rules: [
- {
- test: /\.json/,
- loader: "json-loader"
- }
]
}
webpack、node.js、browserify 間の環境の違いを解消するために、これを行うことにしました。
**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: [
+ rules: [
{
test: /\.js$/,
+ enforce: "pre",
loader: "eslint-loader"
}
]
}
`UglifyJsPlugin` の `sourceMap` オプションは、`true` ではなく `false` がデフォルトになりました。つまり、最小化されたコードにソースマップを使用している場合、または uglifyjs 警告の正しい行番号が必要な場合は、`UglifyJsPlugin` に `sourceMap: true` を設定する必要があります。
devtool: "source-map",
plugins: [
new UglifyJsPlugin({
+ sourceMap: true
})
]
`UglifyJsPlugin` の `compress.warnings` オプションは、`true` ではなく `false` がデフォルトになりました。つまり、uglifyjs 警告を表示する場合は、`compress.warnings` を `true` に設定する必要があります。
devtool: "source-map",
plugins: [
new UglifyJsPlugin({
+ compress: {
+ warnings: true
+ }
})
]
`UglifyJsPlugin` は、ローダーを最小化モードに切り替えなくなりました。`minimize: true` 設定は、長期的にはローダーオプションを介して渡す必要があります。関連するオプションについては、ローダーのドキュメントを参照してください。
ローダーの最小化モードは、webpack 3 以降で削除されます。
古いローダーとの互換性を維持するために、プラグインを介してローダーを最小化モードに切り替えることができます
plugins: [
+ new webpack.LoaderOptionsPlugin({
+ minimize: true
+ })
]
`webpack.optimize.DedupePlugin` はもう必要ありません。設定から削除してください。
BannerPlugin
は、2つのパラメータではなく、単一のオプションオブジェクトを受け取るようになりました。
plugins: [
- new webpack.BannerPlugin('Banner', {raw: true, entryOnly: true});
+ new webpack.BannerPlugin({banner: 'Banner', raw: true, entryOnly: true});
]
OccurrenceOrderPlugin
はデフォルトで有効になり、名前が変更されました(webpack 1 では OccurenceOrderPlugin
)。そのため、設定からプラグインを削除してください。
plugins: [
// webpack 1
- new webpack.optimize.OccurenceOrderPlugin()
// webpack 2
- new webpack.optimize.OccurrenceOrderPlugin()
]
ExtractTextPlugin を webpack 2 で使用するには、バージョン 2 が必要です。
npm install --save-dev extract-text-webpack-plugin
このプラグインの設定変更は、主に構文的なものです。
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(expr)
)は、完全なディレクトリのコンテキストではなく、空のコンテキストを作成するようになりました。
このようなコードは、ES2015 モジュールでは動作しないため、リファクタリングする必要があります。これが不可能な場合は、ContextReplacementPlugin
を使用して、コンパイラに正しい解決策を指示することができます。
以下のように、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
はネイティブの 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 ローダーを設定する方法です。従来、options
は query
と呼ばれ、ローダーの名前に追加できる文字列でした。クエリ文字列によく似ていますが、実際には より強力です
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 },
},
],
},
};
一部のローダーはコンテキスト情報が必要で、設定からそれらを読み取ります。これは、長期的にローダーオプションを介して渡す必要があります。関連するオプションについては、ローダーのドキュメントを参照してください。
古いローダーとの互換性を維持するために、この情報はプラグインを介して渡すことができます。
plugins: [
+ new webpack.LoaderOptionsPlugin({
+ options: {
+ context: __dirname
+ }
+ })
]
webpack 1 では、debug
オプションはローダーをデバッグモードに切り替えました。これは、長期的にローダーオプションを介して渡す必要があります。関連するオプションについては、ローダーのドキュメントを参照してください。
ローダーのデバッグモードは、webpack 3 以降で削除されます。
古いローダーとの互換性を維持するために、プラグインを介してローダーをデバッグモードに切り替えることができます。
- debug: true,
plugins: [
+ new webpack.LoaderOptionsPlugin({
+ debug: true
+ })
]
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
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}`);
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 オプションがいくつかあります。
--define process.env.NODE_ENV="production"
DefinePlugin
を参照してください。
--display-depth
は、各モジュールのエントリポイントまでの距離を表示します。
--display-used-exports
は、モジュールで使用されているエクスポートに関する情報を表示します。
--display-max-modules
は、出力に表示されるモジュールの数を設定します(デフォルトは 15)。
-p
も process.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')
}
}
}