From 552b1853701542a40de48a9c292eadf68681f36a Mon Sep 17 00:00:00 2001 From: LaySent Date: Wed, 20 Nov 2019 22:31:06 +0800 Subject: [PATCH] feat: improve warning of conflict order --- src/index.js | 42 ++++++++++++++++--------- test/TestCases.test.js | 14 +++++++++ test/cases/ignoreOrderFalse/warnings.js | 10 ++++++ 3 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 test/cases/ignoreOrderFalse/warnings.js diff --git a/src/index.js b/src/index.js index cec08e21..58b6d951 100644 --- a/src/index.js +++ b/src/index.js @@ -90,12 +90,7 @@ class CssModule extends webpack.Module { } class CssModuleFactory { - create( - { - dependencies: [dependency], - }, - callback - ) { + create({ dependencies: [dependency] }, callback) { callback(null, new CssModule(dependency)); } } @@ -416,6 +411,9 @@ class MiniCssExtractPlugin { if (typeof chunkGroup.getModuleIndex2 === 'function') { // Store dependencies for modules const moduleDependencies = new Map(modules.map((m) => [m, new Set()])); + const moduleDependenciesReasons = new Map( + modules.map((m) => [m, new Map()]) + ); // Get ordered list of modules per chunk group // This loop also gathers dependencies from the ordered lists @@ -435,9 +433,14 @@ class MiniCssExtractPlugin { for (let i = 0; i < sortedModules.length; i++) { const set = moduleDependencies.get(sortedModules[i]); + const reasons = moduleDependenciesReasons.get(sortedModules[i]); for (let j = i + 1; j < sortedModules.length; j++) { - set.add(sortedModules[j]); + const module = sortedModules[j]; + set.add(module); + const reason = reasons.get(module) || new Set(); + reason.add(cg); + reasons.set(module, reason); } } @@ -453,6 +456,7 @@ class MiniCssExtractPlugin { let success = false; let bestMatch; let bestMatchDeps; + let bestMatchDepsReasons; // get first module where dependencies are fulfilled for (const list of modulesByChunkGroup) { @@ -472,6 +476,7 @@ class MiniCssExtractPlugin { if (!bestMatchDeps || bestMatchDeps.length > failedDeps.length) { bestMatch = list; bestMatchDeps = failedDeps; + bestMatchDepsReasons = moduleDependenciesReasons.get(module); } if (failedDeps.length === 0) { @@ -491,14 +496,21 @@ class MiniCssExtractPlugin { if (!this.options.ignoreOrder) { compilation.warnings.push( new Error( - `chunk ${chunk.name || chunk.id} [${pluginName}]\n` + - 'Conflicting order between:\n' + - ` * ${fallbackModule.readableIdentifier( - requestShortener - )}\n` + - `${bestMatchDeps - .map((m) => ` * ${m.readableIdentifier(requestShortener)}`) - .join('\n')}` + [ + `chunk ${chunk.name || chunk.id} [${pluginName}]`, + 'Following module has been added:', + ` * ${fallbackModule.readableIdentifier(requestShortener)}`, + "while this module as dependencies that haven't been added before:", + ...bestMatchDeps.map((m) => + [ + ` * ${m.readableIdentifier(requestShortener)}`, + `(used previous to added module in chunk ${Array.from( + bestMatchDepsReasons.get(m), + (cg) => cg.name + ).join(',')})`, + ].join(' ') + ), + ].join('\n') ) ); } diff --git a/test/TestCases.test.js b/test/TestCases.test.js index caae878e..60f2dd15 100644 --- a/test/TestCases.test.js +++ b/test/TestCases.test.js @@ -25,6 +25,13 @@ function compareDirectory(actual, expected) { } } +function compareWarning(actual, expectedFile) { + if (!fs.existsSync(expectedFile)) return; + + const expected = require(expectedFile); // eslint-disable-line global-require,import/no-dynamic-require + expect(actual).toBe(expected); +} + describe('TestCases', () => { const casesDirectory = path.resolve(__dirname, 'cases'); const outputDirectory = path.resolve(__dirname, 'js'); @@ -93,6 +100,13 @@ describe('TestCases', () => { compareDirectory(outputDirectoryForCase, expectedDirectory); + const expectedWarning = path.resolve(directoryForCase, 'warnings.js'); + const actualWarning = stats.toString({ + all: false, + warnings: true, + }); + compareWarning(actualWarning, expectedWarning); + done(); }); }, 10000); diff --git a/test/cases/ignoreOrderFalse/warnings.js b/test/cases/ignoreOrderFalse/warnings.js new file mode 100644 index 00000000..9bdd5fb5 --- /dev/null +++ b/test/cases/ignoreOrderFalse/warnings.js @@ -0,0 +1,10 @@ +const cssLoaderPath = require.resolve('css-loader'); + +module.exports = [ + '', + 'WARNING in chunk styles [mini-css-extract-plugin]', + 'Following module has been added:', + ` * css ${cssLoaderPath}!./e2.css`, + "while this module as dependencies that haven't been added before:", + ` * css ${cssLoaderPath}!./e1.css (used previous to added module in chunk entry2)`, +].join('\n');