Spec-Zone.ru › webpack 4

MiniCssExtractPlugin

Этот плагин извлекает CSS в отдельные файлы. Он создаёт файл CSS на каждый файл JS, содержащий CSS. Он поддерживает загрузку CSS по требованию и карты исходного кода.

Он основан на новой функции webpack v4 (типы модулей) и требует webpack 4 для работы.

По сравнению с extract-text-webpack-plugin:

  • Асинхронная загрузка
  • Отсутствие дублирования компиляции (производительность)
  • Проще в использовании
  • Специально для CSS

Установка

npm install --save-dev mini-css-extract-plugin

Использование

Настройка

publicPath

Тип: String|Function Значение по умолчанию: publicPath в webpackOptions.output

Указывает пользовательский путь к общедоступному каталогу для целевого файла(ов).

Минимальный пример

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // all options are optional
      filename: '[name].css',
      chunkFilename: '[id].css',
      ignoreOrder: false, // Enable to remove warnings about conflicting order
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // you can specify a publicPath here
              // by default it uses publicPath in webpackOptions.output
              publicPath: '../',
              hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

publicPath пример функции

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: (resourcePath, context) => {
                // publicPath is the relative path of the resource to the context
                // e.g. for ./css/admin/main.css the publicPath will be ../../
                // while for ./css/main.css the publicPath will be ../
                return path.relative(path.dirname(resourcePath), context) + '/';
              },
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

Пример расширенной настройки

Этот плагин следует использовать только для production сборки без style-loader в цепочке загрузчиков, особенно если вы хотите иметь HMR в development.

Вот пример, чтобы иметь как HMR в development и ваши стили, извлечённые в файл для production сборок.

(Опции загрузчиков опущены для ясности, адаптируйте их соответственно вашим потребностям.)

webpack.config.js

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

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: devMode ? '[name].css' : '[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      },
    ],
  },
};

Горячая замена модулей (HMR)

extract-mini-css-plugin поддерживает горячую загрузку фактических файлов CSS в режиме разработки. Предоставляются некоторые параметры для включения HMR как для стандартных таблиц стилей, так и для CSS или CSS-модулей с локальным объявлением. Ниже представлена примерная конфигурация mini-css для использования HMR с CSS-модулями.

Хотя мы пытаемся выполнить hmr css-модулей. Это нелегко сделать при разделении кода с пользовательскими именами блоков. reloadAll - это опция, которую следует включать только в том случае, если HMR не работает правильно. Основная проблема с css-модулями заключается в том, что при разделении кода идентификаторы блоков могут и часто отличаются от имён файлов.

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // only enable hot in development
              hmr: process.env.NODE_ENV === 'development',
              // if hmr does not work, this is a forceful method.
              reloadAll: true,
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

Минификация для производства

Для минимизации вывода используйте плагин, такой как optimize-css-assets-webpack-plugin. Установка optimization.minimizer переопределяет значения по умолчанию, предоставляемые webpack, поэтому обязательно укажите и минимизатор JS:

webpack.config.js

const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
  optimization: {
    minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
};

Функции

Использование предварительно загруженного или встроенного CSS

Код выполнения обнаруживает уже добавленный CSS через <link> или <style> тег. Это может быть полезно при вставке CSS на стороне сервера для рендеринга на стороне сервера. href тега <link> должно совпадать с URL, который будет использоваться для загрузки блока CSS. Атрибут data-href может использоваться для <link> и <style> тоже. При встраивании CSS необходимо использовать data-href.

Извлечение всего CSS в один файл

Подобно тому, что делает extract-text-webpack-plugin, CSS можно извлечь в один файл CSS, используя optimization.splitChunks.cacheGroups.

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        styles: {
          name: 'styles',
          test: /\.css$/,
          chunks: 'all',
          enforce: true,
        },
      },
    },
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
};

Извлечение CSS на основе входа

Вы также можете извлечь CSS на основе имени входа webpack. Это особенно полезно, если вы динамически импортируете маршруты, но хотите сохранить ваши CSS-сборки в соответствии с входом. Это также предотвращает проблему дублирования CSS, которая была с ExtractTextPlugin.

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

function recursiveIssuer(m) {
  if (m.issuer) {
    return recursiveIssuer(m.issuer);
  } else if (m.name) {
    return m.name;
  } else {
    return false;
  }
}

module.exports = {
  entry: {
    foo: path.resolve(__dirname, 'src/foo'),
    bar: path.resolve(__dirname, 'src/bar'),
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        fooStyles: {
          name: 'foo',
          test: (m, c, entry = 'foo') =>
            m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
          chunks: 'all',
          enforce: true,
        },
        barStyles: {
          name: 'bar',
          test: (m, c, entry = 'bar') =>
            m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
          chunks: 'all',
          enforce: true,
        },
      },
    },
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
};

Опция имени файла модуля

С помощью опции moduleFilename вы можете использовать данные блока для настройки имени файла. Это особенно полезно при работе с несколькими точками входа и желанием получить больший контроль над именем файла для заданной точки входа/блока. В примере ниже мы будем использовать moduleFilename для вывода сгенерированного CSS в другой каталог.

const miniCssExtractPlugin = new MiniCssExtractPlugin({
  moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css`,
});

Кэширование на длительный срок

Для кэширования на длительный срок используйте filename: "[contenthash].css". Дополнительно добавьте [name].

Удаление предупреждений о порядке

Для проектов, где порядок CSS был смягчён за счёт последовательного использования объявления или соглашений об именах, предупреждения о порядке CSS можно отключить, установив флаг ignoreOrder в значение true для плагина.

new MiniCssExtractPlugin({
  ignoreOrder: true,
}),

Плагин для медиа-запросов

Если вам нужно извлечь медиа-запросы из извлечённого CSS (чтобы пользователи мобильных устройств больше не загружали CSS для настольных компьютеров или планшетов), вы можете использовать один из следующих плагинов:

  • Плагин для медиа-запросов
  • Плагин разделения медиа-запросов

Лицензия

MIT

© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://v4.webpack.js.org/plugins/mini-css-extract-plugin

Spec-Zone.ru

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