diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 8cf96662..2d349884 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -43,8 +43,8 @@ jobs: - name: Lint run: npm run lint - # - name: Security audit - # run: npm run security + - name: Security audit + run: npm run security - name: Check commit message uses: wagoid/commitlint-github-action@v1 @@ -55,9 +55,8 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - # css-loader doesn't support node@6 node-version: [10.x, 12.x, 14.x] - webpack-version: [latest, next] + webpack-version: [4, latest] runs-on: ${{ matrix.os }} diff --git a/.prettierrc.js b/.prettierrc.js index 1934550a..4f14003f 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,5 +1 @@ -module.exports = { - singleQuote: true, - trailingComma: 'es5', - arrowParens: 'always', -}; +module.exports = { singleQuote: true }; diff --git a/CHANGELOG.md b/CHANGELOG.md index cf804ec6..41e9fcf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.1.0](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v1.0.0...v1.1.0) (2020-10-19) + + +### Features + +* added the `attributes` option ([e8a2d5a](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/e8a2d5a09ded967e0f4be145f1f52c1e5f7f6df1)) +* added the `insert` option ([a5f17c4](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/a5f17c48cbf0c198ebc955032d11593434ef2373)) + + +### Bug Fixes + +* ignore modules without identifier ([#627](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/627)) ([71a9ce9](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/71a9ce91b377fff892068b87445372fe1c2db142)) +* remove `normalize-url` from deps ([#623](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/623)) ([9ae47e5](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/9ae47e51f198f2e0258d0e87d6e708e57c05bf86)) + ### [1.0.0](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.12.0...v1.0.0) (2020-10-09) ### BREAKING CHANGE diff --git a/README.md b/README.md index 68c1f975..a58c46fc 100644 --- a/README.md +++ b/README.md @@ -73,14 +73,146 @@ module.exports = { ## Options -### `publicPath` +### Plugin Options + +| Name | Type | Default | Description | +| :-----------------------------------: | :------------------: | :------------------------------------------------------------------------------: | :------------------------------------------------------- | +| **[`filename`](#filename)** | `{String\|Function}` | `[name].css` | This option determines the name of each output CSS file | +| **[`chunkFilename`](#chunkFilename)** | `{String\|Function}` | `based on filename` | This option determines the name of non-entry chunk files | +| **[`ignoreOrder`](#ignoreOrder)** | `{Boolean}` | `false` | Remove Order Warnings | +| **[`insert`](#insert)** | `{String\|Function}` | `var head = document.getElementsByTagName("head")[0];head.appendChild(linkTag);` | Inserts `` at the given position | +| **[`attributes`](#attributes)** | `{Object}` | `{}` | Adds custom attributes to tag | + +#### `filename` + +Type: `String|Function` +Default: `[name].css` + +This option determines the name of each output CSS file. + +Works like [`output.filename`](https://webpack.js.org/configuration/output/#outputfilename) + +#### `chunkFilename` + +Type: `String|Function` +Default: `based on filename` + +> i Specifying `chunkFilename` as a `function` is only available in webpack@5 + +This option determines the name of non-entry chunk files. + +Works like [`output.chunkFilename`](https://webpack.js.org/configuration/output/#outputchunkfilename) + +#### `ignoreOrder` + +Type: `Boolean` +Default: `false` + +Remove Order Warnings. +See [examples](#remove-order-warnings) below for details. + +#### `insert` + +Type: `String|Function` +Default: `var head = document.getElementsByTagName("head")[0]; head.appendChild(linkTag);` + +By default, the `extract-css-chunks-plugin` appends styles (`` elements) to `document.head` of the current `window`. + +However in some circumstances it might be necessary to have finer control over the append target or even delay `link` elements instertion. +For example this is the case when you asynchronously load styles for an application that runs inside of an iframe. +In such cases `insert` can be configured to be a function or a custom selector. + +If you target an [iframe](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement) make sure that the parent document has sufficient access rights to reach into the frame document and append elements to it. + +##### `String` + +Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector). +A new `` element will be inserted after the found item. + +**webpack.config.js** + +```js +new MiniCssExtractPlugin({ + insert: '#some-element', +}); +``` + +A new `` element will be inserted after the element with id `some-element`. + +##### `Function` + +Allows to override default behavior and insert styles at any position. + +> ⚠ Do not forget that this code will run in the browser alongside your application. Since not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc we recommend you to use only ECMA 5 features and syntax. + +> > ⚠ The `insert` function is serialized to string and passed to the plugin. This means that it won't have access to the scope of the webpack configuration module. + +**webpack.config.js** + +```js +new MiniCssExtractPlugin({ + insert: function (linkTag) { + var reference = document.querySelector('#some-element'); + if (reference) { + reference.parentNode.insertBefore(linkTag, reference); + } + }, +}); +``` + +A new `` element will be inserted before the element with id `some-element`. + +#### `attributes` + +Type: `Object` +Default: `{}` + +If defined, the `mini-css-extract-plugin` will attach given attributes with their values on element. + +**webpack.config.js** + +```js +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + +module.exports = { + plugins: [ + new MiniCssExtractPlugin({ + attributes: { + id: 'target', + 'data-target': 'example', + }, + }), + ], + module: { + rules: [ + { + test: /\.css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader'], + }, + ], + }, +}; +``` + +Note: It's only applied to dynamically loaded css chunks, if you want to modify link attributes inside html file, please using [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) + +### Loader Options + +| Name | Type | Default | Description | +| :-----------------------------: | :------------------: | :--------------------------------: | :-------------------------------------------------------------------------------- | +| **[`publicPath`](#publicPath)** | `{String\|Function}` | `webpackOptions.output.publicPath` | Specifies a custom public path for the external resources like images, files, etc | +| **[`esModule`](#esModule)** | `{Boolean}` | `true` | Use ES modules syntax | +| **[`modules`](#modules)** | `{Object}` | `undefined` | Configuration CSS Modules | + +#### `publicPath` Type: `String|Function` Default: the `publicPath` in `webpackOptions.output` -Specifies a custom public path for the target file(s). +Specifies a custom public path for the external resources like images, files, etc inside `CSS`. +Works like [`output.publicPath`](https://webpack.js.org/configuration/output/#outputpublicpath) -#### `String` +##### `String` **webpack.config.js** @@ -115,7 +247,7 @@ module.exports = { }; ``` -#### `Function` +##### `Function` **webpack.config.js** @@ -152,7 +284,7 @@ module.exports = { }; ``` -### `esModule` +#### `esModule` Type: `Boolean` Default: `true` @@ -188,14 +320,14 @@ module.exports = { }; ``` -### `modules` +#### `modules` Type: `Object` Default: `undefined` Configuration CSS Modules. -#### `namedExport` +##### `namedExport` Type: `Boolean` Default: `false` @@ -307,6 +439,43 @@ module.exports = { }; ``` +### Common use case + +`mini-css-extract-plugin` is more often used in `production` mode to get separate css files. +For `development` mode (including `webpack-dev-server`) you can use `style-loader`, because it injects CSS into the DOM using multiple and works faster. + +> i Do not use together `style-loader` and `mini-css-extract-plugin`. + +**webpack.config.js** + +```js +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const devMode = process.env.NODE_ENV !== 'production'; + +const plugins = []; +if (!devMode) { + // enable in production only + plugins.push(new MiniCssExtractPlugin()); +} + +module.exports = { + plugins, + module: { + rules: [ + { + test: /\.(sa|sc|c)ss$/, + use: [ + devMode ? 'style-loader' : MiniCssExtractPlugin.loader, + 'css-loader', + 'postcss-loader', + 'sass-loader', + ], + }, + ], + }, +}; +``` + ### The `publicPath` option as function **webpack.config.js** @@ -349,7 +518,7 @@ module.exports = { ### 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`. +This plugin should not be used with `style-loader` in the loaders chain. Here is an example to have both HMR in `development` and your styles extracted in a file for `production` builds. @@ -369,8 +538,8 @@ 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', + filename: devMode ? '[name].css' : '[name].[contenthash].css', + chunkFilename: devMode ? '[id].css' : '[id].[contenthash].css', }), ]; if (devMode) { @@ -417,8 +586,8 @@ 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', + filename: devMode ? '[name].css' : '[name].[contenthash].css', + chunkFilename: devMode ? '[id].css' : '[id].[contenthash].css', }), ]; if (devMode) { @@ -447,20 +616,15 @@ module.exports = { ### 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: +To minify the output, use a plugin like [css-minimizer-webpack-plugin](https://github.com/webpack-contrib/css-minimizer-webpack-plugin). **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'); +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); module.exports = { - optimization: { - minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], - }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', @@ -475,9 +639,18 @@ module.exports = { }, ], }, + optimization: { + minimizer: [ + // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line + // `...` + new CssMinimizerPlugin(), + ], + }, }; ``` +This will enable CSS optimization only in production mode. If you want to run it also in development set the `optimization.minimize` option to true. + ### Using preloaded or inlined CSS The runtime code detects already added CSS via `` or ` + +
+