From 9352ebc05368b9e0fbe69b357d9cc69c649a2a23 Mon Sep 17 00:00:00 2001 From: Josep del Rio Date: Sat, 20 Jul 2019 21:34:22 +0100 Subject: [PATCH 1/4] feat: add option to use ES2015 module syntax --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++----------- src/loader.js | 6 +++--- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3c570d29..8a6b46b7 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: @@ -349,8 +388,8 @@ With the `moduleFilename` option you can use chunk data to customize the filenam ```javascript const miniCssExtractPlugin = new MiniCssExtractPlugin({ - moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css`, -}); + moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css` +}) ``` #### Long Term Caching @@ -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..d8e3c0b4 100644 --- a/src/loader.js +++ b/src/loader.js @@ -181,10 +181,10 @@ 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)};` - : ''; + const result = locals ? `\n${esModules ? 'export default ' : 'module.exports = '}${JSON.stringify(locals)};` : ''; resultSource += options.hmr ? hotLoader(result, { context: this.context, options, locals }) From a1812c40883ef7a169b39a66aa16a1fe70ba0afb Mon Sep 17 00:00:00 2001 From: Josep del Rio Date: Sat, 20 Jul 2019 23:22:46 +0100 Subject: [PATCH 2/4] style: run prettify --- README.md | 4 ++-- src/loader.js | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8a6b46b7..7b941115 100644 --- a/README.md +++ b/README.md @@ -388,8 +388,8 @@ With the `moduleFilename` option you can use chunk data to customize the filenam ```javascript const miniCssExtractPlugin = new MiniCssExtractPlugin({ - moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css` -}) + moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css`, +}); ``` #### Long Term Caching diff --git a/src/loader.js b/src/loader.js index d8e3c0b4..a24bbdba 100644 --- a/src/loader.js +++ b/src/loader.js @@ -181,10 +181,15 @@ export function pitch(request) { return callback(e); } - const esModules = typeof options.esModules === 'boolean' && options.esModules === true; + const esModules = + typeof options.esModules === 'boolean' && options.esModules === true; let resultSource = `// extracted by ${pluginName}`; - const result = locals ? `\n${esModules ? 'export default ' : 'module.exports = '}${JSON.stringify(locals)};` : ''; + const result = locals + ? `\n${ + esModules ? 'export default ' : 'module.exports = ' + }${JSON.stringify(locals)};` + : ''; resultSource += options.hmr ? hotLoader(result, { context: this.context, options, locals }) From 16aac80f338e1a3d6e6af48abac1fb414b402747 Mon Sep 17 00:00:00 2001 From: Josep del Rio Date: Sat, 27 Jul 2019 20:09:11 -0400 Subject: [PATCH 3/4] test: added tests --- .../esModules-options.test.js.snap | 6 ++++ test/cases/esModules/expected/main.css | 7 ++++ test/cases/esModules/index.js | 2 ++ test/cases/esModules/style.css | 7 ++++ test/cases/esModules/webpack.config.js | 31 +++++++++++++++++ test/esModules-options.test.js | 34 +++++++++++++++++++ 6 files changed, 87 insertions(+) create mode 100644 test/__snapshots__/esModules-options.test.js.snap create mode 100644 test/cases/esModules/expected/main.css create mode 100644 test/cases/esModules/index.js create mode 100644 test/cases/esModules/style.css create mode 100644 test/cases/esModules/webpack.config.js create mode 100644 test/esModules-options.test.js 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..e30e2a84 --- /dev/null +++ b/test/cases/esModules/expected/main.css @@ -0,0 +1,7 @@ +body { + background: red; +} + +.test { + 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(); + }); + }); +}); From ceccf1f3721cce17d7dd241a663e28fa6fbbcd1a Mon Sep 17 00:00:00 2001 From: Josep del Rio Date: Sat, 27 Jul 2019 20:17:05 -0400 Subject: [PATCH 4/4] test: fix test expected result --- test/cases/esModules/expected/main.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/cases/esModules/expected/main.css b/test/cases/esModules/expected/main.css index e30e2a84..93de9fed 100644 --- a/test/cases/esModules/expected/main.css +++ b/test/cases/esModules/expected/main.css @@ -2,6 +2,7 @@ body { background: red; } -.test { +.MHBvAShXnAxWEC-jxsBd { color: black; } +