このプラグインは、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"],
},
],
},
};booleanfalse は 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 のように動作します。
stringwebpack.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",
],
},
],
},
};functionwebpack.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/));`,
])
);まだお読みでない場合は、貢献ガイドラインに目を通してください。