このプラグインは、CSSを個別のファイルに抽出します。CSSを含むJSファイルごとにCSSファイルを作成します。CSSおよびソースマップのオンデマンドロードをサポートします。
これは、新しいwebpack v5機能に基づいて構築されており、動作するにはwebpack 5が必要です。
extract-text-webpack-pluginと比較した場合
まず、mini-css-extract-plugin
をインストールする必要があります
npm install --save-dev mini-css-extract-plugin
または
yarn add -D mini-css-extract-plugin
または
pnpm add -D mini-css-extract-plugin
mini-css-extract-plugin
をcss-loader
と組み合わせることをお勧めします
次に、ローダーとプラグインをwebpack
設定に追加します。例:
style.css
body {
background: green;
}
component.js
import "./style.css";
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
警告
webpackのエントリーポイントからCSSをインポートしたり、初期チャンクでスタイルをインポートしたりすると、
mini-css-extract-plugin
はこのCSSをページにロードしないことに注意してください。link
タグを自動生成するにはhtml-webpack-plugin
を使用するか、link
タグを含むindex.html
ファイルを作成してください。
警告
ソースマップは、
source-map
/nosources-source-map
/hidden-nosources-source-map
/hidden-source-map
の値でのみ機能します。なぜなら、CSSはsourceMappingURL
コメント(例://# sourceMappingURL=style.css.map
)によるソースマップのみをサポートするからです。devtool
を別の値に設定する必要がある場合は、css-loader
のsourceMap: true
を使用して、抽出されたCSSのソースマップ生成を有効にできます。
filename
型
type filename =
| string
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
デフォルト: [name].css
このオプションは、各出力CSSファイルの名前を決定します。
output.filename
のように動作します。
chunkFilename
型
type chunkFilename =
| string
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
デフォルト: filenameに基づいて
chunkFilename
をfunction
として指定できるのは webpack@5 のみです。
このオプションは、エントリー以外のチャンクファイルの名前を決定します。
output.chunkFilename
のように動作します。
ignoreOrder
型
type ignoreOrder = boolean;
デフォルト: false
順序の警告を削除します。詳細は下記の 例 を参照してください。
insert
型
type insert = string | ((linkTag: HTMLLinkElement) => void);
デフォルト: document.head.appendChild(linkTag);
初期ではない(非同期)CSSチャンクのために、指定された位置に link
タグを挿入します。
警告
初期ではない(非同期)チャンクのみ。
デフォルトでは、mini-css-extract-plugin
は現在の window
の document.head
にスタイル(<link>
要素)を追加します。
ただし、状況によっては、追加先のターゲットをより細かく制御したり、link
要素の挿入を遅延させたりする必要がある場合があります。たとえば、これが、iframe内で実行されるアプリケーションのスタイルを非同期にロードする場合です。このような場合、insert
は関数またはカスタムセレクターになるように構成できます。
iframe をターゲットにする場合は、親ドキュメントがフレームドキュメントにアクセスして要素を追加するのに十分なアクセス権を持っていることを確認してください。
string
カスタムの クエリセレクター を設定できます。新しい <link>
要素は、見つかった項目の後に挿入されます。
webpack.config.js
new MiniCssExtractPlugin({
insert: "#some-element",
});
新しい <link>
要素は、id some-element
の要素の後に挿入されます。
function
デフォルトの動作をオーバーライドし、任意の場所にスタイルを挿入できます。
⚠ このコードは、アプリケーションと共にブラウザー内で実行されることに注意してください。すべてのブラウザーが、
let
、const
、アロー関数式
などの最新のECMA機能をサポートしているわけではないため、ECMA 5の機能と構文のみを使用することをお勧めします。
⚠
insert
関数は文字列にシリアライズされ、プラグインに渡されます。つまり、webpack設定モジュールのスコープにアクセスすることはできません。
webpack.config.js
new MiniCssExtractPlugin({
insert: function (linkTag) {
var reference = document.querySelector("#some-element");
if (reference) {
reference.parentNode.insertBefore(linkTag, reference);
}
},
});
新しい <link>
要素は、id some-element
の要素の前に挿入されます。
attributes
型
type attributes = Record<string, string>};
デフォルト: {}
警告
初期ではない(非同期)チャンクのみ。
定義されている場合、mini-css-extract-plugin
は、指定された属性とその値を <link>
要素にアタッチします。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
attributes: {
id: "target",
"data-target": "example",
},
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
注
動的にロードされたcssチャンクにのみ適用されます。htmlファイル内のリンク属性を変更する場合は、html-webpack-pluginを使用してください。
linkType
型
type linkType = string | boolean;
デフォルト: text/css
このオプションを使用すると、<link type="text/css" ...>
のようなカスタムリンクタイプで非同期チャンクをロードできます。
string
可能な値: text/css
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
linkType: "text/css",
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
boolean
false
は link の type
属性を無効にします。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
linkType: false,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
runtime
型
type runtime = boolean;
デフォルト: true
ランタイム生成を有効/無効にできます。CSSは引き続き抽出され、カスタムロードメソッドに使用できます。たとえば、assets-webpack-plugin を使用してそれらを取得し、必要に応じてアセットをダウンロードするために独自のランタイムコードを使用できます。
false
にするとスキップします。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
runtime: false,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
experimentalUseImportModule
型
type experimentalUseImportModule = boolean;
デフォルト: undefined
明示的に有効にされていない場合(つまり、true
および false
でこのオプションを明示的に制御できます)、新しいAPIが利用可能な場合(少なくともwebpack 5.52.0
が必要です)はデフォルトで有効になります。ブール値はバージョン 5.33.2
以降で使用できますが、experiments.executeModule
を有効にする必要があります(webpack 5.52.0
からは不要)。
子コンパイラーの代わりに新しいwebpack APIを使用してモジュールを実行します。これにより、パフォーマンスとメモリ使用量が大幅に向上します。
experiments.layers
と組み合わせると、CSS実行のレイヤーを指定するための layer
オプションがローダーオプションに追加されます。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// You don't need this for `>= 5.52.0` due to the fact that this is enabled by default
// Required only for `>= 5.33.2 & <= 5.52.0`
// Not available/unsafe for `<= 5.33.2`
experimentalUseImportModule: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
publicPath
型
type publicPath =
| string
| ((resourcePath: string, rootContext: string) => string);
デフォルト: webpackOptions.output
の publicPath
CSS
内の画像、ファイルなどの外部リソースのカスタムパブリックパスを指定します。output.publicPath
のように動作します。
string
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "/public/path/to/",
},
},
"css-loader",
],
},
],
},
};
function
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
return path.relative(path.dirname(resourcePath), context) + "/";
},
},
},
"css-loader",
],
},
],
},
};
emit
型
type emit = boolean;
デフォルト: true
trueの場合、ファイルを生成します(ファイルシステムにファイルを書き込みます)。falseの場合、プラグインはCSSを抽出しますが、ファイルを生成しません。これは、サーバー側のパッケージでこのオプションを無効にすると便利な場合がよくあります。
esModule
型
type esModule = boolean;
デフォルト: true
デフォルトでは、mini-css-extract-plugin
はESモジュールの構文を使用するJSモジュールを生成します。 モジュール連結 や ツリーシェイキング の場合など、ESモジュールを使用すると便利な場合があります。
以下を使用してCommonJS構文を有効にできます。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
"css-loader",
],
},
],
},
};
production
ビルドでは、CSS/JSリソースの並列ロードを後で使用できるように、バンドルからCSSを抽出することをお勧めします。これは、mini-css-extract-plugin
が個別のcssファイルを作成するため、これを使用して実現できます。development
モード(webpack-dev-server
を含む)では、複数の<style>
を使用してDOMにCSSを挿入する style-loader を使用できます。そしてより高速に動作します。
style-loader
とmini-css-extract-plugin
を一緒に使用しないでください。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";
module.exports = {
module: {
rules: [
{
// If you enable `experiments.css` or `experiments.futureDefaults`, please uncomment line below
// type: "javascript/auto",
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
};
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: "[name].css",
chunkFilename: "[id].css",
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: "../",
},
},
"css-loader",
],
},
],
},
};
⚠ ローカルの名前は
camelCase
に変換されます。
⚠ CSSクラス名でJavaScriptの予約語を使用することは許可されていません。
⚠
css-loader
のesModule
オプションとmodules.namedExport
オプションを有効にする必要があります。
styles.css
.foo-baz {
color: red;
}
.bar {
color: blue;
}
index.js
import { fooBaz, bar } from "./styles.css";
console.log(fooBaz, bar);
以下を使用してESモジュールの名前付きエクスポートを有効にできます。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
localIdentName: "foo__[name]__[local]",
},
},
},
],
},
],
},
};
publicPath
オプションwebpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
// publicPath is the relative path of the resource to the context
// e.g. for ./css/admin/main.css the publicPath will be ../../
// while for ./css/main.css the publicPath will be ../
return path.relative(path.dirname(resourcePath), context) + "/";
},
},
},
"css-loader",
],
},
],
},
};
このプラグインは、ローダーチェーンで style-loader
と一緒に使用しないでください。
development
でHMRを使用し、production
ビルドでスタイルをファイルに抽出する例を次に示します。
(わかりやすくするために、ローダーオプションは省略されています。必要に応じて適応してください。)
webpack-dev-server
を使用している場合は、HotModuleReplacementPlugin
プラグインを使用しないでください。 webpack-dev-server
は hot
オプションを使用してHMRを有効/無効にします。
webpack.config.js
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? "[name].css" : "[name].[contenthash].css",
chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
};
注
HMRはwebpack 5で自動的にサポートされます。構成する必要はありません。以下をスキップしてください。
mini-css-extract-plugin
は、開発中の実際のcssファイルのホットリロードをサポートしています。標準スタイルシートとローカルスコープのCSSまたはCSSモジュールの両方のHMRを有効にするためのオプションがいくつか用意されています。以下は、CSSモジュールでHMRを使用するためのmini-cssの構成例です。
webpack-dev-server
を使用している場合は、HotModuleReplacementPlugin
プラグインを使用しないでください。 webpack-dev-server
は hot
オプションを使用してHMRを有効/無効にします。
webpack.config.js
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? "[name].css" : "[name].[contenthash].css",
chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {},
},
"css-loader",
],
},
],
},
};
出力を最小化するには、css-minimizer-webpack-pluginのようなプラグインを使用してください。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
optimization: {
minimizer: [
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`,
new CssMinimizerPlugin(),
],
},
};
これにより、CSSの最適化は本番モードでのみ有効になります。開発時にも実行したい場合は、optimization.minimize
オプションをtrueに設定してください。
ランタイムコードは、<link>
または<style>
タグを介して既に追加されたCSSを検出します。これは、サーバーサイドレンダリングのためにサーバー側でCSSを注入する場合に役立ちます。<link>
タグのhref
は、CSSチャンクのロードに使用されるURLと一致する必要があります。data-href
属性は、<link>
と<style>
の両方に使用できます。CSSをインライン化する場合は、data-href
を使用する必要があります。
CSSは、optimization.splitChunks.cacheGroups
を使用して1つのCSSファイルに抽出できます。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
Webpack 5では、test
の代わりにtype
を使用する必要があります。そうしないと、.css
ファイルの他に、余分な.js
ファイルが生成される可能性があります。これは、test
がどのモジュールをドロップすべきかを知らないためです(この場合、.js
をドロップすべきであることを検出できません)。
webpackのエントリー名に基づいてCSSを抽出することもできます。これは、ルートを動的にインポートするものの、エントリーに従ってCSSをバンドルしたい場合に特に役立ちます。これにより、ExtractTextPluginで発生していたCSSの重複問題も回避できます。
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
foo: path.resolve(__dirname, "src/foo"),
bar: path.resolve(__dirname, "src/bar"),
},
optimization: {
splitChunks: {
cacheGroups: {
fooStyles: {
type: "css/mini-extract",
name: "styles_foo",
chunks: (chunk) => {
return chunk.name === "foo";
},
enforce: true,
},
barStyles: {
type: "css/mini-extract",
name: "styles_bar",
chunks: (chunk) => {
return chunk.name === "bar";
},
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
filename
オプションを使用すると、チャンクデータを使用してファイル名をカスタマイズできます。これは、複数のエントリポイントを扱い、特定のエントリポイント/チャンクのファイル名をより詳細に制御したい場合に特に役立ちます。以下の例では、filename
を使用して、生成されたCSSを別のディレクトリに出力します。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: ({ chunk }) => `${chunk.name.replace("/js/", "/css/")}.css`,
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
長期キャッシュには、filename: "[contenthash].css"
を使用してください。オプションで[name]
を追加します。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
CSS Modulesなどのスコープや命名規則の一貫した使用を通じてCSSの順序が緩和されているプロジェクトでは、プラグインのignoreOrderフラグをtrueに設定することで、CSSの順序に関する警告を無効にできます。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/index.js",
module: {
rules: [
{
test: /\.s[ac]ss$/i,
oneOf: [
{
resourceQuery: "?dark",
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: `@use 'dark-theme/vars' as vars;`,
},
},
],
},
{
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: `@use 'light-theme/vars' as vars;`,
},
},
],
},
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
attributes: {
id: "theme",
},
}),
],
};
src/index.js
import "./style.scss";
let theme = "light";
const themes = {};
themes[theme] = document.querySelector("#theme");
async function loadTheme(newTheme) {
// eslint-disable-next-line no-console
console.log(`CHANGE THEME - ${newTheme}`);
const themeElement = document.querySelector("#theme");
if (themeElement) {
themeElement.remove();
}
if (themes[newTheme]) {
// eslint-disable-next-line no-console
console.log(`THEME ALREADY LOADED - ${newTheme}`);
document.head.appendChild(themes[newTheme]);
return;
}
if (newTheme === "dark") {
// eslint-disable-next-line no-console
console.log(`LOADING THEME - ${newTheme}`);
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => {
themes[newTheme] = document.querySelector("#theme");
// eslint-disable-next-line no-console
console.log(`LOADED - ${newTheme}`);
});
}
}
document.onclick = () => {
if (theme === "light") {
theme = "dark";
} else {
theme = "light";
}
loadTheme(theme);
};
src/dark-theme/_vars.scss
$background: black;
src/light-theme/_vars.scss
$background: white;
src/styles.scss
body {
background-color: vars.$background;
}
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Document</title>
<link id="theme" rel="stylesheet" type="text/css" href="./main.css" />
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
抽出されたCSSからメディアクエリを抽出したい場合(モバイルユーザーがデスクトップやタブレット固有のCSSをロードする必要がないようにするため)、以下のプラグインのいずれかを使用する必要があります。
mini-css-extract-pluginは、ニーズに合わせて拡張するためのフックを提供します。
SyncWaterfallHook
linkタグの挿入コードを注入する前に呼び出されます。文字列を返す必要があります
MiniCssExtractPlugin.getCompilationHooks(compilation).beforeTagInsert.tap(
"changeHref",
(source, varNames) =>
Template.asString([
source,
`${varNames.tag}.setAttribute("href", "/plugins/mini-css-extract-plugin/));`,
])
);
まだお読みでない場合は、貢献ガイドラインに目を通してください。