mini-css-extract-plugin

[![npm][npm]][npm-url] [![node][node]][node-url] [![deps][deps]][deps-url] [![tests][tests]][tests-url] [![coverage][cover]][cover-url] [![chat][chat]][chat-url] [![size][size]][size-url] # mini-css-extract-plugin This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps. It builds on top of a new webpack v4 feature (module types) and requires webpack 4 to work. Compared to the extract-text-webpack-plugin: - Async loading - No duplicate compilation (performance) - Easier to use - Specific to CSS ## Getting Started To begin, you'll need to install `mini-css-extract-plugin`: ```bash npm install --save-dev mini-css-extract-plugin ``` It's recommended to combine `mini-css-extract-plugin` with the [`css-loader`](https://github.com/webpack-contrib/css-loader) Then add the loader and the plugin to your `webpack` config. For example: **style.css** ```css body { background: green; } ``` **component.js** ```js import './style.css'; ``` **webpack.config.js** ```js const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { plugins: [new MiniCssExtractPlugin()], module: { rules: [ { test: /\.css$/i, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, ], }, }; ``` ## Options ### `publicPath` Type: `String|Function` Default: the `publicPath` in `webpackOptions.output` Specifies a custom public path for the target file(s). #### `String` **webpack.config.js** ```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: '/public/path/to/', }, }, 'css-loader', ], }, ], }, }; ``` #### `Function` **webpack.config.js** ```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) => { return path.relative(path.dirname(resourcePath), context) + '/'; }, }, }, 'css-loader', ], }, ], }, }; ``` ### `esModule` Type: `Boolean` Default: `true` By default, `mini-css-extract-plugin` generates JS modules that use the ES modules syntax. There are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/). You can enable a CommonJS syntax using: **webpack.config.js** ```js const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { plugins: [new MiniCssExtractPlugin()], module: { rules: [ { test: /\.css$/i, use: [ { loader: MiniCssExtractPlugin.loader, options: { esModule: false, }, }, 'css-loader', ], }, ], }, }; ``` ### `modules` Type: `Object` Default: `undefined` Configuration CSS Modules. #### `namedExport` Type: `Boolean` Default: `false` Enables/disables ES modules named export for locals. > ⚠ Names of locals are converted to `camelCase`. > ⚠ It is not allowed to use JavaScript reserved words in css class names. > ⚠ Options `esModule` and `modules.namedExport` in `css-loader` and `MiniCssExtractPlugin.loader` should be enabled. **styles.css** ```css .foo-baz { color: red; } .bar { color: blue; } ``` **index.js** ```js import { fooBaz, bar } from './styles.css'; console.log(fooBaz, bar); ``` You can enable a ES module named export using: **webpack.config.js** ```js const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { plugins: [new MiniCssExtractPlugin()], module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { esModule: true, modules: { namedExport: true, }, }, }, { loader: 'css-loader', options: { esModule: true, modules: { namedExport: true, localIdentName: 'foo__[name]__[local]', }, }, }, ], }, ], }, }; ``` ## Examples ### Minimal example **webpack.config.js** ```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: '../', }, }, 'css-loader', ], }, ], }, }; ``` ### The `publicPath` option as function **webpack.config.js** ```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', ], }, ], }, }; ``` ### Advanced configuration example This plugin should be used only on `production` builds without `style-loader` in the loaders chain, especially if you want to have HMR in `development`. Here is an example to have both HMR in `development` and your styles extracted in a file for `production` builds. (Loaders options left out for clarity, adapt accordingly to your needs.) You should not use `HotModuleReplacementPlugin` plugin if you are using a `webpack-dev-server`. `webpack-dev-server` enables / disables HMR using `hot` option. **webpack.config.js** ```js const webpack = require('webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const devMode = process.env.NODE_ENV !== 'production'; const 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', }), ]; if (devMode) { // only enable hot in development plugins.push(new webpack.HotModuleReplacementPlugin()); } module.exports = { plugins, module: { rules: [ { test: /\.(sa|sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader', ], }, ], }, }; ``` ### Hot Module Reloading (HMR) Note: HMR is automatically supported in webpack 5. No need to configure it. Skip the following: The `mini-css-extract-plugin` supports hot reloading of actual css files in development. Some options are provided to enable HMR of both standard stylesheets and locally scoped CSS or CSS modules. Below is an example configuration of mini-css for HMR use with CSS modules. You should not use `HotModuleReplacementPlugin` plugin if you are using a `webpack-dev-server`. `webpack-dev-server` enables / disables HMR using `hot` option. **webpack.config.js** ```js const webpack = require('webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const 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', }), ]; if (devMode) { // only enable hot in development plugins.push(new webpack.HotModuleReplacementPlugin()); } module.exports = { plugins, module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: {}, }, 'css-loader', ], }, ], }, }; ``` ### Minimizing For Production To minify the output, use a plugin like [optimize-css-assets-webpack-plugin](https://github.com/NMFR/optimize-css-assets-webpack-plugin). Setting `optimization.minimizer` overrides the defaults provided by webpack, so make sure to also specify a JS minimizer: **webpack.config.js** ```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'], }, ], }, }; ``` ### Using preloaded or inlined CSS The runtime code detects already added CSS via `` or `