技術探し

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

webpackのinline syntax

誰得かわからないですが、これの質問が来たのでここで説明しようと思います。
webpackは、ローダーチェインと呼ばれる仕組みで動いています。
これには、inlineの書き方が存在しますが開発者ですら使うのは非推奨です。
しかし、webpackのログにはこの表記が多々出てくるため疑問がある人は多いと思います。

設定は以下のファイル群です。

// webpack.config.js
module.exports = {
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          'style-loader',
          'css-loader',
        ],
      },
      {
        test: /\.css$/i,
        use: [require.resolve('./loader')],
        enforce: 'post',
      }
    ],
  },
};
// loader.js
module.exports = function postLoader(res) {
  console.log(this.resource);

  return res;
}

この場合は、拡張子.cssがきた場合にcss-loader -> style-loader -> ./loaderというローダーチェインが発生します。

基本

webpackのローダーの読み方は右からとなり、optionsのつなぎはqueryです。
また、inlineはwebpack.config.jsに書かれたものよりも優先度が高く上書き可能です。
以下の場合だと、css-modulesとsourceMapが上書きされ有効化されます。
ローダー間は!でセパレートします。

import style from 'style-loader!css-loader?modules&sourceMap!./style.css';

接頭辞

webpackではprefixにつけるものによって内容が変化します。

!

import style from '!style-loader!css-loader?modules&sourceMap!./style.css';

先頭に!をつけることにより、webpack.config.jsに書かれたローダーの設定群を無効にします。

!!

import style from '!!style-loader!css-loader?modules&sourceMap!./style.css';

先頭に!!をつけることにより、!に加えenforceのpre, postを無効にします。
なので、この記事の例だと./loaderの呼び出しも!!にすることにより無効化出来ます。

!!!...

これ以降はまだ予約なし。

-!

import style from '-!style-loader!css-loader?modules&sourceMap!./style.css';

先頭に-!をつけることにより、!に加えenforceのpreを無効化します。(postのみ動く)
この記事の場合、./loaderはpostで設定されるため呼び出しが行われます。

Match Resource

!=!を使うことにより、リソースのmatchを行います。

import style from './style.js!=!style-loader!css-loader?modules&sourceMap!./style.css'

この場合は、cssで処理してたものを強制的にjsと認識させます。
なので、実際にはstyle.jsというファイル名は存在しません。

これは主にModule Typeを変更するときに使われます。
例えば、jsonファイルをjsに変換してなにか処理を続行する場合等。

上の例で上げたwebpack.config.jsを見てみます。

module.exports = {
  mode: 'development',
  module: {
      ...
      {
        test: /\.css$/i,
        use: [require.resolve('./loader')],
        enforce: 'post',
      }
    ],
  },
};
// loader
module.exports = function postLoader(res) {
  console.log(this.resource);

  return res;
}

Match Resouceは変換先の拡張子をwebpack.config.jsへ渡すため、この場合のローダーの出力は何も出ません。

さて、以下のようにキャッチするのをcssではなくjsに変更します。

module.exports = {
  mode: 'development',
  module: {
      ...
      {
-        test: /\.css$/i,
+        test: /\.js$/i,
        use: [require.resolve('./loader')],
        enforce: 'post',
      }
    ],
  },
};

ローダーの出力は以下のようになります。

/webpack/src/index.js
/webpack/src/style.css <----- !!!!!
/webpack/node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js
/webpack/node_modules/css-loader/dist/runtime/api.js

でてきました。すごい不思議だとは思いますが、testの条件にマッチしていないように見えます。
importのファイル名は.cssなのにtest: /\.js$/iのローダに入っていることとなります。
この場合は、match resouceによって変換されていることが読み取れます。

最後に

覚えなくていいです。