css-loader
Блок css-loader интерпретирует @import и url() как import/require() и выполнит их разрешение.
Начало работы
[!WARNING]
Для использования последней версии css-loader необходим webpack@5
Для начала вам нужно установить css-loader:
npm install --save-dev css-loader
или
yarn add -D css-loader
или
pnpm add -D css-loader
Затем добавьте плагин в вашу конфигурацию webpack. Например:
file.js
import * as css from "file.css";
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
}; И запустите webpack выбранным вами способом.
Если по какой-то причине вам нужно извлечь CSS в отдельный файл (то есть не хранить CSS в модуле JS), вы можете ознакомиться с рекомендуемым примером.
Параметры
url
Тип:
type url =
| boolean
| {
filter: (url: string, resourcePath: string) => boolean;
}; По умолчанию: true
Позволяет включить/отключить обработку функций CSS url и image-set. Если установлено значение false, css-loader не будет анализировать пути, указанные в url или image-set. Также можно передать функцию для динамического управления этим поведением, основываясь на пути к ресурсу. Начиная с версии 4.0.0, абсолютные пути анализируются на основе корневого каталога сервера.
Примеры разрешения:
url(image.png) => require('./image.png')
url('image.png') => require('./image.png')
url(./image.png) => require('./image.png')
url('./image.png') => require('./image.png')
url('http://dontwritehorriblecode.com/2112.png') => require('http://dontwritehorriblecode.com/2112.png')
image-set(url('image2x.png') 1x, url('image1x.png') 2x) => require('./image1x.png') and require('./image2x.png') Для импорта ресурсов из node_modules пути (включая resolve.modules) и для alias, добавьте префикс ~:
url(~module/image.png) => require('module/image.png')
url('~module/image.png') => require('module/image.png')
url(~aliasDirectory/image.png) => require('otherDirectory/image.png')
boolean
Включение/выключение разрешения url().
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
url: true,
},
},
],
},
};
object
Позволяет отфильтровать url(). Все отфильтрованные url() не будут разрешаться (останутся в коде в том виде, в котором были написаны).
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
url: {
filter: (url, resourcePath) => {
// resourcePath - path to css file
// Don't handle `img.png` urls
if (url.includes("img.png")) {
return false;
}
// Don't handle images under root-relative /external_images/
if (/^\/external_images\//.test(path)) {
return false;
}
return true;
},
},
},
},
],
},
};
import
Тип:
type importFn =
| boolean
| {
filter: (
url: string,
media: string,
resourcePath: string,
supports?: string,
layer?: string,
) => boolean;
}; По умолчанию: true
Позволяет включить/отключить обработку псевдонимов @import. Управление разрешением @import. Абсолютные URL в @import будут перемещены в код во время выполнения.
Примеры разрешения:
@import 'style.css' => require('./style.css')
@import url(style.css) => require('./style.css')
@import url('style.css') => require('./style.css')
@import './style.css' => require('./style.css')
@import url(./style.css) => require('./style.css')
@import url('./style.css') => require('./style.css')
@import url('http://dontwritehorriblecode.com/style.css') => @import url('http://dontwritehorriblecode.com/style.css') in runtime
Для импорта стилей из node_modules пути (включая resolve.modules) и для alias, добавьте префикс ~:
@import url(~module/style.css) => require('module/style.css')
@import url('~module/style.css') => require('module/style.css')
@import url(~aliasDirectory/style.css) => require('otherDirectory/style.css')
boolean
Включение/выключение разрешения @import.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
import: true,
},
},
],
},
};
object
filter
Тип:
type filter = (url: string, media: string, resourcePath: string) => boolean;
По умолчанию: undefined
Позволяет отфильтровать @import. Все отфильтрованные @import не будут разрешаться (останутся в коде в том виде, в котором были написаны).
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
import: {
filter: (url, media, resourcePath) => {
// resourcePath - path to css file
// Don't handle `style.css` import
if (url.includes("style.css")) {
return false;
}
return true;
},
},
},
},
],
},
};
modules
Тип:
type modules =
| boolean
| "local"
| "global"
| "pure"
| "icss"
| {
auto: boolean | regExp | ((resourcePath: string) => boolean);
mode:
| "local"
| "global"
| "pure"
| "icss"
| ((resourcePath) => "local" | "global" | "pure" | "icss");
localIdentName: string;
localIdentContext: string;
localIdentHashSalt: string;
localIdentHashFunction: string;
localIdentHashDigest: string;
localIdentRegExp: string | regExp;
getLocalIdent: (
context: LoaderContext,
localIdentName: string,
localName: string,
) => string;
namedExport: boolean;
exportGlobals: boolean;
exportLocalsConvention:
| "as-is"
| "camel-case"
| "camel-case-only"
| "dashes"
| "dashes-only"
| ((name: string) => string);
exportOnlyLocals: boolean;
getJSON: ({
resourcePath,
imports,
exports,
replacements,
}: {
resourcePath: string;
imports: object[];
exports: object[];
replacements: object[];
}) => Promise<void> | void;
}; По умолчанию: undefined
Позволяет включить/выключить модули CSS или ICSS и настроить конфигурацию:
-
undefined- включить модули CSS для всех файлов, соответствующих/\.module\.\w+$/i.test(filename)и/\.icss\.\w+$/i.test(filename)регулярным выражениям. -
true- включить модули CSS для всех файлов. -
false- выключить модули CSS для всех файлов. -
string- выключить модули CSS для всех файлов и установить параметрmode, подробнее можно прочитать здесь -
object- включить модули CSS для всех файлов, если параметрmodules.autoне указан, в противном случае параметрmodules.autoопределит, будут ли это модули CSS или нет, подробнее можно прочитать здесь
Параметр modules включает/выключает спецификацию CSS Modules и настраивает базовое поведение.
Использование значения false увеличивает производительность, потому что мы избегаем анализа функций CSS Modules, что будет полезно для разработчиков, использующих обычный CSS или другие технологии.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: true,
},
},
],
},
};
Features
Scope
Использование значения local требует указания классов :global. Использование значения global требует указания классов :local. Использование значения pure требует, чтобы селекторы содержали по крайней мере один локальный класс или идентификатор.
Дополнительную информацию можно найти здесь.
Стиль может быть ограничен локальным пространством, чтобы избежать глобального применения стилей.
Синтаксис :local(.className) используется для объявления className в локальном пространстве. Локальные идентификаторы экспортируются модулем.
Использование :local (без скобок) включает локальный режим для данного селектора. Обозначение :global(.className) используется для объявления явного глобального селектора. Использование :global (без скобок) включает глобальный режим для данного селектора.
Загрузчик заменяет локальные селекторы уникальными идентификаторами. Выбранные уникальные идентификаторы экспортируются модулем.
:local(.className) {
background: red;
}
:local .className {
color: green;
}
:local(.className .subClass) {
color: green;
}
:local .className .subClass :global(.global-class-name) {
color: blue;
} ._23_aKvs-b8bW2Vg3fwHozO {
background: red;
}
._23_aKvs-b8bW2Vg3fwHozO {
color: green;
}
._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 {
color: green;
}
._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 .global-class-name {
color: blue;
} [!NOTE]
Идентификаторы экспортируются
exports.locals = {
className: "_23_aKvs-b8bW2Vg3fwHozO",
subClass: "_13LGdX8RMStbBE9w-t0gZ1",
}; Рекомендуется использовать CamelCase для локальных селекторов. Они проще в использовании внутри импортированного JS модуля.
Можно использовать :local(#someId), но это не рекомендуется. Используйте классы вместо идентификаторов.
Composing
При объявлении локального имени класса, можно составить локальный класс из другого локального имени класса.
:local(.className) {
background: red;
color: yellow;
}
:local(.subClass) {
composes: className;
background: blue;
} Это не приводит к изменениям в самом CSS, но экспортирует несколько имён классов.
exports.locals = {
className: "_23_aKvs-b8bW2Vg3fwHozO",
subClass: "_13LGdX8RMStbBE9w-t0gZ1 _23_aKvs-b8bW2Vg3fwHozO",
}; ._23_aKvs-b8bW2Vg3fwHozO {
background: red;
color: yellow;
}
._13LGdX8RMStbBE9w-t0gZ1 {
background: blue;
}
Importing
Для импорта локального имени класса из другого модуля.
[!NOTE]
Мы настоятельно рекомендуем указывать расширение при импорте файла, так как возможно импортировать файл с любым расширением, и заранее неизвестно, какой файл использовать.
:local(.continueButton) {
composes: button from "library/button.css";
background: red;
} :local(.nameEdit) {
composes: edit highlight from "./edit.css";
background: red;
} Для импорта из нескольких модулей используйте несколько правил composes:.
:local(.className) {
composes:
edit highlight from "./edit.css",
button from "module/button.css",
classFromThisModule;
background: red;
} или
:local(.className) {
composes: edit highlight from "./edit.css";
composes: button from "module/button.css";
composes: classFromThisModule;
background: red;
}
Values
Можно использовать @value для указания значений, которые будут повторно использоваться в документе.
Рекомендуется использовать префикс v- для значений, s- для селекторов и m- для медиа псевдонимов.
@value v-primary: #BF4040;
@value s-black: black-selector;
@value m-large: (min-width: 960px);
.header {
color: v-primary;
padding: 0 10px;
}
.s-black {
color: black;
}
@media m-large {
.header {
padding: 0 20px;
}
}
boolean
Включить возможности CSS Modules.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: true,
},
},
],
},
};
string
Включить возможности CSS Modules и настроить mode.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
// Using `local` value has same effect like using `modules: true`
modules: "global",
},
},
],
},
};
object
Включить возможности CSS Modules и настроить параметры для них.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
mode: "local",
auto: true,
exportGlobals: true,
localIdentName: "[path][name]__[local]--[hash:base64:5]",
localIdentContext: path.resolve(__dirname, "src"),
localIdentHashSalt: "my-custom-hash",
namedExport: true,
exportLocalsConvention: "as-is",
exportOnlyLocals: false,
getJSON: ({ resourcePath, imports, exports, replacements }) => {},
},
},
},
],
},
};
auto
Тип:
type auto =
| boolean
| regExp
| ((
resourcePath: string,
resourceQuery: string,
resourceFragment: string,
) => boolean); По умолчанию: undefined
Позволяет автоматически включить модули CSS/ICSS, основываясь на имени файла, запросе или фрагменте, когда параметр modules является объектом.
Возможные значения:
-
undefined- включить модули CSS для всех файлов. -
true- включить модули CSS для всех файлов, соответствующих/\.module\.\w+$/i.test(filename)и/\.icss\.\w+$/i.test(filename)регулярным выражениям. -
false- выключить модули CSS. -
RegExp- включить модули CSS для всех файлов, соответствующих/RegExp/i.test(filename)регулярному выражению. -
function- включить модули CSS для файлов, удовлетворяющих вашему фильтру по имени файла.
boolean
Возможные значения:
-
true- включает модули CSS или совместимый формат CSS, устанавливает параметрmodules.modeв значениеlocalдля всех файлов, удовлетворяющих условию/\.module(s)?\.\w+$/i.test(filename), или устанавливает параметрmodules.modeв значениеicssдля всех файлов, удовлетворяющих условию/\.icss\.\w+$/i.test(filename) -
false- выключает модули CSS или совместимый формат CSS на основе имени файла
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
auto: true,
},
},
},
],
},
};
RegExp
Включение модулей CSS для файлов на основе проверки имени файла с помощью регулярного выражения.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
auto: /\.custom-module\.\w+$/i,
},
},
},
],
},
};
function
Включение модулей CSS для файлов на основе имени файла, запроса или фрагмента, удовлетворяющего проверке вашей функции фильтра.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
auto: (resourcePath, resourceQuery, resourceFragment) => {
return resourcePath.endsWith(".custom-module.css");
},
},
},
},
],
},
};
mode
Тип:
type mode =
| "local"
| "global"
| "pure"
| "icss"
| ((
resourcePath: string,
resourceQuery: string,
resourceFragment: string,
) => "local" | "global" | "pure" | "icss"); По умолчанию: 'local'
Настройка параметра mode . Можно опустить значение, чтобы использовать режим local.
Управляет уровнем компиляции, применяемой к входным стилям.
local, global, и pure обрабатывают class и id изоляцию и значения @value . icss будет компилировать только низкоуровневый формат Interoperable CSS для объявления зависимостей :import и :export между CSS и другими языками.
ICSS лежит в основе поддержки CSS Modules и предоставляет низкоуровневый синтаксис для других инструментов, чтобы реализовать свои собственные вариации CSS-модулей.
string
Возможные значения - local, global, pure, и icss.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
mode: "global",
},
},
},
],
},
};
function
Позволяет устанавливать разные значения для параметра mode на основе имени файла, запроса или фрагмента.
Возможные возвращаемые значения - local, global, pure и icss.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
// Callback must return "local", "global", or "pure" values
mode: (resourcePath, resourceQuery, resourceFragment) => {
if (/pure.css$/i.test(resourcePath)) {
return "pure";
}
if (/global.css$/i.test(resourcePath)) {
return "global";
}
return "local";
},
},
},
},
],
},
};
localIdentName
Тип:
type localIdentName = string;
По умолчанию: '[hash:base64]'
Позволяет настроить имя сгенерированного локального идентификатора.
Для получения дополнительной информации о параметрах см.:
- webpack шаблоны строк,
- output.hashDigest,
- output.hashDigestLength,
- output.hashFunction,
- output.hashSalt.
Поддерживаемые шаблоны строк:
-
[name]имя базового ресурса -
[folder]папка ресурса относительно параметраcompiler.contextили параметраmodules.localIdentContext. -
[path]путь ресурса относительно параметраcompiler.contextили параметраmodules.localIdentContext. -
[file]- имя файла и путь. -
[ext]- расширение с ведущим.. -
[hash]- хэш строки, сгенерированный на основеlocalIdentHashSalt,localIdentHashFunction,localIdentHashDigest,localIdentHashDigestLength,localIdentContext,resourcePathиexportName -
[<hashFunction>:hash:<hashDigest>:<hashDigestLength>]- хэш со настройками хэширования. -
[local]- исходный класс.
Рекомендации:
- используйте
'[path][name]__[local]'для разработки - используйте
'[hash:base64]'для производства
Заполнитель [local] содержит исходный класс.
Примечание: все защищённые (<>:"/\|?*) и управляющие символы файловой системы (исключая символы в заполнителе [local] ) будут преобразованы в -.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentName: "[path][name]__[local]--[hash:base64:5]",
},
},
},
],
},
};
localIdentContext
Тип:
type localIdentContex = string;
По умолчанию: compiler.context
Позволяет переопределить базовый контекст загрузчика для имени локального идентификатора.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentContext: path.resolve(__dirname, "src"),
},
},
},
],
},
};
localIdentHashSalt
Тип:
type localIdentHashSalt = string;
По умолчанию: undefined
Позволяет добавить пользовательский хэш для генерации более уникальных классов. Дополнительная информация см. в output.hashSalt.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentHashSalt: "hash",
},
},
},
],
},
};
localIdentHashFunction
Тип:
type localIdentHashFunction = string;
По умолчанию: md4
Позволяет указать функцию хэширования для генерации классов. Дополнительная информация см. в output.hashFunction.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentHashFunction: "md4",
},
},
},
],
},
};
localIdentHashDigest
Тип:
type localIdentHashDigest = string;
По умолчанию: hex
Позволяет указать хэш-хеш для генерации классов. Дополнительная информация см. в output.hashDigest.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentHashDigest: "base64",
},
},
},
],
},
};
localIdentHashDigestLength
Тип:
type localIdentHashDigestLength = number;
По умолчанию: 20
Позволяет указать длину хэша для генерации классов. Дополнительная информация см. в output.hashDigestLength.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentHashDigestLength: 5,
},
},
},
],
},
};
hashStrategy
Тип: 'resource-path-and-local-name' | 'minimal-subset' По умолчанию: 'resource-path-and-local-name'
Использовать ли локальное имя при вычислении хэша.
-
'resource-path-and-local-name'При хешировании используются и путь к ресурсу, и локальное имя. Каждый идентификатор в модуле получает свой собственный хэш-дайджест. -
'minimal-subset'Автоматически определяет, можно ли опустить имена идентификаторов из хэширования. Используйте это значение для оптимизации вывода для лучшей сжатия GZIP или Brotli.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
hashStrategy: "minimal-subset",
},
},
},
],
},
};
localIdentRegExp
Тип:
type localIdentRegExp = string | RegExp;
По умолчанию: undefined
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
localIdentRegExp: /page-(.*)\.css/i,
},
},
},
],
},
};
getLocalIdent
Тип:
type getLocalIdent = ( context: LoaderContext, localIdentName: string, localName: string, ) => string;
По умолчанию: undefined
Позволяет указать функцию для генерации имени класса. По умолчанию используется встроенная функция для генерации имени класса. Если пользовательская функция возвращает null или undefined, то используется встроенная функция для генерации имени класса.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
getLocalIdent: (context, localIdentName, localName, options) => {
return "whatever_random_class_name";
},
},
},
},
],
},
};
namedExport
Тип:
type namedExport = boolean;
По умолчанию: Зависит от значения параметра esModule. Если значение параметра esModule равно true, это значение также будет true, в противном случае оно будет false.
Включает/выключает имён экспорт ES модулей для локальных переменных.
[!WARNING]
Поскольку использование класса
defaultв CSS запрещено, когдаnamedExportравноtrue(поскольку в ECMA-модулях зарезервировано ключевое словоdefaultдля экспорта по умолчанию), оно автоматически переименовывается в класс_default.
styles.css
.foo-baz {
color: red;
}
.bar {
color: blue;
}
.default {
color: green;
} index.js
import * as styles from "./styles.css"; // If using `exportLocalsConvention: "as-is"` (default value): console.log(styles["foo-baz"], styles.bar); // If using `exportLocalsConvention: "camel-case-only"`: console.log(styles.fooBaz, styles.bar); // For the `default` classname console.log(styles["_default"]);
Можно включить экспорт имён ES-модулей, используя:
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
},
},
},
],
},
}; Для установки пользовательского имени для namedExport можно использовать параметр exportLocalsConvention в виде функции. Пример ниже в разделе examples.
exportGlobals
Тип:
type exportsGLobals = boolean;
По умолчанию: false
Разрешить css-loader экспортировать имена из глобального класса или идентификатора, чтобы использовать их в качестве локального имени.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportGlobals: true,
},
},
},
],
},
};
exportLocalsConvention
Тип:
type exportLocalsConvention = | "as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only" | ((name: string) => string);
По умолчанию: Зависит от значения параметра modules.namedExport, если true - as-is, в противном случае camel-case-only.
[!WARNING]
Имена локальных переменных преобразуются в верблюжье написание, когда экспорт имён
false, то есть параметрexportLocalsConventionимеет значениеcamelCaseOnlyпо умолчанию. Вы можете установить это значение на любое другое допустимое значение, но селекторы, которые не являются допустимыми идентификаторами JavaScript, могут столкнуться с проблемами, которые не реализуют всю спецификацию модулей.
Стиль имён экспортируемых классов.
string
По умолчанию экспортируемые ключи JSON соответствуют именам классов (т. е. значение as-is).
| Имя | Тип | Описание |
|---|---|---|
'as-is' |
string |
Имена классов будут экспортированы как есть. |
'camel-case' |
string |
Имена классов будут преобразованны в верблюжье написание, исходное имя класса не будет удалено из локальных переменных. |
'camel-case-only' |
string |
Имена классов будут преобразованны в верблюжье написание, исходное имя класса будет удалено из локальных переменных. |
'dashes' |
string |
В именах классов будут преобразованны только дефисы. |
'dashes-only' |
string |
Дефисы в именах классов будут преобразованны в верблюжье написание, исходное имя класса будет удалено из локальных переменных. |
file.css
.class-name {
} file.js
import { className } from "file.css"; webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportLocalsConvention: "camel-case-only",
},
},
},
],
},
};
function
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportLocalsConvention: function (name) {
return name.replace(/-/g, "_");
},
},
},
},
],
},
}; webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportLocalsConvention: function (name) {
return [
name.replace(/-/g, "_"),
// dashesCamelCase
name.replace(/-+(\w)/g, (match, firstLetter) =>
firstLetter.toUpperCase(),
),
];
},
},
},
},
],
},
};
exportOnlyLocals
Тип:
type exportOnlyLocals = boolean;
По умолчанию: false
Экспортировать только локальные переменные.
Полезно при использовании модулей CSS для предварительного рендеринга (например, SSR). Для предварительного рендеринга с mini-css-extract-plugin используйте этот параметр вместо style-loader!css-loader в пакете предварительного рендеринга. Он не встраивает CSS, а только экспортирует соответствия идентификаторов.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportOnlyLocals: true,
},
},
},
],
},
};
getJSON
Тип:
type getJSON = ({
resourcePath,
imports,
exports,
replacements,
}: {
resourcePath: string;
imports: object[];
exports: object[];
replacements: object[];
}) => Promise<void> | void; По умолчанию: undefined
Включает обратный вызов для вывода JSON-отображения модулей CSS. Обратный вызов вызывается с объектом, содержащим следующее:
-
resourcePath: абсолютный путь к исходному ресурсу, например,/foo/bar/baz.module.css -
imports: массив объектов импорта с данными об типах импорта и путях к файлам, например,
[
{
"type": "icss_import",
"importName": "___CSS_LOADER_ICSS_IMPORT_0___",
"url": "\"-!../../../../../node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[4].use[1]!../../../../../node_modules/postcss-loader/dist/cjs.js!../../../../../node_modules/sass-loader/dist/cjs.js!../../../../baz.module.css\"",
"icss": true,
"index": 0
}
] (Обратите внимание, что это будет включать все импорты, а не только те, которые относятся к модулям CSS.)
-
exports: массив объектов экспорта с экспортируемыми именами и значениями, например,
[
{
"name": "main",
"value": "D2Oy"
}
] -
replacements: массив объектов замены импорта, используемых для связыванияimportsиexports, например,
{
"replacementName": "___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___",
"importName": "___CSS_LOADER_ICSS_IMPORT_0___",
"localName": "main"
} Используя getJSON, можно выводить файлы со всеми соответствиями модулей CSS. В следующем примере мы используем getJSON для кеширования канонических соответствий и добавления плейсхолдеров для любых составленных значений (через composes), и мы используем пользовательский плагин для консолидации значений и вывода их в файл:
webpack.config.js
const path = require("path");
const fs = require("fs");
const CSS_LOADER_REPLACEMENT_REGEX =
/(___CSS_LOADER_ICSS_IMPORT_\d+_REPLACEMENT_\d+___)/g;
const REPLACEMENT_REGEX = /___REPLACEMENT\[(.*?)]\[(.*?)]___/g;
const IDENTIFIER_REGEX = /\[(.*?)]\[(.*?)]/;
const replacementsMap = {};
const canonicalValuesMap = {};
const allExportsJson = {};
function generateIdentifier(resourcePath, localName) {
return `[${resourcePath}][${localName}]`;
}
function addReplacements(resourcePath, imports, exportsJson, replacements) {
const importReplacementsMap = {};
// create a dict to quickly identify imports and get their absolute stand-in strings in the currently loaded file
// e.g., { '___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___': '___REPLACEMENT[/foo/bar/baz.css][main]___' }
importReplacementsMap[resourcePath] = replacements.reduce(
(acc, { replacementName, importName, localName }) => {
const replacementImportUrl = imports.find(
(importData) => importData.importName === importName,
).url;
const relativePathRe = /.*!(.*)"/;
const [, relativePath] = replacementImportUrl.match(relativePathRe);
const importPath = path.resolve(path.dirname(resourcePath), relativePath);
const identifier = generateIdentifier(importPath, localName);
return { ...acc, [replacementName]: `___REPLACEMENT${identifier}___` };
},
{},
);
// iterate through the raw exports and add stand-in variables
// ('___REPLACEMENT[<absolute_path>][<class_name>]___')
// to be replaced in the plugin below
for (const [localName, classNames] of Object.entries(exportsJson)) {
const identifier = generateIdentifier(resourcePath, localName);
if (CSS_LOADER_REPLACEMENT_REGEX.test(classNames)) {
// if there are any replacements needed in the concatenated class names,
// add them all to the replacements map to be replaced altogether later
replacementsMap[identifier] = classNames.replaceAll(
CSS_LOADER_REPLACEMENT_REGEX,
(_, replacementName) =>
importReplacementsMap[resourcePath][replacementName],
);
} else {
// otherwise, no class names need replacements so we can add them to
// canonical values map and all exports JSON verbatim
canonicalValuesMap[identifier] = classNames;
allExportsJson[resourcePath] = allExportsJson[resourcePath] || {};
allExportsJson[resourcePath][localName] = classNames;
}
}
}
function replaceReplacements(classNames) {
return classNames.replaceAll(
REPLACEMENT_REGEX,
(_, resourcePath, localName) => {
const identifier = generateIdentifier(resourcePath, localName);
if (identifier in canonicalValuesMap) {
return canonicalValuesMap[identifier];
}
// Recurse through other stand-in that may be imports
const canonicalValue = replaceReplacements(replacementsMap[identifier]);
canonicalValuesMap[identifier] = canonicalValue;
return canonicalValue;
},
);
}
function getJSON({ resourcePath, imports, exports, replacements }) {
const exportsJson = exports.reduce((acc, { name, value }) => {
return { ...acc, [name]: value };
}, {});
if (replacements.length > 0) {
// replacements present --> add stand-in values for absolute paths and local names,
// which will be resolved to their canonical values in the plugin below
addReplacements(resourcePath, imports, exportsJson, replacements);
} else {
// no replacements present --> add to canonicalValuesMap verbatim
// since all values here are canonical/don't need resolution
for (const [key, value] of Object.entries(exportsJson)) {
const id = `[${resourcePath}][${key}]`;
canonicalValuesMap[id] = value;
}
allExportsJson[resourcePath] = exportsJson;
}
}
class CssModulesJsonPlugin {
constructor(options) {
this.options = options;
}
// eslint-disable-next-line class-methods-use-this
apply(compiler) {
compiler.hooks.emit.tap("CssModulesJsonPlugin", () => {
for (const [identifier, classNames] of Object.entries(replacementsMap)) {
const adjustedClassNames = replaceReplacements(classNames);
replacementsMap[identifier] = adjustedClassNames;
const [, resourcePath, localName] = identifier.match(IDENTIFIER_REGEX);
allExportsJson[resourcePath] = allExportsJson[resourcePath] || {};
allExportsJson[resourcePath][localName] = adjustedClassNames;
}
fs.writeFileSync(
this.options.filepath,
JSON.stringify(
// Make path to be relative to `context` (your project root)
Object.fromEntries(
Object.entries(allExportsJson).map((key) => {
key[0] = path
.relative(compiler.context, key[0])
.replace(/\\/g, "/");
return key;
}),
),
null,
2,
),
"utf8",
);
});
}
}
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: { modules: { getJSON } },
},
],
},
plugins: [
new CssModulesJsonPlugin({
filepath: path.resolve(__dirname, "./output.css.json"),
}),
],
}; В вышеприведённом примере все псевдонимы импорта заменены на ___REPLACEMENT[<resourcePath>][<localName>]___ в getJSON, и они разрешаются в пользовательском плагине. Все соответствия CSS содержатся в allExportsJson:
{
"foo/bar/baz.module.css": {
"main": "D2Oy",
"header": "thNN"
},
"foot/bear/bath.module.css": {
"logo": "sqiR",
"info": "XMyI"
}
} Это сохраняется в локальном файле с именем output.css.json.
importLoaders
Тип:
type importLoaders = number;
По умолчанию: 0
Включает/отключает или настраивает количество загрузчиков, применяемых перед загрузчиком CSS для @import псевдоклассов, модулей CSS и импортов ICSS, т. е. @import/composes/@value value from './values.css' и т. д.
Параметр importLoaders позволяет настроить количество загрузчиков перед css-loader, которые следует применить к ресурсам @import и модулям CSS/импортам ICSS.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2,
// 0 => no loaders (default);
// 1 => postcss-loader;
// 2 => postcss-loader, sass-loader
},
},
"postcss-loader",
"sass-loader",
],
},
],
},
}; Это может измениться в будущем, когда система модулей (например, webpack) будет поддерживать соответствие загрузчиков по источнику.
sourceMap
Тип:
type sourceMap = boolean;
По умолчанию: зависит от значения compiler.devtool
По умолчанию, генерация карт исходного кода зависит от параметра devtool. Все значения, кроме eval и false, включают генерацию карт исходного кода.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
sourceMap: true,
},
},
],
},
};
esModule
Тип:
type esModule = boolean;
По умолчанию: true
По умолчанию, css-loader генерирует JS-модули, которые используют синтаксис ES-модулей. В некоторых случаях использование ES-модулей выгодно, например, в случае с конкатенацией модулей и устранением лишнего кода.
Вы можете включить синтаксис модулей CommonJS, используя:
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
esModule: false,
},
},
],
},
};
exportType
Тип:
type exportType = "array" | "string" | "css-style-sheet";
По умолчанию: 'array'
Позволяет экспортировать стили как массив с модулями, строку или объект-стиль (например, CSSStyleSheet). Значение по умолчанию — 'array', т.е. загрузчик экспортирует массив модулей со специфическим API, используемым в style-loader или других местах.
webpack.config.js
module.exports = {
module: {
rules: [
{
assert: { type: "css" },
loader: "css-loader",
options: {
exportType: "css-style-sheet",
},
},
],
},
}; src/index.js
import sheet from "./styles.css" assert { type: "css" };
document.adoptedStyleSheets = [sheet];
shadowRoot.adoptedStyleSheets = [sheet];
'array'
Экспорт по умолчанию — массив модулей со специфическим API, используемый в style-loader или других местах.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/i,
use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"],
},
],
},
}; src/index.js
// `style-loader` applies styles to DOM import "./styles.css";
'string'
[!ПРЕДУПРЕЖДЕНИЕ]
Не следует использовать
style-loaderилиmini-css-extract-pluginс этим значением.
[!ПРЕДУПРЕЖДЕНИЕ]
Опция
esModuleдолжна быть включена, если вы хотите использовать её сCSS modules, по умолчанию для локальных стилей используется экспорт с именем.
Экспорт по умолчанию — string.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/i,
use: ["css-loader", "postcss-loader", "sass-loader"],
},
],
},
}; src/index.js
import sheet from "./styles.css"; console.log(sheet);
'css-style-sheet'
[!ПРЕДУПРЕЖДЕНИЕ]
Правила
@importпока не поддерживаются, дополнительная информация
[!ПРЕДУПРЕЖДЕНИЕ]
Вам больше не нужен
style-loader, пожалуйста, удалите его.
[!ПРЕДУПРЕЖДЕНИЕ]
Опция
esModuleдолжна быть включена, если вы хотите использовать её сCSS modules, по умолчанию для локальных стилей используется экспорт с именем.
[!ПРЕДУПРЕЖДЕНИЕ]
Карты исходных данных в настоящее время не поддерживаются в
Chromeиз-за ошибки
Экспорт по умолчанию — объект-стиль (т.е. CSSStyleSheet).
Полезно для создания пользовательских элементов и тени DOM.
Дополнительная информация:
- Использование сценариев CSS-модулей для импорта стилей
- Объекты-стили: бесшовные, многократно используемые стили
webpack.config.js
module.exports = {
module: {
rules: [
{
assert: { type: "css" },
loader: "css-loader",
options: {
exportType: "css-style-sheet",
},
},
// For Sass/SCSS:
//
// {
// assert: { type: "css" },
// rules: [
// {
// loader: "css-loader",
// options: {
// exportType: "css-style-sheet",
// // Other options
// },
// },
// {
// loader: "sass-loader",
// options: {
// // Other options
// },
// },
// ],
// },
],
},
}; src/index.js
// Example for Sass/SCSS:
// import sheet from "./styles.scss" assert { type: "css" };
// Example for CSS modules:
// import sheet, { myClass } from "./styles.scss" assert { type: "css" };
// Example for CSS:
import sheet from "./styles.css" assert { type: "css" };
document.adoptedStyleSheets = [sheet];
shadowRoot.adoptedStyleSheets = [sheet]; Для целей миграции вы можете использовать следующую конфигурацию:
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
oneOf: [
{
assert: { type: "css" },
loader: "css-loader",
options: {
exportType: "css-style-sheet",
// Other options
},
},
{
use: [
"style-loader",
{
loader: "css-loader",
options: {
// Other options
},
},
],
},
],
},
],
},
}; Примеры
Рекомендации
Для сборки production рекомендуется извлекать CSS из вашего пакета, что позволит использовать параллельную загрузку ресурсов CSS/JS в дальнейшем. Это можно сделать, используя плагин mini-css-extract-plugin, так как он создаёт отдельные файлы CSS. Для режима development (включая webpack-dev-server) можно использовать style-loader, так как он вставляет CSS в DOM с помощью нескольких <style></style> и работает быстрее.
[!ПРИМЕЧАНИЕ]
Не используйте
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$/i,
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
};
Отключение разрешения URL с помощью комментария /* webpackIgnore: true */
С помощью комментария /* webpackIgnore: true */ можно отключить обработку источников для правил и отдельных объявлений.
/* webpackIgnore: true */
@import url(./basic.css);
@import /* webpackIgnore: true */ url(./imported.css);
.class {
/* Disabled url handling for the all urls in the 'background' declaration */
color: red;
/* webpackIgnore: true */
background: url("./url/img.png"), url("./url/img.png");
}
.class {
/* Disabled url handling for the first url in the 'background' declaration */
color: red;
background:
/* webpackIgnore: true */ url("./url/img.png"), url("./url/img.png");
}
.class {
/* Disabled url handling for the second url in the 'background' declaration */
color: red;
background:
url("./url/img.png"),
/* webpackIgnore: true */ url("./url/img.png");
}
/* prettier-ignore */
.class {
/* Disabled url handling for the second url in the 'background' declaration */
color: red;
background: url("./url/img.png"),
/* webpackIgnore: true */
url("./url/img.png");
}
/* prettier-ignore */
.class {
/* Disabled url handling for third and sixth urls in the 'background-image' declaration */
background-image: image-set(
url(./url/img.png) 2x,
url(./url/img.png) 3x,
/* webpackIgnore: true */ url(./url/img.png) 4x,
url(./url/img.png) 5x,
url(./url/img.png) 6x,
/* webpackIgnore: true */
url(./url/img.png) 7x
);
} Активы
Следующий webpack.config.js может загружать файлы CSS, встраивать небольшие изображения PNG/JPG/GIF/SVG, а также шрифты в виде Data URL и копировать более крупные файлы в выходную директорию.
Для webpack v5:
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
// More information here https://webpack.js.org/guides/asset-modules/
type: "asset",
},
],
},
}; Извлечение
Для сборок в режиме производства рекомендуется извлекать CSS из вашего пакета, что позволит использовать параллельную загрузку ресурсов CSS/JS в дальнейшем.
-
Этого можно достичь, используя плагин mini-css-extract-plugin для извлечения CSS при запуске в режиме производства.
-
В качестве альтернативы, если вам нужна лучшая производительность в режиме разработки и вывод CSS, имитирующий производство. extract-css-chunks-webpack-plugin предлагает дружественную к горячей перезагрузке расширенную версию плагина mini-css-extract-plugin. HMR обновляет реальные CSS-файлы в режиме разработки, работая так же, как mini-css в режиме не разработки
Чистый CSS, CSS-модули и PostCSS
Если в вашем проекте используется чистый CSS (без CSS-модулей), CSS-модули и PostCSS, вы можете использовать следующую настройку:
webpack.config.js
module.exports = {
module: {
rules: [
{
// For pure CSS - /\.css$/i,
// For Sass/SCSS - /\.((c|sa|sc)ss)$/i,
// For Less - /\.((c|le)ss)$/i,
test: /\.((c|sa|sc)ss)$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
// Run `postcss-loader` on each CSS `@import` and CSS modules/ICSS imports, do not forget that `sass-loader` compile non CSS `@import`'s into a single file
// If you need run `sass-loader` and `postcss-loader` on each CSS `@import` please set it to `2`
importLoaders: 1,
},
},
{
loader: "postcss-loader",
options: { plugins: () => [postcssPresetEnv({ stage: 0 })] },
},
// Can be `less-loader`
{
loader: "sass-loader",
},
],
},
// For webpack v5
{
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
// More information here https://webpack.js.org/guides/asset-modules/
type: "asset",
},
],
},
}; Разрешение неразрешенных URL с помощью псевдонима
index.css
.class {
background: url(/assets/unresolved/img.png);
} webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
resolve: {
alias: {
"/assets/unresolved/img.png": path.resolve(
__dirname,
"assets/real-path-to-img/img.png",
),
},
},
}; Именованный экспорт со своими именами
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
namedExport: true,
exportLocalsConvention: function (name) {
return name.replace(/-/g, "_");
},
},
},
},
],
},
};
Разделение функций, относящихся только к Interoperable CSS и CSS Module
Следующая настройка демонстрирует возможность включения функций, относящихся только к Interoperable CSS (например, :import и :export ), без использования дополнительных функций CSS Module, установив опцию mode для всех файлов, не соответствующих соглашению об именовании *.module.scss. Это демонстрация, так как ранее по умолчанию все файлы получали функции ICSS в версии до v4. В то же время, все файлы, соответствующие *.module.scss, рассматриваются как CSS Modules в данном примере.
Предполагается, что проект требует синхронизации переменных рисования холста с CSS — рисование на холсте использует тот же цвет (установленный в JavaScript по имени цвета), что и фон HTML (установленный по имени класса в CSS).
webpack.config.js
module.exports = {
module: {
rules: [
// ...
// --------
// SCSS ALL EXCEPT MODULES
{
test: /\.scss$/i,
exclude: /\.module\.scss$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
mode: "icss",
},
},
},
{
loader: "sass-loader",
},
],
},
// --------
// SCSS MODULES
{
test: /\.module\.scss$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
mode: "local",
},
},
},
{
loader: "sass-loader",
},
],
},
// --------
// ...
],
},
}; variables.scss
Файл обрабатывается только как ICSS.
$colorBackground: red;
:export {
colorBackgroundCanvas: $colorBackground;
} Component.module.scss
Файл обрабатывается как CSS Module.
@import "variables.scss";
.componentClass {
background-color: $colorBackground;
} Component.jsx
Использование функциональности CSS Module наряду с переменными SCSS напрямую в JavaScript.
import * as svars from "variables.scss";
import * as styles from "Component.module.scss";
// Render DOM with CSS modules class name
// <div className={styles.componentClass}>
// <canvas ref={mountsCanvas}/>
// </div>
// Somewhere in JavaScript canvas drawing code use the variable directly
// const ctx = mountsCanvas.current.getContext('2d',{alpha: false});
ctx.fillStyle = `${svars.colorBackgroundCanvas}`;
Содействие
Пожалуйста, ознакомьтесь с нашими рекомендациями по содействию, если вы этого еще не сделали.
Лицензия
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/loaders/css-loader