diff --git a/README.md b/README.md index 3c570d29..7b941115 100644 --- a/README.md +++ b/README.md @@ -51,10 +51,9 @@ module.exports = { plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output - // all options are optional + // both options are optional filename: '[name].css', chunkFilename: '[id].css', - ignoreOrder: false, // Enable to remove warnings about conflicting order }), ], module: { @@ -203,6 +202,46 @@ module.exports = { }; ``` +#### `esModules` + +Type: `boolean` +Default: `false` + +By default, extract-mini-css-plugin generates JS modules that use the CommonJS syntax. However, there are some +cases in which using ES2015 modules is more 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/). + +**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: { + esModules: true, + }, + }, + '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: @@ -359,13 +398,7 @@ For long term caching use `filename: "[contenthash].css"`. Optionally add `[name ### Remove Order Warnings -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. - -```javascript -new MiniCssExtractPlugin({ - ignoreOrder: true, -}), -``` +If the terminal is getting bloated with chunk order warnings. You can filter by configuring [warningsFilter](https://webpack.js.org/configuration/stats/) withing the webpack stats option ### Media Query Plugin diff --git a/src/loader.js b/src/loader.js index a91dd787..a24bbdba 100644 --- a/src/loader.js +++ b/src/loader.js @@ -181,9 +181,14 @@ export function pitch(request) { return callback(e); } + const esModules = + typeof options.esModules === 'boolean' && options.esModules === true; + let resultSource = `// extracted by ${pluginName}`; const result = locals - ? `\nmodule.exports = ${JSON.stringify(locals)};` + ? `\n${ + esModules ? 'export default ' : 'module.exports = ' + }${JSON.stringify(locals)};` : ''; resultSource += options.hmr diff --git a/test/__snapshots__/esModules-options.test.js.snap b/test/__snapshots__/esModules-options.test.js.snap new file mode 100644 index 00000000..8f224123 --- /dev/null +++ b/test/__snapshots__/esModules-options.test.js.snap @@ -0,0 +1,6 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EsModules should generate ES6 modules 1`] = ` +"// extracted by mini-css-extract-plugin +export default {\\"test\\":\\"MHBvAShXnAxWEC-jxsBd\\"};" +`; diff --git a/test/cases/esModules/expected/main.css b/test/cases/esModules/expected/main.css new file mode 100644 index 00000000..93de9fed --- /dev/null +++ b/test/cases/esModules/expected/main.css @@ -0,0 +1,8 @@ +body { + background: red; +} + +.MHBvAShXnAxWEC-jxsBd { + color: black; +} + diff --git a/test/cases/esModules/index.js b/test/cases/esModules/index.js new file mode 100644 index 00000000..a517631c --- /dev/null +++ b/test/cases/esModules/index.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +import styles from './style.css'; diff --git a/test/cases/esModules/style.css b/test/cases/esModules/style.css new file mode 100644 index 00000000..e30e2a84 --- /dev/null +++ b/test/cases/esModules/style.css @@ -0,0 +1,7 @@ +body { + background: red; +} + +.test { + color: black; +} diff --git a/test/cases/esModules/webpack.config.js b/test/cases/esModules/webpack.config.js new file mode 100644 index 00000000..dcc44437 --- /dev/null +++ b/test/cases/esModules/webpack.config.js @@ -0,0 +1,31 @@ +import Self from '../../../src'; + +module.exports = { + entry: './index.js', + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: Self.loader, + options: { + esModules: true, + }, + }, + { + loader: 'css-loader', + options: { + modules: true, + }, + }, + ], + }, + ], + }, + plugins: [ + new Self({ + filename: '[name].css', + }), + ], +}; diff --git a/test/esModules-options.test.js b/test/esModules-options.test.js new file mode 100644 index 00000000..19150205 --- /dev/null +++ b/test/esModules-options.test.js @@ -0,0 +1,34 @@ +import path from 'path'; + +import webpack from 'webpack'; + +describe('EsModules', () => { + it('should generate ES6 modules', (done) => { + const casesDirectory = path.resolve(__dirname, 'cases'); + const directoryForCase = path.resolve(casesDirectory, 'esModules'); + // eslint-disable-next-line import/no-dynamic-require, global-require + const webpackConfig = require(path.resolve( + directoryForCase, + 'webpack.config.js' + )); + const compiler = webpack({ + ...webpackConfig, + mode: 'development', + context: directoryForCase, + cache: false, + }); + + compiler.run((err1, stats) => { + const { modules } = stats.toJson(); + let foundModule = false; + modules.forEach((module) => { + if (module.name === './style.css') { + foundModule = true; + expect(module.source).toMatchSnapshot(); + } + }); + expect(foundModule).toBe(true); + done(); + }); + }); +});