style-loader
Вставка 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
Тип:
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; Вклад
Пожалуйста, уделите время на прочтение наших руководств по вкладу, если вы еще этого не сделали.
Лицензия
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/loaders/style-loader