style-loader

免責事項 style-loaderは、コミュニティメンバーによって維持されているサードパーティパッケージであり、webpackと同じサポート、セキュリティポリシー、またはライセンスがない可能性があり、webpackによって維持されていません。

npm node tests coverage discussion size

CSSをDOMに挿入します。

はじめに

始めるには、`style-loader`をインストールする必要があります。

npm install --save-dev style-loader

または

yarn add -D style-loader

または

pnpm add -D style-loader

`style-loader`を`css-loader`と組み合わせることをお勧めします。

次に、ローダーを`webpack`の設定に追加します。例:

style.css

body {
  background: green;
}

component.js

import "./style.css";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

セキュリティ警告

このローダーは主に開発向けです。デフォルトの設定は本番環境では安全ではありません。推奨される設定例nonceに関するセクションを参照してください。

オプション

injectType

タイプ

type injectType =
  | "styleTag"
  | "singletonStyleTag"
  | "autoStyleTag"
  | "lazyStyleTag"
  | "lazySingletonStyleTag"
  | "lazyAutoStyleTag"
  | "linkTag";

デフォルト:styleTag

スタイルがDOMにどのように挿入されるかを設定できます。

可能な値

styleTag

複数の<style></style>を使用して、スタイルをDOMに自動的に挿入します。これは**デフォルト**の動作です。

component.js

import "./styles.css";

ローカル(CSSモジュール)を含む例

component-with-css-modules.js

import styles from "./styles.css";

const divElement = document.createElement("div");
divElement.className = styles["my-class"];

インポートされたオブジェクトに格納されているすべてのローカル(クラス名)。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          // The `injectType`  option can be avoided because it is default behaviour
          { loader: "style-loader", options: { injectType: "styleTag" } },
          "css-loader",
        ],
      },
    ],
  },
};

ローダーは次のようにスタイルを挿入します。

<style>
  .foo {
    color: red;
  }
</style>
<style>
  .bar {
    color: blue;
  }
</style>

singletonStyleTag

1つの<style></style>を使用して、スタイルをDOMに自動的に挿入します。

警告

ソースマップは機能しません。

component.js

import "./styles.css";

component-with-css-modules.js

import styles from "./styles.css";

const divElement = document.createElement("div");
divElement.className = styles["my-class"];

インポートされたオブジェクトに格納されているすべてのローカル(クラス名)。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: { injectType: "singletonStyleTag" },
          },
          "css-loader",
        ],
      },
    ],
  },
};

ローダーは次のようにスタイルを挿入します。

<style>
  .foo {
    color: red;
  }
  .bar {
    color: blue;
  }
</style>

autoStyleTag

styleTagと同じように動作しますが、IE6~9でコードが実行された場合は、singletonStyleTagモードがオンになります。

lazyStyleTag

必要に応じて複数の<style></style>を使用してスタイルをDOMに挿入します。遅延スタイルには.lazy.cssという名前の規約に従い、基本的なstyle-loaderの使用には.cssを使用することをお勧めします(他のファイルタイプと同様、つまり.lazy.less.less)。lazyStyleTag値を設定すると、style-loaderはスタイルを遅延して挿入し、style.use() / style.unuse()を介してオンデマンドで使用できるようにします。

⚠️ unuseuseよりも頻繁に呼び出された場合の動作は定義されていません。そうしないでください。

component.js

import styles from "./styles.lazy.css";

styles.use();
// For removing styles you can use
// styles.unuse();

component-with-css-modules.js

import styles from "./styles.lazy.css";

styles.use();

const divElement = document.createElement("div");
divElement.className = styles.locals["my-class"];

すべてのローカル(クラス名)は、インポートされたオブジェクトのlocalsプロパティに格納されます。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        exclude: /\.lazy\.css$/i,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.lazy\.css$/i,
        use: [
          { loader: "style-loader", options: { injectType: "lazyStyleTag" } },
          "css-loader",
        ],
      },
    ],
  },
};

ローダーは次のようにスタイルを挿入します。

<style>
  .foo {
    color: red;
  }
</style>
<style>
  .bar {
    color: blue;
  }
</style>

lazySingletonStyleTag

必要に応じて1つの<style></style>を使用してスタイルをDOMに挿入します。遅延スタイルには.lazy.cssという名前の規約に従い、基本的なstyle-loaderの使用には.cssを使用することをお勧めします(他のファイルタイプと同様、つまり.lazy.less.less)。lazySingletonStyleTag値を設定すると、style-loaderはスタイルを遅延して挿入し、style.use() / style.unuse()を介してオンデマンドで使用できるようにします。

⚠️ ソースマップは機能しません。

⚠️ unuseuseよりも頻繁に呼び出された場合の動作は定義されていません。そうしないでください。

