Spec-Zone.ru › webpack 5

style-loader

Предупреждение: style-loader — это пакет сторонних разработчиков, поддерживаемый участниками сообщества. Возможно, он не имеет такой же поддержки, политики безопасности или лицензии, как webpack, и не поддерживается webpack.

Вставка 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"],
      },
    ],
  },
};

Предупреждение о безопасности

Этот загрузчик в первую очередь предназначен для разработки. По умолчанию настройки не безопасны для среды производства. Подробности см. в рекомендуемой конфигурации и разделе о nonces.

Параметры

  • injectType
  • attributes
  • insert
  • styleTagTransform
  • base
  • esModule

injectType

Тип:

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

Значение по умолчанию: styleTag

Позволяет настроить способ вставки стилей в DOM.

Возможные значения:

styleTag

Автоматически вставляет стили в DOM с использованием нескольких <style></style>. Это по умолчанию.

component.js

import "./styles.css";

Пример с локальными переменными (CSS Modules):

component-with-css-modules.js

import * as styles from "./styles.css";

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

Все локальные переменные (имена классов) экспортируются как именованные экспорты. Для достижения этого поведения также необходимо настроить параметр modules для css-loader. Дополнительную информацию см. в css-loader documentation.

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" } },
          {
            loader: "css-loader",
            // Uncomment it if you want to use CSS modules
            // options: { modules: true }
          },
        ],
      },
    ],
  },
};

Загрузчик вставляет стили следующим образом:

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

singletonStyleTag

Автоматически вставляет стили в DOM с использованием одного <style></style>.

[!WARNING]

Карты исходного кода не работают.

component.js

import "./styles.css";

component-with-css-modules.js

import * as styles from "./styles.css";

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

Все локальные переменные (имена классов) экспортируются как именованные экспорты. Для достижения этого поведения также необходимо настроить параметр modules для css-loader. Дополнительную информацию см. в css-loader documentation.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: "style-loader",
            options: { injectType: "singletonStyleTag" },
          },
          {
            loader: "css-loader",
            // Uncomment it if you want to use CSS modules
            // options: { modules: true }
          },
        ],
      },
    ],
  },
};

Загрузчик вставляет стили следующим образом:

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

autoStyleTag

Работает так же, как styleTag, но если код выполняется в IE6-9, включается режим singletonStyleTag.

lazyStyleTag

Вставляет стили в DOM с использованием нескольких <style></style> по требованию. Рекомендуется использовать соглашение об именовании .lazy.css для ленивых стилей и .css для базового использования style-loader (аналогично другим типам файлов, например, .lazy.less и .less). При указании значения lazyStyleTag для style-loader стили вставляются лениво, делая их доступными по требованию через style.use() / style.unuse().

⚠️ Поведение не определено, когда unuse вызывается чаще, чем use. Не делайте этого.

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, { "my-class" as myClass } from "./styles.lazy.css";

styles.use();

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

Все локальные переменные (имена классов) экспортируются как именованные экспорты. Для достижения этого поведения также необходимо настроить параметр modules для css-loader. Дополнительную информацию см. в css-loader documentation.

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" } },
          {
            loader: "css-loader",
            // Uncomment it if you want to use CSS modules
            // options: { modules: true }
          },
        ],
      },
    ],
  },
};

Загрузчик вставляет стили следующим образом:

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

lazySingletonStyleTag

Вставляет стили в DOM с использованием одного <style></style> по требованию. Рекомендуется использовать соглашение об именовании .lazy.css для ленивых стилей и .css для базового использования style-loader (аналогично другим типам файлов, например, .lazy.less и .less). При указании значения lazySingletonStyleTag для style-loader стили вставляются лениво, делая их доступными по требованию через style.use() / style.unuse().

⚠️ Карты исходного кода не работают.

⚠️ Поведение не определено, когда unuse вызывается чаще, чем use. Не делайте этого.

component.js

import styles from "./styles.css";

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

component-with-css-modules.js

import styles, { "my-class" as myClass } from "./styles.lazy.css";

styles.use();

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

Все локальные переменные (имена классов) экспортируются как именованные экспорты. Для достижения этого поведения также необходимо настроить параметр modules для css-loader. Дополнительную информацию см. в css-loader documentation.

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" },
          },
          {
            loader: "css-loader",
            // Uncomment it if you want to use CSS modules
            // options: { modules: true }
          },
        ],
      },
    ],
  },
};

Загрузчик генерирует следующее:

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

lazyAutoStyleTag

Работает так же, как lazyStyleTag, но если код выполняется в IE6-9, включается режим lazySingletonStyleTag.

linkTag

Вставляет стили в DOM с использованием нескольких <link rel="stylesheet" href="path/to/file.css"> .

ℹ️ Загрузчик динамически вставит тег <link href="path/to/file.css" rel="stylesheet"> во время выполнения через JavaScript. Используйте MiniCssExtractPlugin, если вы хотите включить статический <link href="path/to/file.css" rel="stylesheet">.

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 "./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;

Значение по умолчанию: head

По умолчанию, style-loader добавляет элементы <style>/<link> в конец целевого элемента стилей, который представляет собой тег <head> страницы, если не указано иначе в insert. Это приведет к тому, что CSS, созданный загрузчиком, будет иметь приоритет над уже имеющимся CSS в целевом элементе. Вы можете использовать другие значения, если стандартное поведение не подходит, но мы не рекомендуем этого делать. Если вы нацеливаетесь на iframe, убедитесь, что у вас есть достаточные права доступа, стили будут вставлены в заголовок документа содержимого.

