diff --git a/package-lock.json b/package-lock.json index 734f5f26..46110843 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "requires": true, "packages": { "": { - "version": "1.3.6", + "version": "1.3.7", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", diff --git a/src/index.js b/src/index.js index a30914fb..73c34458 100644 --- a/src/index.js +++ b/src/index.js @@ -280,6 +280,8 @@ class MiniCssExtractPlugin { baseDataPath: 'options', }); + this._sortedModulesCache = new WeakMap(); + this.options = Object.assign( { filename: DEFAULT_FILENAME, ignoreOrder: false }, options @@ -535,7 +537,15 @@ class MiniCssExtractPlugin { ? Array.from(this.getChunkModules(chunk, chunkGraph)).filter( (module) => module.type === MODULE_TYPE ) - : chunkGraph.getChunkModulesIterableBySourceType(chunk, MODULE_TYPE); + : this.sortModules( + compilation, + chunk, + chunkGraph.getChunkModulesIterableBySourceType( + chunk, + MODULE_TYPE + ), + compilation.runtimeTemplate.requestShortener + ); if (modules) { const { hashFunction, hashDigest, hashDigestLength } = outputOptions; @@ -1076,8 +1086,14 @@ class MiniCssExtractPlugin { return obj; } - renderContentAsset(compiler, compilation, chunk, modules, requestShortener) { - let usedModules; + sortModules(compilation, chunk, modules, requestShortener) { + let usedModules = this._sortedModulesCache.get(chunk); + + if (usedModules || !modules) { + return usedModules; + } + + modules = [...modules]; const [chunkGroup] = chunk.groupsIterable; const moduleIndexFunctionName = @@ -1215,6 +1231,19 @@ class MiniCssExtractPlugin { usedModules = modules; } + this._sortedModulesCache.set(chunk, usedModules); + + return usedModules; + } + + renderContentAsset(compiler, compilation, chunk, modules, requestShortener) { + const usedModules = this.sortModules( + compilation, + chunk, + modules, + requestShortener + ); + // TODO remove after drop webpack v4 const { ConcatSource, SourceMapSource, RawSource } = compiler.webpack ? compiler.webpack.sources diff --git a/test/TestCache.test.js b/test/TestCache.test.js index d488b5e0..ed192cfe 100644 --- a/test/TestCache.test.js +++ b/test/TestCache.test.js @@ -167,7 +167,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler1.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -207,7 +209,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler2.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -274,7 +278,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler1.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -316,7 +322,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler2.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -385,7 +393,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler1.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -428,7 +438,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler2.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -497,7 +509,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler1.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -540,7 +554,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler2.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); diff --git a/test/cases/content-entries-with-same-import/expected/1.a2e2caac15fbc316194f.css b/test/cases/content-entries-with-same-import/expected/1.a2e2caac15fbc316194f.css new file mode 100644 index 00000000..f6a43c7e --- /dev/null +++ b/test/cases/content-entries-with-same-import/expected/1.a2e2caac15fbc316194f.css @@ -0,0 +1,8 @@ +.a { + width: 100px; +} + +.b { + width: 100px; +} + diff --git a/test/cases/content-entries-with-same-import/expected/2.b93278edf8733a516ab1.css b/test/cases/content-entries-with-same-import/expected/2.b93278edf8733a516ab1.css new file mode 100644 index 00000000..c40231b8 --- /dev/null +++ b/test/cases/content-entries-with-same-import/expected/2.b93278edf8733a516ab1.css @@ -0,0 +1,8 @@ +.b { + width: 100px; +} + +.a { + width: 100px; +} + diff --git a/test/cases/content-entries-with-same-import/index.js b/test/cases/content-entries-with-same-import/index.js new file mode 100644 index 00000000..f3b5f43e --- /dev/null +++ b/test/cases/content-entries-with-same-import/index.js @@ -0,0 +1,7 @@ +const app1 = import('./one'); +const app2 = import('./two'); + +// eslint-disable-next-line no-console +console.log(app1); +// eslint-disable-next-line no-console +console.log(app2); diff --git a/test/cases/content-entries-with-same-import/one.js b/test/cases/content-entries-with-same-import/one.js new file mode 100644 index 00000000..f9f16b34 --- /dev/null +++ b/test/cases/content-entries-with-same-import/one.js @@ -0,0 +1,4 @@ +import './style1.css'; +import './style2.css'; + +export default 'one'; diff --git a/test/cases/content-entries-with-same-import/style1.css b/test/cases/content-entries-with-same-import/style1.css new file mode 100644 index 00000000..6e0b4761 --- /dev/null +++ b/test/cases/content-entries-with-same-import/style1.css @@ -0,0 +1,3 @@ +.a { + width: 100px; +} diff --git a/test/cases/content-entries-with-same-import/style2.css b/test/cases/content-entries-with-same-import/style2.css new file mode 100644 index 00000000..16518354 --- /dev/null +++ b/test/cases/content-entries-with-same-import/style2.css @@ -0,0 +1,3 @@ +.b { + width: 100px; +} diff --git a/test/cases/content-entries-with-same-import/test.filter.js b/test/cases/content-entries-with-same-import/test.filter.js new file mode 100644 index 00000000..042a0256 --- /dev/null +++ b/test/cases/content-entries-with-same-import/test.filter.js @@ -0,0 +1,3 @@ +const webpack = require('webpack'); + +module.exports = () => webpack.version[0] !== '4'; diff --git a/test/cases/content-entries-with-same-import/two.js b/test/cases/content-entries-with-same-import/two.js new file mode 100644 index 00000000..ea6f0b50 --- /dev/null +++ b/test/cases/content-entries-with-same-import/two.js @@ -0,0 +1,4 @@ +import './style2.css'; +import './style1.css'; + +export default 'two'; diff --git a/test/cases/content-entries-with-same-import/webpack.config.js b/test/cases/content-entries-with-same-import/webpack.config.js new file mode 100644 index 00000000..b317ec1c --- /dev/null +++ b/test/cases/content-entries-with-same-import/webpack.config.js @@ -0,0 +1,21 @@ +import Self from '../../../src'; + +module.exports = { + entry: './index.js', + module: { + rules: [ + { + test: /\.css$/, + use: [Self.loader, 'css-loader'], + }, + ], + }, + output: { + filename: '[name].[contenthash].js', + }, + plugins: [ + new Self({ + filename: '[name].[contenthash].css', + }), + ], +};