component.js

import styles from "./styles.css";

styles.use();
// For removing styles you can use
// styles.unuse();

component-with-css-modules.js

import styles from "./styles.lazy.css";

styles.use();

const divElement = document.createElement("div");
divElement.className = styles.locals["my-class"];

すべてのローカル(クラス名)は、インポートされたオブジェクトのlocalsプロパティに格納されます。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        exclude: /\.lazy\.css$/i,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.lazy\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: { injectType: "lazySingletonStyleTag" },
          },
          "css-loader",
        ],
      },
    ],
  },
};

ローダーはこれを生成します

<style>
  .foo {
    color: red;
  }
  .bar {
    color: blue;
  }
</style>

lazyAutoStyleTag

lazyStyleTagと同じように動作しますが、IE6~9でコードが実行された場合は、lazySingletonStyleTagモードがオンになります。

linkTag

複数の<link rel="stylesheet" href="path/to/file.css">を使用して、スタイルをDOMに挿入します。

ℹ️ ローダーは、JavaScriptを介して実行時に<link href="path/to/file.css" rel="stylesheet">タグを動的に挿入します。静的な<link href="path/to/file.css" rel="stylesheet">を含める場合は、MiniCssExtractPluginを使用する必要があります。

import "./styles.css";
import "./other-styles.css";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.link\.css$/i,
        use: [
          { loader: "style-loader", options: { injectType: "linkTag" } },
          { loader: "file-loader" },
        ],
      },
    ],
  },
};

ローダーはこれを生成します

<link rel="stylesheet" href="path/to/style.css" />
<link rel="stylesheet" href="path/to/other-styles.css" />

attributes

タイプ

type attributes = HTMLAttributes;

デフォルト: {}

定義されている場合、style-loaderは指定された属性とその値を<style> / <link>要素に付加します。

component.js

import style from "./file.css";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          { loader: "style-loader", options: { attributes: { id: "id" } } },
          { loader: "css-loader" },
        ],
      },
    ],
  },
};
<style id="id"></style>

insert

タイプ

type insert =
  | string
  | ((htmlElement: HTMLElement, options: Record<string, any>) => void);

デフォルト: head

デフォルトでは、style-loader<style>/<link>要素をスタイルターゲットの末尾に追加します。insertで指定しない限り、ターゲットはページの<head>タグになります。これにより、ローダーによって作成されたCSSは、ターゲットに既に存在するCSSよりも優先されます。標準の動作がニーズに合わない場合は、他の値を使用できますが、お勧めしません。 iframe をターゲットにする場合は、十分なアクセス権限があることを確認してください。スタイルはコンテンツドキュメントのheadに挿入されます。

string

セレクター

スタイルをDOMに挿入するカスタムクエリセレクターを設定できます。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              insert: "body",
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};
関数への絶対パス

デフォルトの動作をオーバーライドし、任意の位置にスタイルを挿入できるカスタム関数の絶対パスを設定できます。

警告

このコードはブラウザで使用されるため、すべてのブラウザが最新のECMA機能(letconstアロー関数式など)をサポートしているわけではないことに注意してください。最新のECMA機能をサポートするには、babel-loader を使用することをお勧めします。

警告

一部のDOMメソッドは古いブラウザでは使用できない可能性があるため、DOMコアレベル2のプロパティのみを使用することをお勧めしますが、サポートするブラウザによって異なります。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              insert: require.resolve("modulePath"),
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

新しい<style>/<link>要素は、bodyタグの最後に挿入されます。

function

デフォルトの動作をオーバーライドし、任意の位置にスタイルを挿入できます。

警告

このコードはブラウザで使用されるため、すべてのブラウザが最新のECMA機能(letconstアロー関数式など)をサポートしているわけではないことに注意してください。ECMA 5の機能のみを使用することをお勧めしますが、サポートするブラウザによって異なります。

警告

一部のDOMメソッドは古いブラウザでは使用できない可能性があるため、DOMコアレベル2のプロパティのみを使用することをお勧めしますが、サポートするブラウザによって異なります。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              insert: function insertAtTop(element) {
                var parent = document.querySelector("head");
                // eslint-disable-next-line no-underscore-dangle
                var lastInsertedElement =
                  window._lastElementInsertedByStyleLoader;

                if (!lastInsertedElement) {
                  parent.insertBefore(element, parent.firstChild);
                } else if (lastInsertedElement.nextSibling) {
                  parent.insertBefore(element, lastInsertedElement.nextSibling);
                } else {
                  parent.appendChild(element);
                }

                // eslint-disable-next-line no-underscore-dangle
                window._lastElementInsertedByStyleLoader = element;
              },
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