Selector

Позволяет настроить пользовательский селектор для вставки стилей в DOM.

webpack.config.js

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

Absolute path to function

Позволяет настроить абсолютный путь к пользовательской функции, которая позволяет переопределить стандартное поведение и вставить стили в любое место.

[!WARNING]

Не забывайте, что этот код будет использоваться в браузере, и не все браузеры поддерживают новейшие возможности ECMAScript, такие как let, const, arrow function expression и т. д. Мы рекомендуем использовать babel-loader для поддержки новейших возможностей ECMAScript.

[!WARNING]

Не забывайте, что некоторые методы DOM могут быть недоступны в старых браузерах. Мы рекомендуем использовать только свойства DOM уровня 2, но это зависит от того, какие браузеры вы хотите поддерживать.

webpack.config.js

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

Новый <style>/<link> элемент будет вставлен в конец тега body.

Примеры:

Вставка стилей в начало тега head:

insert-function.js

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;
}

module.exports = insertAtTop;

webpack.config.js

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

Вы можете передать любые параметры в style.use(options), и это значение будет передано функциям insert и styleTagTransform.

insert-function.js

function insertIntoTarget(element, options) {
  var parent = options.target || document.head;

  parent.appendChild(element);
}

module.exports = insertIntoTarget;

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 depends what browsers you want to support
              insert: require.resolve("./insert-function.js"),
            },
          },
          "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;

Значение по умолчанию: undefined

string

Позволяет настроить абсолютный путь к пользовательской функции, которая позволяет переопределить стандартное поведение styleTagTransform.

[!WARNING]

Не забывайте, что этот код будет использоваться в браузере, и не все браузеры поддерживают новейшие возможности ECMAScript, такие как let, const, arrow function expression и т. д. Мы рекомендуем использовать только возможности ECMAScript 5, но это зависит от того, какие браузеры вы хотите поддерживать.

[!WARNING]

Не забывайте, что некоторые методы DOM могут быть недоступны в старых браузерах. Мы рекомендуем использовать только свойства DOM уровня 2, но это зависит от того, какие браузеры вы хотите поддерживать.

webpack.config.js

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

base

type base = number;

Эта настройка в первую очередь используется как обходной путь для столкновений CSS при использовании одного или нескольких DllPlugin. base позволяет предотвратить перезапись CSS приложения (или CSS DllPlugin2) CSS DllPlugin1, указав базовый идентификатор модуля CSS, который больше, чем диапазон, используемый DllPlugin1, например:

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 генерирует модули JavaScript, использующие синтаксис ES модулей. В некоторых случаях использование ES модулей полезно, например, в случае склеивания модулей и удаления неиспользуемого кода.

Вы можете включить синтаксис CommonJS, используя:

webpack.config.js

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

Примеры

Рекомендуемый

Для production сборок рекомендуется извлечь CSS из вашего пакета, чтобы в дальнейшем можно было использовать параллельную загрузку ресурсов CSS/JS. Это можно сделать, используя mini-css-extract-plugin, так как он создает отдельные файлы css. Для development режима (включая webpack-dev-server) вы можете использовать style-loader, так как он вставляет CSS в DOM, используя несколько <style></style> и работает быстрее.

[!WARNING]

Не используйте одновременно 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: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          devMode ? "style-loader" : MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
          "sass-loader",
        ],
      },
    ],
  },
  plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
};

Именованный экспорт для CSS Modules

[!WARNING]

Запрещено использовать зарезервированные слова JavaScript в именах классов css.

[!WARNING]

Параметры esModule и modules.namedExport в css-loader должны быть включены (по умолчанию для css-loader@7 это true).

styles.css

.fooBaz {
  color: red;
}
.bar {
  color: blue;
}
.my-class {
  color: green;
}

index.js

import { fooBaz, bar, "my-class" as myClass } from "./styles.css";

console.log(fooBaz, bar, myClass);

Или:

index.js

import * as styles from "./styles.css";

console.log(styles.fooBaz, styles.bar, styles["my-class"]);

Вы можете включить именованный экспорт модулей 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) Content Security Policy, вставленный код обычно будет заблокирован. Обходным путём является использование nonce. Однако обратите внимание, что использование nonce значительно снижает защиту, обеспечиваемую CSP. Вы можете узнать больше о влиянии на безопасность в спецификации. Лучшим решением является не использование этого загрузчика в производстве.

Есть два способа работы с nonce:

  • использование опции attributes
  • использование переменной __webpack_nonce__

[!WARNING]

опция 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.

insert-function.js

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;
}

module.exports = insertAtTop;

webpack.config.js

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

Вставка стилей перед целевым элементом

Вставляет стили перед элементом #id.

insert-function.js

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;
}

module.exports = insertBeforeAt;

webpack.config.js

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

Пользовательские элементы (Shadow DOM)

Вы можете определить пользовательскую цель для ваших стилей для типа lazyStyleTag.

insert-function.js

function insertIntoTarget(element, options) {
  var parent = options.target || document.head;

  parent.appendChild(element);
}

module.exports = insertIntoTarget;

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: require.resolve("./insert-function.js"),
            },
          },
          "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

© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/loaders/style-loader

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API