Spec-Zone.ru › webpack 5

css-loader

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

Блок 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
  • import
  • modules
  • sourceMap
  • importLoaders
  • esModule
  • exportType

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

Содействие

Пожалуйста, ознакомьтесь с нашими рекомендациями по содействию, если вы этого еще не сделали.

CONTRIBUTING

Лицензия

MIT

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

Spec-Zone.ru

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