diff --git a/src/loader.js b/src/loader.js index 619c48d3..17bf97c8 100644 --- a/src/loader.js +++ b/src/loader.js @@ -209,6 +209,8 @@ export function pitch(request) { ? `\n${esModule ? 'export default' : 'module.exports ='} ${JSON.stringify( locals )};` + : esModule + ? `\nexport {};` : ''; let resultSource = `// extracted by ${pluginName}`; diff --git a/test/enforce-esm.test.js b/test/enforce-esm.test.js new file mode 100644 index 00000000..57795488 --- /dev/null +++ b/test/enforce-esm.test.js @@ -0,0 +1,36 @@ +import { getCompiler, source, compile } from './helpers'; + +it('should enforce esm for empty module with options.esModule', async (done) => { + const compiler = getCompiler( + './esm.js', + { esModule: true }, + { + mode: 'production', + optimization: { minimize: false }, + } + ); + const stats = await compile(compiler); + expect(stats.hasErrors()).toBe(false); + expect(source('./simple.css', stats)).toMatchInlineSnapshot(` + "// extracted by mini-css-extract-plugin + export {};" + `); + done(); +}); + +it('should keep empty module without options.esModule', async (done) => { + const compiler = getCompiler( + './esm.js', + {}, + { + mode: 'production', + optimization: { minimize: false }, + } + ); + const stats = await compile(compiler); + expect(stats.hasErrors()).toBe(false); + expect(source('./simple.css', stats)).toMatchInlineSnapshot( + `"// extracted by mini-css-extract-plugin"` + ); + done(); +}); diff --git a/test/fixtures/esm.js b/test/fixtures/esm.js new file mode 100644 index 00000000..1a4074dd --- /dev/null +++ b/test/fixtures/esm.js @@ -0,0 +1 @@ +import "./simple.css"; diff --git a/test/helpers/getCompiler.js b/test/helpers/getCompiler.js index ef29941e..9283da6f 100644 --- a/test/helpers/getCompiler.js +++ b/test/helpers/getCompiler.js @@ -6,9 +6,11 @@ import { createFsFromVolume, Volume } from 'memfs'; import MiniCssExtractPlugin from '../../src'; export default (fixture, loaderOptions = {}, config = {}) => { + const { outputFileSystem, ...cnfg } = config; + const fullConfig = { mode: 'development', - devtool: config.devtool || false, + devtool: cnfg.devtool || false, context: path.resolve(__dirname, '../fixtures'), entry: path.resolve(__dirname, '../fixtures', fixture), output: { @@ -40,16 +42,18 @@ export default (fixture, loaderOptions = {}, config = {}) => { chunkFilename: '[id].css', }), ], - ...config, + ...cnfg, }; const compiler = webpack(fullConfig); - if (!config.outputFileSystem) { - const outputFileSystem = createFsFromVolume(new Volume()); + if (!outputFileSystem) { + const outputFS = createFsFromVolume(new Volume()); // Todo remove when we drop webpack@4 support - outputFileSystem.join = path.join.bind(path); + outputFS.join = path.join.bind(path); + compiler.outputFileSystem = outputFS; + } else { compiler.outputFileSystem = outputFileSystem; } diff --git a/test/helpers/index.js b/test/helpers/index.js index f0ad1bae..1446ee47 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -1,4 +1,5 @@ import compile from './compile'; import getCompiler from './getCompiler'; +import source from './source'; -export { compile, getCompiler }; +export { source, compile, getCompiler }; diff --git a/test/helpers/source.js b/test/helpers/source.js new file mode 100644 index 00000000..38b19379 --- /dev/null +++ b/test/helpers/source.js @@ -0,0 +1,19 @@ +export default function getSource(name, stats) { + const { modules } = stats.toJson({ source: true }); + + for (let i = 0; i < modules.length; i++) { + const module = modules[i]; + + if (module.modules && module.modules.length > 0) { + for (let j = 0; j < module.modules.length; j++) { + if (module.modules[j].name === name) { + return module.modules[j].source; + } + } + } else if (module.name === name) { + return module.source; + } + } + + return undefined; +}