headタグの先頭にスタイルを挿入します。

style.use(options)に任意のパラメータを渡すことができ、この値はinsert関数とstyleTagTransform関数に渡されます。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              injectType: "lazyStyleTag",
              // Do not forget that this code will be used in the browser and
              // not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
              // we recommend use only ECMA 5 features,
              // but it is depends what browsers you want to support
              insert: function insertIntoTarget(element, options) {
                var parent = options.target || document.head;

                parent.appendChild(element);
              },
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

指定された要素、またはターゲットが指定されていない場合はheadタグにスタイルを挿入します。これで、Shadow DOM(または他の任意の要素)にスタイルを挿入できます。

custom-square.css

div {
  width: 50px;
  height: 50px;
  background-color: red;
}

custom-square.js

import customSquareStyles from "./custom-square.css";

class CustomSquare extends HTMLElement {
  constructor() {
    super();

    this.attachShadow({ mode: "open" });

    const divElement = document.createElement("div");

    divElement.textContent = "Text content.";

    this.shadowRoot.appendChild(divElement);

    customSquareStyles.use({ target: this.shadowRoot });

    // You can override injected styles
    const bgPurple = new CSSStyleSheet();
    const width = this.getAttribute("w");
    const height = this.getAttribute("h");

    bgPurple.replace(`div { width: ${width}px; height: ${height}px; }`);

    this.shadowRoot.adoptedStyleSheets = [bgPurple];

    // `divElement` will have `100px` width, `100px` height and `red` background color
  }
}

customElements.define("custom-square", CustomSquare);

export default CustomSquare;

styleTagTransform

タイプ

type styleTagTransform =
  | string
  | ((
      css: string,
      styleElement: HTMLStyleElement,
      options: Record<string, any>
    ) => void);

デフォルト: undefined

string

デフォルトの動作styleTagTransformをオーバーライドできるカスタム関数の絶対パスを設定できます。

警告

このコードはブラウザで使用されるため、すべてのブラウザが最新のECMA機能(letconstアロー関数式など)をサポートしているわけではないことに注意してください。ECMA 5の機能のみを使用することをお勧めしますが、サポートするブラウザによって異なります。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              injectType: "styleTag",
              styleTagTransform: require.resolve("module-path"),
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

function

'style'タグをDOMに挿入するときに、タグとCSSを変換します。

警告

このコードはブラウザで使用されるため、すべてのブラウザが最新のECMA機能(letconstアロー関数式など)をサポートしているわけではないことに注意してください。ECMA 5の機能のみを使用することをお勧めしますが、サポートするブラウザによって異なります。

警告

一部のDOMメソッドは古いブラウザでは使用できない可能性があるため、DOMコアレベル2のプロパティのみを使用することをお勧めしますが、サポートするブラウザによって異なります。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              injectType: "styleTag",
              styleTagTransform: function (css, style) {
                // Do something ...
                style.innerHTML = `${css}.modify{}\n`;

                document.head.appendChild(style);
              },
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

base

type base = number;

この設定は主に、1つ以上のDllPluginを使用する場合のCSSの衝突の回避策として使用されます。baseを使用すると、DllPlugin1で使用されている範囲よりも大きいCSSモジュールIDベースを指定することで、アプリのCSS(またはDllPlugin2のCSS)がDllPlugin1のCSSを上書きすることを防ぐことができます。例:

webpack.dll1.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

webpack.dll2.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          { loader: "style-loader", options: { base: 1000 } },
          "css-loader",
        ],
      },
    ],
  },
};

webpack.app.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          { loader: "style-loader", options: { base: 2000 } },
          "css-loader",
        ],
      },
    ],
  },
};

esModule

タイプ

type esModule = boolean;

デフォルト: true

デフォルトでは、style-loaderはESモジュール構文を使用するJSモジュールを生成します。 モジュール連結ツリーシェイキングの場合など、ESモジュールを使用する方が有利な場合があります。

CommonJSモジュール構文を有効にするには、

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "style-loader",
        options: {
          esModule: false,
        },
      },
    ],
  },
};

推奨

productionビルドの場合、後でCSS/JSリソースを並列ロードできるように、バンドルからCSSを抽出することをお勧めします。これは、個別のCSSファイルを作成するため、mini-css-extract-pluginを使用することで実現できます。developmentモード(webpack-dev-serverを含む)の場合、複数の<style></style>を使用してCSSをDOMに挿入し、より高速に動作するため、style-loaderを使用できます。

警告

style-loadermini-css-extract-pluginを同時に使用しないでください。

webpack.config.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";

module.exports = {
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          devMode ? "style-loader" : MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
          "sass-loader",
        ],
      },
    ],
  },
  plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
};

CSSモジュール用の名前付きエクスポート

