技術探し

JavaScriptを中心に記事を書いていきます :;(∩´﹏`∩);:

webpack4への簡単なマイグレーションガイド

まだ、公式の方で作成中の段階ですので、一旦ここにまとめます。
この記事では、loader/plugin開発側の話はしません。

medium.com

medium.com

github.com

ラッキング

github.com

ローダー/プラグイン作者向け

medium.com

これもまとめたほうがいいかもしれない。。。

変更一覧

abouthiroppy.hatenablog.jp

詳しくは上の記事をみてください。


簡単なマイグレーションガイド

  • Nodeを6, 8, 9にする
  • webpack-cliを入れる
  • ローダー/プラグインを更新する
  • modeをdevelopment, production, noneに設定する
  • NoEmitOnErrorsPluginの削除
  • ModuleConcatenationPlugin の削除
  • NamedModulesPlugin の削除
  • ModuleConcatenationPluginの削除
  • NoErrorsPluginの削除
  • NewWatchingPluginの削除
  • CommonsChunkPluginの削除
    • optimization.runtimeChunkの追加
    • optimization.splitChunksの追加
      • optimization.splitChunks.chunks: "all"
  • uglifyjs-webpack-pluginの削除
    • optimization.minimizerへ移す必要がある
  • system.import()の変更
  • import(CJS)の時は、defaultのみのアクセスにする

#0CJS(Zero-Config JS)

webpack4は設定ファイルなしでも動くようになりました。
entryが./srcとなり、outputが./distです。

環境

Node4のサポートが切れました

LTSの6, 8または、9(current)を使ってください。
Node10のリリースは4月25日予定です。

webpack-cliへの分離

多くの人はwebpackをnpm scriptで使っていると思います。
その場合、webpack-cliが別途必要となります。

github.com

ローダー/プラグインのアップデートが必要

webpack4になり、ローダー/プラグインは対応が必要となりました。
もし、webpack4対応されていない場合は、webpack4を使用できない可能性があり、先に確認することをオススメします。

side-effects(old: pure-module)

ライブラリのpackage.json"sideEffects": false,の記述がある場合、バンドルサイズを大幅に減らすことが可能です。

configファイル

mode

developmentproductionnoneをmodeとして、追加する必要があります。(しない場合、警告がでる)

"scripts": {
  "dev": "webpack --mode development ./index.js --output ./dist/main.js",
  "build": "webpack --mode production ./index.js --output ./dist/main.js"
}
module.exports = {
  mode: 'development',
  ...
}

loadersからrulesへ

module.loadersがなくなり、V2から入ったmodule.rulesを使用してください。

プラグイン

変更

  • NoEmitOnErrorsPlugin -> ptimization.noEmitOnErrors
    • [デフォルト] productionでon
  • ModuleConcatenationPlugin -> optimization.concatenateModules
    • [デフォルト] productionでon
  • NamedModulesPlugin -> optimization.namedModules
    • [デフォルト] developmentでon
  • ModuleConcatenationPlugin -> optimization.concatenateModules
    • [デフォルト] productionでon
  • NoErrorsPluginの削除
    • [デフォルト] productionでon
  • NewWatchingPluginの削除
  • CommonsChunkPluginの削除
  • uglifyjs-webpack-pluginの削除
    • optimization.minimizerの追加
  • optimization.minimizeの追加
    • minimizingのスイッチ
    • [デフォルト] developmentでoff, productionでon

uglifyJS

webpack.optimize.uglifyjsはなくなりました。
なので、config.optimization.minimizerへ追加する必要があります。

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

{
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        uglifyOptions: {
          compress: {
            warnings: false,
            pure_funcs: ['console.debug', 'console.log', 'console.info', 'console.warn']
          }
        }
      })
    ]
  }
}

extract-text-webpack-plugin

[contenthash].css とファイル名を指定しているとエラーで落ちます。
Error: Path variable [contenthash] not implemented in this context: [contenthash].css
もし、extract-text-webpack-pluginを使いたい場合は、[md5:contenthash:hex:10].css等に変更する必要があります。
webpack4以降は、mini-css-extract-pluginへ移行することをおすすめします。

github.com

その他

  • DefinePluginからmodeにより、process.env.NODE_ENVの指定が必要なくなった

コード

System.import()

SystemJSのimportを使っている場合、警告がでます。
無効にする: Rule.parser.system: true
切る: Rule.parser.system: false

webpackInclude/webpackExcludeのサポート

Dynamic Importをしている時に、ファイルのフィルタリングを可能とします。

モジュールタイプ

以下の5つが追加されました。

  • javascript/auto(default)
    • webpack3と同じモードで仕様に沿ってない
    • CJS、AMD、ESMが有効
  • javascript/esm
    • ESM以外使用出来ず、仕様に沿っている
    • ESMでないものはデフォルトのインポートでのみでき、named importはエラーを出します
  • javascript/dynamic
    • CJSとESMが使えない
  • json
    • jsonを読み込む(CJSとESMで可能)
  • webassembly/experimental
    • wasm用モジュール

拡張子の探索順は、.wasm, .mjs, .js, .jsonです。

CJSとESMについて
前提知識

github.com

Nodeでは、ES Modulesを認識させるには、.mjsという拡張子が必要です。
また、.jsはCommonJS Modulesとなります。
なので、export/importを使いたい場合は.mjsという拡張子にする必要があります。

javascript/esm

webpack4のjavascript/esmでは以下が通らなくなります。
ESMの仕様に沿います。

// webpack.config.js

module.exports = {
  target: 'node',
  module: {
    rules: [
      {
        test: /\.js/,
        type: 'javascript/esm'
      }
    ]
  }
}
import { readFile } from 'fs';

console.log(readFile);
// 6:12-20 Can't import the named export 'readFile' from 
//  non EcmaScript module (only default export is available)

CJSで書かれたファイルはESMで読み込まれる時にはデフォルトしか許容されません。
javascript/autoの場合は上記が通り、[Function]が出力されます。

以下のように修正する必要があります。

import fs from 'fs';

console.log(fs.readFile);

CJSとESMが混ざっている場合、コードが破壊される可能性が高いため注意が必要です。
今のところ、デフォルトはjavascript/autoです。

さいごに

なにか気になることがあれば、Twitterの方でお気軽にどうぞ;)