7eda7addd7b211de6bade1281ca08b9921eba2654cedd8638601907459beffe28bc17bbed1759c5208c6c36df235058f542b4efac21a2249e8753822f0edf7 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <div align="center">
  2. <!-- replace with accurate logo e.g from https://worldvectorlogo.com/ -->
  3. <img width="200" height="200" src="https://cdn.worldvectorlogo.com/logos/javascript.svg">
  4. <a href="https://webpack.js.org/">
  5. <img width="200" height="200" vspace="" hspace="25" src="https://cdn.rawgit.com/webpack/media/e7485eb2/logo/icon-square-big.svg">
  6. </a>
  7. <h1>mini-css-extract-plugin</h1>
  8. </div>
  9. [![npm][npm]][npm-url]
  10. [![deps][deps]][deps-url]
  11. [![tests][tests]][tests-url]
  12. [![coverage][cover]][cover-url]
  13. [![chat][chat]][chat-url]
  14. 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.
  15. It builds on top of a new webpack v4 feature (module types) and requires webpack 4 to work.
  16. Compared to the extract-text-webpack-plugin:
  17. - Async loading
  18. - No duplicate compilation (performance)
  19. - Easier to use
  20. - Specific to CSS
  21. <h2 align="center">Install</h2>
  22. ```bash
  23. npm install --save-dev mini-css-extract-plugin
  24. ```
  25. <h2 align="center">Usage</h2>
  26. ### Configuration
  27. #### `publicPath`
  28. Type: `String|Function`
  29. Default: the `publicPath` in `webpackOptions.output`
  30. Specifies a custom public path for the target file(s).
  31. #### `esModule`
  32. Type: `Boolean`
  33. Default: `false`
  34. By default, `mini-css-extract-plugin` generates JS modules that use the CommonJS modules syntax.
  35. 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/).
  36. You can enable a ES module syntax using:
  37. **webpack.config.js**
  38. ```js
  39. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  40. module.exports = {
  41. plugins: [new MiniCssExtractPlugin()],
  42. module: {
  43. rules: [
  44. {
  45. test: /\.css$/i,
  46. use: [
  47. {
  48. loader: MiniCssExtractPlugin.loader,
  49. options: {
  50. esModule: true,
  51. },
  52. },
  53. 'css-loader',
  54. ],
  55. },
  56. ],
  57. },
  58. };
  59. ```
  60. #### Minimal example
  61. **webpack.config.js**
  62. ```js
  63. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  64. module.exports = {
  65. plugins: [
  66. new MiniCssExtractPlugin({
  67. // Options similar to the same options in webpackOptions.output
  68. // all options are optional
  69. filename: '[name].css',
  70. chunkFilename: '[id].css',
  71. ignoreOrder: false, // Enable to remove warnings about conflicting order
  72. }),
  73. ],
  74. module: {
  75. rules: [
  76. {
  77. test: /\.css$/,
  78. use: [
  79. {
  80. loader: MiniCssExtractPlugin.loader,
  81. options: {
  82. // you can specify a publicPath here
  83. // by default it uses publicPath in webpackOptions.output
  84. publicPath: '../',
  85. hmr: process.env.NODE_ENV === 'development',
  86. },
  87. },
  88. 'css-loader',
  89. ],
  90. },
  91. ],
  92. },
  93. };
  94. ```
  95. #### `publicPath` function example
  96. **webpack.config.js**
  97. ```js
  98. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  99. module.exports = {
  100. plugins: [
  101. new MiniCssExtractPlugin({
  102. // Options similar to the same options in webpackOptions.output
  103. // both options are optional
  104. filename: '[name].css',
  105. chunkFilename: '[id].css',
  106. }),
  107. ],
  108. module: {
  109. rules: [
  110. {
  111. test: /\.css$/,
  112. use: [
  113. {
  114. loader: MiniCssExtractPlugin.loader,
  115. options: {
  116. publicPath: (resourcePath, context) => {
  117. // publicPath is the relative path of the resource to the context
  118. // e.g. for ./css/admin/main.css the publicPath will be ../../
  119. // while for ./css/main.css the publicPath will be ../
  120. return path.relative(path.dirname(resourcePath), context) + '/';
  121. },
  122. },
  123. },
  124. 'css-loader',
  125. ],
  126. },
  127. ],
  128. },
  129. };
  130. ```
  131. #### Advanced configuration example
  132. 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`.
  133. Here is an example to have both HMR in `development` and your styles extracted in a file for `production` builds.
  134. (Loaders options left out for clarity, adapt accordingly to your needs.)
  135. **webpack.config.js**
  136. ```js
  137. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  138. const devMode = process.env.NODE_ENV !== 'production';
  139. module.exports = {
  140. plugins: [
  141. new MiniCssExtractPlugin({
  142. // Options similar to the same options in webpackOptions.output
  143. // both options are optional
  144. filename: devMode ? '[name].css' : '[name].[hash].css',
  145. chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
  146. }),
  147. ],
  148. module: {
  149. rules: [
  150. {
  151. test: /\.(sa|sc|c)ss$/,
  152. use: [
  153. {
  154. loader: MiniCssExtractPlugin.loader,
  155. options: {
  156. hmr: process.env.NODE_ENV === 'development',
  157. },
  158. },
  159. 'css-loader',
  160. 'postcss-loader',
  161. 'sass-loader',
  162. ],
  163. },
  164. ],
  165. },
  166. };
  167. ```
  168. #### Hot Module Reloading (HMR)
  169. extract-mini-css-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.
  170. While we attempt to hmr css-modules. It is not easy to perform when code-splitting with custom chunk names. `reloadAll` is an option that should only be enabled if HMR isn't working correctly. The core challenge with css-modules is that when code-split, the chunk ids can and do end up different compared to the filename.
  171. **webpack.config.js**
  172. ```js
  173. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  174. module.exports = {
  175. plugins: [
  176. new MiniCssExtractPlugin({
  177. // Options similar to the same options in webpackOptions.output
  178. // both options are optional
  179. filename: '[name].css',
  180. chunkFilename: '[id].css',
  181. }),
  182. ],
  183. module: {
  184. rules: [
  185. {
  186. test: /\.css$/,
  187. use: [
  188. {
  189. loader: MiniCssExtractPlugin.loader,
  190. options: {
  191. // only enable hot in development
  192. hmr: process.env.NODE_ENV === 'development',
  193. // if hmr does not work, this is a forceful method.
  194. reloadAll: true,
  195. },
  196. },
  197. 'css-loader',
  198. ],
  199. },
  200. ],
  201. },
  202. };
  203. ```
  204. ### Minimizing For Production
  205. 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:
  206. **webpack.config.js**
  207. ```js
  208. const TerserJSPlugin = require('terser-webpack-plugin');
  209. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  210. const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  211. module.exports = {
  212. optimization: {
  213. minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
  214. },
  215. plugins: [
  216. new MiniCssExtractPlugin({
  217. filename: '[name].css',
  218. chunkFilename: '[id].css',
  219. }),
  220. ],
  221. module: {
  222. rules: [
  223. {
  224. test: /\.css$/,
  225. use: [MiniCssExtractPlugin.loader, 'css-loader'],
  226. },
  227. ],
  228. },
  229. };
  230. ```
  231. ### Features
  232. #### Using preloaded or inlined CSS
  233. The runtime code detects already added CSS via `<link>` or `<style>` tag.
  234. This can be useful when injecting CSS on server-side for Server-Side-Rendering.
  235. The `href` of the `<link>` tag has to match the URL that will be used for loading the CSS chunk.
  236. The `data-href` attribute can be used for `<link>` and `<style>` too.
  237. When inlining CSS `data-href` must be used.
  238. #### Extracting all CSS in a single file
  239. Similar to what [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) does, the CSS
  240. can be extracted in one CSS file using `optimization.splitChunks.cacheGroups`.
  241. **webpack.config.js**
  242. ```js
  243. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  244. module.exports = {
  245. optimization: {
  246. splitChunks: {
  247. cacheGroups: {
  248. styles: {
  249. name: 'styles',
  250. test: /\.css$/,
  251. chunks: 'all',
  252. enforce: true,
  253. },
  254. },
  255. },
  256. },
  257. plugins: [
  258. new MiniCssExtractPlugin({
  259. filename: '[name].css',
  260. }),
  261. ],
  262. module: {
  263. rules: [
  264. {
  265. test: /\.css$/,
  266. use: [MiniCssExtractPlugin.loader, 'css-loader'],
  267. },
  268. ],
  269. },
  270. };
  271. ```
  272. #### Extracting CSS based on entry
  273. You may also extract the CSS based on the webpack entry name. This is especially useful if you import routes dynamically
  274. but want to keep your CSS bundled according to entry. This also prevents the CSS duplication issue one had with the
  275. ExtractTextPlugin.
  276. ```javascript
  277. const path = require('path');
  278. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  279. function recursiveIssuer(m) {
  280. if (m.issuer) {
  281. return recursiveIssuer(m.issuer);
  282. } else if (m.name) {
  283. return m.name;
  284. } else {
  285. return false;
  286. }
  287. }
  288. module.exports = {
  289. entry: {
  290. foo: path.resolve(__dirname, 'src/foo'),
  291. bar: path.resolve(__dirname, 'src/bar'),
  292. },
  293. optimization: {
  294. splitChunks: {
  295. cacheGroups: {
  296. fooStyles: {
  297. name: 'foo',
  298. test: (m, c, entry = 'foo') =>
  299. m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
  300. chunks: 'all',
  301. enforce: true,
  302. },
  303. barStyles: {
  304. name: 'bar',
  305. test: (m, c, entry = 'bar') =>
  306. m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
  307. chunks: 'all',
  308. enforce: true,
  309. },
  310. },
  311. },
  312. },
  313. plugins: [
  314. new MiniCssExtractPlugin({
  315. filename: '[name].css',
  316. }),
  317. ],
  318. module: {
  319. rules: [
  320. {
  321. test: /\.css$/,
  322. use: [MiniCssExtractPlugin.loader, 'css-loader'],
  323. },
  324. ],
  325. },
  326. };
  327. ```
  328. #### Module Filename Option
  329. With the `moduleFilename` option you can use chunk data to customize the filename. This is particularly useful when dealing with multiple entry points and wanting to get more control out of the filename for a given entry point/chunk. In the example below, we'll use `moduleFilename` to output the generated css into a different directory.
  330. ```javascript
  331. const miniCssExtractPlugin = new MiniCssExtractPlugin({
  332. moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css`,
  333. });
  334. ```
  335. #### Long Term Caching
  336. For long term caching use `filename: "[contenthash].css"`. Optionally add `[name]`.
  337. ### Remove Order Warnings
  338. For projects where css ordering has been mitigated through consistent use of scoping or naming conventions, the css order warnings can be disabled by setting the ignoreOrder flag to true for the plugin.
  339. ```javascript
  340. new MiniCssExtractPlugin({
  341. ignoreOrder: true,
  342. }),
  343. ```
  344. ### Media Query Plugin
  345. If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins:
  346. - [Media Query Plugin](https://github.com/SassNinja/media-query-plugin)
  347. - [Media Query Splitting Plugin](https://github.com/mike-diamond/media-query-splitting-plugin)
  348. ## License
  349. [MIT](./LICENSE)
  350. [npm]: https://img.shields.io/npm/v/mini-css-extract-plugin.svg
  351. [npm-url]: https://npmjs.com/package/mini-css-extract-plugin
  352. [node]: https://img.shields.io/node/v/mini-css-extract-plugin.svg
  353. [node-url]: https://nodejs.org
  354. [deps]: https://david-dm.org/webpack-contrib/mini-css-extract-plugin.svg
  355. [deps-url]: https://david-dm.org/webpack-contrib/mini-css-extract-plugin
  356. [tests]: https://dev.azure.com/webpack-contrib/mini-css-extract-plugin/_apis/build/status/webpack-contrib.mini-css-extract-plugin?branchName=master
  357. [tests-url]: https://dev.azure.com/webpack-contrib/mini-css-extract-plugin/_build/latest?definitionId=6&branchName=master
  358. [cover]: https://codecov.io/gh/webpack-contrib/mini-css-extract-plugin/branch/master/graph/badge.svg
  359. [cover-url]: https://codecov.io/gh/webpack-contrib/mini-css-extract-plugin
  360. [chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
  361. [chat-url]: https://gitter.im/webpack/webpack
  362. [size]: https://packagephobia.now.sh/badge?p=mini-css-extract-plugin
  363. [size-url]: https://packagephobia.now.sh/result?p=mini-css-extract-plugin