警告

ローカルの名前はcamelCaseに変換されます。

警告

CSSクラス名にJavaScriptの予約語を使用することはできません。

警告

css-loaderのオプションesModulemodules.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

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: "style-loader",
          },
          {
            loader: "css-loader",
            options: {
              modules: {
                namedExport: true,
              },
            },
          },
        ],
      },
    ],
  },
};

ソースマップ

ローダーは、前のローダーがソースマップを出力する場合、自動的にソースマップを挿入します。したがって、ソースマップを生成するには、前のローダーのsourceMapオプションをtrueに設定します。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          { loader: "css-loader", options: { sourceMap: true } },
        ],
      },
    ],
  },
};

Nonce

コンテンツセキュリティポリシー(CSP)を使用している場合、挿入されたコードは通常ブロックされます。回避策としてnonceを使用できます。ただし、nonceを使用すると、CSPによって提供される保護が大幅に低下することに注意してください。仕様でセキュリティへの影響について詳しく読むことができます。より良い解決策は、本番環境でこのローダーを使用しないことです。

nonceを操作するには2つの方法があります。

  • attributesオプションを使用する
  • __webpack_nonce__変数を使用する

警告

attributesオプションは__webpack_nonce__変数よりも優先されます。

attributes

component.js

import "./style.css";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              attributes: {
                nonce: "12345678",
              },
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

ローダーは生成します。

<style nonce="12345678">
  .foo {
    color: red;
  }
</style>

__webpack_nonce__

create-nonce.js

__webpack_nonce__ = "12345678";

component.js

import "./create-nonce.js";
import "./style.css";

requireの代替例

component.js

__webpack_nonce__ = "12345678";

require("./style.css");

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

ローダーは生成します。

<style nonce="12345678">
  .foo {
    color: red;
  }
</style>

先頭にスタイルを挿入する

headタグの先頭にスタイルを挿入します。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              insert: function insertAtTop(element) {
                var parent = document.querySelector("head");
                var lastInsertedElement =
                  window._lastElementInsertedByStyleLoader;

                if (!lastInsertedElement) {
                  parent.insertBefore(element, parent.firstChild);
                } else if (lastInsertedElement.nextSibling) {
                  parent.insertBefore(element, lastInsertedElement.nextSibling);
                } else {
                  parent.appendChild(element);
                }

                window._lastElementInsertedByStyleLoader = element;
              },
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

ターゲット要素の前にスタイルを挿入する

#id要素の前にスタイルを挿入します。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              insert: function insertBeforeAt(element) {
                const parent = document.querySelector("head");
                const target = document.querySelector("#id");

                const lastInsertedElement =
                  window._lastElementInsertedByStyleLoader;

                if (!lastInsertedElement) {
                  parent.insertBefore(element, target);
                } else if (lastInsertedElement.nextSibling) {
                  parent.insertBefore(element, lastInsertedElement.nextSibling);
                } else {
                  parent.appendChild(element);
                }

                window._lastElementInsertedByStyleLoader = element;
              },
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

カスタム要素(Shadow DOM)

lazyStyleTagタイプに対して、スタイルのカスタムターゲットを定義できます。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: {
              injectType: "lazyStyleTag",
              // Do not forget that this code will be used in the browser and
              // not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
              // we recommend use only ECMA 5 features,
              // but it is depends what browsers you want to support
              insert: function insertIntoTarget(element, options) {
                var parent = options.target || document.head;

                parent.appendChild(element);
              },
            },
          },
          "css-loader",
        ],
      },
    ],
  },
};

指定された要素、またはターゲットが指定されていない場合はheadタグにスタイルを挿入します。

custom-square.css

div {
  width: 50px;
  height: 50px;
  background-color: red;
}

custom-square.js

import customSquareStyles from "./custom-square.css";

class CustomSquare extends HTMLElement {
  constructor() {
    super();

    this.attachShadow({ mode: "open" });

    const divElement = document.createElement("div");

    divElement.textContent = "Text content.";

    this.shadowRoot.appendChild(divElement);

    customSquareStyles.use({ target: this.shadowRoot });

    // You can override injected styles
    const bgPurple = new CSSStyleSheet();
    const width = this.getAttribute("w");
    const height = this.getAttribute("h");

    bgPurple.replace(`div { width: ${width}px; height: ${height}px; }`);

    this.shadowRoot.adoptedStyleSheets = [bgPurple];

    // `divElement` will have `100px` width, `100px` height and `red` background color
  }
}

customElements.define("custom-square", CustomSquare);

export default CustomSquare;

コントリビューション

まだお読みでない場合は、コントリビューションガイドラインをお読みください。

CONTRIBUTING

ライセンス

MIT