抹桥的博客
Language
Home
Archive
About
GitHub
Language
主题色
250
3411 文字
17 分
【翻訳】Webpack 1 から 2 へのアップグレードガイド
2017-01-20

resolve.rootresolve.fallbackresolve.modulesDirectories#

これらの設定項目はすべて、単一の設定 resolve.modules に置き換えられました。詳細については、resolving を参照してください。

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

resolve.extensions#

このオプションは、空の文字列を渡す必要がなくなりました。その動作は resolve.enforceExtension に移動されました。詳細については、resolving を参照してください。

resolve.*#

ここには多くの変更点がありますが、あまり使われていないため、すべてを列挙することはしません。詳細については、resolving を参照してください。

module.loaders は現在 module.rules です#

古いローダー設定は、ローダーやその他の内容を設定できる、より強力なルールシステムに置き換えられました。互換性を確保するため、古い module.loaders 構文は引き続き有効で利用可能です。新しい命名規則はより理解しやすいため、module.rules を使用して設定をアップグレードする良い理由となります。

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

ローダーを連結する(Chaining loaders)#

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"]
+ }

json-loader は不要になりました#

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

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

webpack がこのように選択した目的は、webpack、Node.js、および Browserify の異なる環境間の違いをなくすことです。

設定内のローダーはコンテキストに対して相対的に解決されます(Loaders in configuration resolve relative to 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.preLoadersmodule.postLoaders は削除されました

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

UglifyJsPlugin sourceMap#

UglifyJsPluginsourceMap のデフォルトオプションは true から false に変更されました。これは、圧縮されたコードで sourceMap 機能を使用する必要がある場合、手動で sourceMap: false を設定する必要があることを意味します。

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

UglifyJsPlugin 警告#

UglifyJsPlugincompress.warnings は、前述の項目と同様に、デフォルトオプションが true から false に変更されました。uglifyjs の警告を表示する必要がある場合は、compress.warningstrue に設定する必要があります。

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

UglifyJsPlugin ローダーの最小化(minimize loaders)#

UglifyJsPlugin は、圧縮モードでローダーを切り替えることはなくなりました。minimize: true は、ローダーに渡す設定で常に設定する必要があります。詳細についてはドキュメントを参照してください。

webpack 3 またはそれ以降のバージョンでは、ローダーの圧縮モードというこの機能は削除されます。

BannerPlugin - 破壊的変更#

BannerPlugin は、2つの引数を渡すことをサポートしなくなり、代わりにオブジェクトを渡すようになりました。

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

OccurrenceOrderPlugin はデフォルト設定になりました#

手動で設定する必要はなくなりました。

  plugins: [
-   new webpack.optimize.OccurrenceOrderPlugin()
  ]

ExtractTextWebpackPlugin - 破壊的変更#

ExtractTextWebpackPlugin 1.0.0 は webpack 2 で正常に動作しません。ExtractTextPlugin V2 をインストールする必要があります。

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

設定の違いは主に構文にあります。

ExtractTextPlugin.extract

module: {
  rules: [
    test: /.css$/,
-    loader: ExtractTextPlugin.extract("style-loader", "css-loader", { publicPath: "/dist" })
+    loader: ExtractTextPlugin.extract({
+      fallbackLoader: "style-loader",
+      loader: "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 はデフォルトで失敗するようになりました(Full dynamic requires now fail by default)#

式によって決定される依存関係は、以前に作成された完全なフォルダーを含むコンテキストの代わりに、空のコンテキストを作成します。

ES2015 モジュールでは機能しないため、ここのコードをリファクタリングすることをお勧めします。それが難しい場合は、ContextReplacementPlugin を使用して、コンパイラが正しいアドレスを見つけるように指定できます。

CLI と設定ファイルでのカスタム引数の使用#

CLI 引数を悪用して、次のようにカスタム引数を設定に渡している場合:

webapck --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 に依存しています。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つのものの可能性があります。どちらもローダーを設定する方法です。典型的な 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
  +     }
+   })
]
 

debug#

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 ベースであるため、処理できるようになりました。

警告(Caveat):require.ensure は3番目の引数でコードブロック名を簡単に指定できますが、import API はまだこの機能をサポートしていません。この機能に依存している場合は、引き続き require.ensure を使用できます。

require.ensure(
  [],
  function (require) {
    var foo = require("./module");
  },
  "custom-chunk-name",
);

import を Babel と組み合わせて使用したい場合、構文解析エラーを回避するために、まだ Stage 3 の構文プラグインである dynamic-import をインストールする必要があります。この提案が標準に追加されれば、この作業は不要になります。

動的式(Dynamic expressions)#

import() に式を渡す必要がある可能性は十分にあります。ここでの処理パターンは CommonJS と非常によく似ています。

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 の場合、それらは完全に自由に混在させることができます。この場合、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
// module.exports map to default
import fs, { readFileSync } from "fs";

// named exports are read from returned object+

typeof fs.readFileSync === "function";
typeof readFileSync === "function";

重要な点として、webpack がこれらのモジュールシンボルを使用できるように、Babel にそれらを解析しないように指示する必要があります。.babelrc で次のように設定するだけで十分です。

babelrc

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

ヒント#

何も変更する必要はありませんが、非常に便利です。

文字列テンプレート#

webpack は現在、式での文字列テンプレートの使用をサポートしています。これは、webpack の構成要素でそれらを使用できることを意味します。

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

Configuration Promise#

webpack は現在、設定ファイルから Promise を返すことをサポートしています。これは、設定ファイルで非同期処理を実行できることを意味します。

webpack.config.js

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

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

webpack は現在、ローダーがファイルを照合するためのより多くの方法をサポートしています。

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

その他のコマンドラインオプション#

いくつかの新しいコマンドラインオプションが追加されました。 --define process.env.NODE_ENV="production"DefinePlugin を参照。

--display-depth 各モジュールとエントリポイントからの距離を表示

--display-used-exports モジュールがどのモジュールの公開情報を使用したかを表示

--display-max-modules 出力に表示される最大モジュール数を設定

-p も同様に process.env.NODE_ENV を “production” に設定

ローダーの変更#

ローダーの作者のみに関係します。

キャッシュ可能(Cacheable)#

ローダーは現在、デフォルトでキャッシュ可能です。ローダーは、キャッシュできない場合に return を選択する必要があります。

  // 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 オブジェクトを引数として受け取ることをサポートしています。

複雑なオプションを使用すると、1つの制限が生じます。設定オブジェクトに ident を与える必要があり、それによって他のローダーから参照できるようになります。

オプションオブジェクトに ident を持つことは、他のインラインローダーから参照できることを意味します。

require('some-loader??by-iden!resource')
{
  test: /.../,
  loader: "...",
  options: {
    ident: "by-ident",
    magic: () => return Math.random()
  }
}

このインライン記述は頻繁に使用すべきではありませんが、ローダーによって生成されたコードで使用できます。例:style-loader はモジュールを生成し、残りのリクエスト(CSS を公開するためなど)を require します。

// style-loader generated code (simplified)
var addStyle = require("./add-style");
var css = require("-!css-loader?{"modules":true}!postcss-loader??postcss-ident");

addStyle(css);

したがって、複雑なオプションを使用する場合は、ユーザーに ident について伝えてください。

この記事は 2017年1月20日 に公開され、2017年1月20日 に最終更新されました。3181 日が経過しており、内容が古くなっている可能性があります。

【翻訳】Webpack 1 から 2 へのアップグレードガイド
https://blog.kisnows.com/ja-JP/2017/01/20/webpack2-migrating-v1-v2/
作者
Kisnows
公開日
2017-01-20
ライセンス
CC BY-NC-ND 4.0