From 75895bb8971eeed54d3c736f53f9419affb19b48 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Sat, 1 Aug 2020 19:36:40 +0300 Subject: [PATCH 1/7] docs: fix changelog --- CHANGELOG.md | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ee2347..195b1fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,37 +1,7 @@ # Changelog -All notable changes to this project will be documented in this file. +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 1.0.3 - 2020-04-07 - -### Dependencies - -Update dev dependencies: - -- acorn@5.7.4 (#2) - -## 1.0.2 - 2020-02-12 - -### Dependencies - -Update dev dependencies: - -- handlebars@4.5.3 (#1) - -## 1.0.1 - 2019-12-17 - -### Dependencies - -Update dev dependencies: - -- webpack@4.41.3 ([security fix](https://github.com/webpack/webpack/releases/tag/v4.41.3)) -- mini-css-extract-plugin@0.8.2 -- node-sass@4.13.0 -- css-loader@3.4.0 - -## 1.0.0 - 2019-09-01 +## 1.0.0 - 2020-08-01 Initial release From 997e00f66298219dccfdff8c01c71bebc973df49 Mon Sep 17 00:00:00 2001 From: Alexey Lavinsky Date: Mon, 3 Aug 2020 20:01:41 +0300 Subject: [PATCH 2/7] fix: compatibility cache feature with webpack@5 (#16) --- .gitignore | 3 +- src/Webpack4Cache.js | 10 +- src/Webpack5Cache.js | 69 +----- src/index.js | 5 + .../cache-option.test.js.snap.webpack5 | 85 ++++++++ test/cache-option.test.js | 199 +++++++++++++++++- test/helpers/getCompiler.js | 1 - 7 files changed, 306 insertions(+), 66 deletions(-) create mode 100644 test/__snapshots__/cache-option.test.js.snap.webpack5 diff --git a/.gitignore b/.gitignore index f2ff349..ef12a3a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,9 +10,10 @@ npm-debug.log* /local /reports /node_modules +/test/outputs/ .DS_Store Thumbs.db .idea *.iml *.sublime-project -*.sublime-workspace \ No newline at end of file +*.sublime-workspace diff --git a/src/Webpack4Cache.js b/src/Webpack4Cache.js index 3384f80..121cfe9 100644 --- a/src/Webpack4Cache.js +++ b/src/Webpack4Cache.js @@ -22,16 +22,16 @@ export default class Webpack4Cache { return Boolean(this.cacheDir); } - get(task) { + async get(task) { // eslint-disable-next-line no-param-reassign task.cacheIdent = task.cacheIdent || serialize(task.cacheKeys); - return cacache - .get(this.cacheDir, task.cacheIdent) - .then(({ data }) => JSON.parse(data)); + const { data } = await cacache.get(this.cacheDir, task.cacheIdent); + + return JSON.parse(data); } - store(task, data) { + async store(task, data) { return cacache.put(this.cacheDir, task.cacheIdent, JSON.stringify(data)); } } diff --git a/src/Webpack5Cache.js b/src/Webpack5Cache.js index 6f49e2d..897a938 100644 --- a/src/Webpack5Cache.js +++ b/src/Webpack5Cache.js @@ -1,75 +1,28 @@ -// eslint-disable-next-line import/extensions,import/no-unresolved -import getLazyHashedEtag from 'webpack/lib/cache/getLazyHashedEtag'; import serialize from 'serialize-javascript'; -import { util } from 'webpack'; - export default class Cache { // eslint-disable-next-line no-unused-vars constructor(compilation, ignored) { - this.compilation = compilation; + this.cache = compilation.getCache('CssMinimizerWebpackPlugin'); } + // eslint-disable-next-line class-methods-use-this isEnabled() { - return Boolean(this.compilation.cache); - } - - createCacheIdent(task) { - const { - outputOptions: { hashSalt, hashDigest, hashDigestLength, hashFunction }, - } = this.compilation; - - const hash = util.createHash(hashFunction); - - if (hashSalt) { - hash.update(hashSalt); - } - - hash.update(serialize(task.cacheKeys)); - - const digest = hash.digest(hashDigest); - const cacheKeys = digest.substr(0, hashDigestLength); - - return `${this.compilation.compilerPath}/CssMinimizerWebpackPlugin/${cacheKeys}/${task.file}`; + return true; } - get(task) { + async get(task) { // eslint-disable-next-line no-param-reassign - task.cacheIdent = task.cacheIdent || this.createCacheIdent(task); + task.cacheIdent = + task.cacheIdent || `${task.file}|${serialize(task.cacheKeys)}`; // eslint-disable-next-line no-param-reassign - task.cacheETag = task.cacheETag || getLazyHashedEtag(task.assetSource); + task.cacheETag = + task.cacheETag || this.cache.getLazyHashedEtag(task.assetSource); - return new Promise((resolve, reject) => { - this.compilation.cache.get( - task.cacheIdent, - task.cacheETag, - (err, result) => { - if (err) { - reject(err); - } else if (result) { - resolve(result); - } else { - reject(); - } - } - ); - }); + return this.cache.getPromise(task.cacheIdent, task.cacheETag); } - store(task, data) { - return new Promise((resolve, reject) => { - this.compilation.cache.store( - task.cacheIdent, - task.cacheETag, - data, - (err) => { - if (err) { - reject(err); - } else { - resolve(data); - } - } - ); - }); + async store(task, data) { + return this.cache.storePromise(task.cacheIdent, task.cacheETag, data); } } diff --git a/src/index.js b/src/index.js index 972fe1f..25cf36a 100644 --- a/src/index.js +++ b/src/index.js @@ -399,6 +399,11 @@ class CssMinimizerPlugin { return enqueue(task); } + // Webpack@5 return `undefined` when cache is not found + if (!taskResult) { + return enqueue(task); + } + task.callback(taskResult); return Promise.resolve(); diff --git a/test/__snapshots__/cache-option.test.js.snap.webpack5 b/test/__snapshots__/cache-option.test.js.snap.webpack5 new file mode 100644 index 0000000..d9b7165 --- /dev/null +++ b/test/__snapshots__/cache-option.test.js.snap.webpack5 @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`"cache" option should work with "false" value for the "cache" option: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`"cache" option should work with "false" value for the "cache" option: assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`"cache" option should work with "false" value for the "cache" option: errors 1`] = `Array []`; + +exports[`"cache" option should work with "false" value for the "cache" option: errors 2`] = `Array []`; + +exports[`"cache" option should work with "false" value for the "cache" option: warnings 1`] = `Array []`; + +exports[`"cache" option should work with "false" value for the "cache" option: warnings 2`] = `Array []`; + +exports[`"cache" option should work with "filesystem" value for the "cache.type" option: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`"cache" option should work with "filesystem" value for the "cache.type" option: assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`"cache" option should work with "filesystem" value for the "cache.type" option: errors 1`] = `Array []`; + +exports[`"cache" option should work with "filesystem" value for the "cache.type" option: errors 2`] = `Array []`; + +exports[`"cache" option should work with "filesystem" value for the "cache.type" option: warnings 1`] = `Array []`; + +exports[`"cache" option should work with "filesystem" value for the "cache.type" option: warnings 2`] = `Array []`; + +exports[`"cache" option should work with "memory" value for the "cache.type" option: assets 1`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`"cache" option should work with "memory" value for the "cache.type" option: assets 2`] = ` +Object { + "five.css": "body{color:red;font-size:20px}a{color:#00f}", + "four.css": "h1{color:green}h2{color:#ff0}", + "one.css": "a{text-align:center}", + "three.css": "body{color:red;font-size:20px}a{color:#00f}", + "two.css": "a{text-align:center}", +} +`; + +exports[`"cache" option should work with "memory" value for the "cache.type" option: errors 1`] = `Array []`; + +exports[`"cache" option should work with "memory" value for the "cache.type" option: errors 2`] = `Array []`; + +exports[`"cache" option should work with "memory" value for the "cache.type" option: warnings 1`] = `Array []`; + +exports[`"cache" option should work with "memory" value for the "cache.type" option: warnings 2`] = `Array []`; diff --git a/test/cache-option.test.js b/test/cache-option.test.js index 1a05e45..98e0728 100644 --- a/test/cache-option.test.js +++ b/test/cache-option.test.js @@ -1,3 +1,6 @@ +import path from 'path'; + +import del from 'del'; import cacache from 'cacache'; import findCacheDir from 'find-cache-dir'; @@ -323,5 +326,199 @@ if (getCompiler.isWebpack4()) { }); }); } else { - test.skip('skip it', () => {}); + describe('"cache" option', () => { + const fileSystemCacheDirectory = path.resolve( + __dirname, + './outputs/type-filesystem' + ); + + beforeAll(() => { + return Promise.all([del(fileSystemCacheDirectory)]); + }); + + it('should work with "false" value for the "cache" option', async () => { + const compiler = getCompiler({ + entry: { + one: `${__dirname}/fixtures/cache.js`, + two: `${__dirname}/fixtures/cache-1.js`, + three: `${__dirname}/fixtures/cache-2.js`, + four: `${__dirname}/fixtures/cache-3.js`, + five: `${__dirname}/fixtures/cache-4.js`, + }, + cache: false, + }); + + new CssMinimizerPlugin().apply(compiler); + + let getCounter = 0; + + compiler.cache.hooks.get.tap( + { name: 'TestCache', stage: -100 }, + (identifier) => { + if (identifier.indexOf('CssMinimizerWebpackPlugin') !== -1) { + getCounter += 1; + } + } + ); + + let storeCounter = 0; + + compiler.cache.hooks.store.tap( + { name: 'TestCache', stage: -100 }, + (identifier) => { + if (identifier.indexOf('CssMinimizerWebpackPlugin') !== -1) { + storeCounter += 1; + } + } + ); + + const stats = await compile(compiler); + + // Without cache webpack always try to get + expect(getCounter).toBe(5); + // Without cache webpack always try to store + expect(storeCounter).toBe(5); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + getCounter = 0; + storeCounter = 0; + + const newStats = await compile(compiler); + + // Without cache webpack always try to get + expect(getCounter).toBe(5); + // Without cache webpack always try to store + expect(storeCounter).toBe(5); + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(newStats)).toMatchSnapshot('errors'); + expect(getWarnings(newStats)).toMatchSnapshot('warnings'); + }); + + it('should work with "memory" value for the "cache.type" option', async () => { + const compiler = getCompiler({ + entry: { + one: `${__dirname}/fixtures/cache.js`, + two: `${__dirname}/fixtures/cache-1.js`, + three: `${__dirname}/fixtures/cache-2.js`, + four: `${__dirname}/fixtures/cache-3.js`, + five: `${__dirname}/fixtures/cache-4.js`, + }, + cache: { + type: 'memory', + }, + }); + + new CssMinimizerPlugin().apply(compiler); + + let getCounter = 0; + + compiler.cache.hooks.get.tap( + { name: 'TestCache', stage: -100 }, + (identifier) => { + if (identifier.indexOf('CssMinimizerWebpackPlugin') !== -1) { + getCounter += 1; + } + } + ); + + let storeCounter = 0; + + compiler.cache.hooks.store.tap( + { name: 'TestCache', stage: -100 }, + (identifier) => { + if (identifier.indexOf('CssMinimizerWebpackPlugin') !== -1) { + storeCounter += 1; + } + } + ); + + const stats = await compile(compiler); + + // Get cache for assets + expect(getCounter).toBe(5); + // Store cached assets + expect(storeCounter).toBe(5); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + getCounter = 0; + storeCounter = 0; + + const newStats = await compile(compiler); + + // Get cache for assets + expect(getCounter).toBe(5); + // No need to store, we got cached assets + expect(storeCounter).toBe(0); + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(newStats)).toMatchSnapshot('errors'); + expect(getWarnings(newStats)).toMatchSnapshot('warnings'); + }); + + it('should work with "filesystem" value for the "cache.type" option', async () => { + const compiler = getCompiler({ + entry: { + one: `${__dirname}/fixtures/cache.js`, + two: `${__dirname}/fixtures/cache-1.js`, + three: `${__dirname}/fixtures/cache-2.js`, + four: `${__dirname}/fixtures/cache-3.js`, + five: `${__dirname}/fixtures/cache-4.js`, + }, + cache: { + type: 'filesystem', + cacheDirectory: fileSystemCacheDirectory, + }, + }); + + new CssMinimizerPlugin().apply(compiler); + + let getCounter = 0; + + compiler.cache.hooks.get.tap( + { name: 'TestCache', stage: -100 }, + (identifier) => { + if (identifier.indexOf('CssMinimizerWebpackPlugin') !== -1) { + getCounter += 1; + } + } + ); + + let storeCounter = 0; + + compiler.cache.hooks.store.tap( + { name: 'TestCache', stage: -100 }, + (identifier) => { + if (identifier.indexOf('CssMinimizerWebpackPlugin') !== -1) { + storeCounter += 1; + } + } + ); + + const stats = await compile(compiler); + + // Get cache for assets + expect(getCounter).toBe(5); + // Store cached assets + expect(storeCounter).toBe(5); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + + getCounter = 0; + storeCounter = 0; + + const newStats = await compile(compiler); + + // Get cache for assets + expect(getCounter).toBe(5); + // No need to store, we got cached assets + expect(storeCounter).toBe(0); + expect(readAssets(compiler, newStats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(newStats)).toMatchSnapshot('errors'); + expect(getWarnings(newStats)).toMatchSnapshot('warnings'); + }); + }); } diff --git a/test/helpers/getCompiler.js b/test/helpers/getCompiler.js index f27d59f..3b439dd 100644 --- a/test/helpers/getCompiler.js +++ b/test/helpers/getCompiler.js @@ -11,7 +11,6 @@ export default function getCompiler(options) { cache: getCompiler.isWebpack4() ? false : { type: 'memory' }, optimization: { minimize: false, - noEmitOnErrors: false, }, output: { pathinfo: false, From 69c144c5521007cca29313b83de34d6ef327eafe Mon Sep 17 00:00:00 2001 From: Alexey Lavinsky Date: Tue, 4 Aug 2020 13:04:25 +0300 Subject: [PATCH 3/7] Tests refactor --- test/CssMinimizerPlugin.test.js | 15 +-- .../CssMinimizerPlugin.test.js.snap.webpack4 | 10 +- .../CssMinimizerPlugin.test.js.snap.webpack5 | 10 +- .../sourceMap-option.test.js.snap.webpack4 | 85 +++++++----- .../sourceMap-option.test.js.snap.webpack5 | 85 +++++++----- .../test-option.test.js.snap.webpack4 | 44 ++++--- .../test-option.test.js.snap.webpack5 | 44 ++++--- test/sourceMap-option.test.js | 121 +++++++++--------- test/test-option.test.js | 54 ++++---- 9 files changed, 271 insertions(+), 197 deletions(-) diff --git a/test/CssMinimizerPlugin.test.js b/test/CssMinimizerPlugin.test.js index 0c662c0..32991cc 100644 --- a/test/CssMinimizerPlugin.test.js +++ b/test/CssMinimizerPlugin.test.js @@ -39,7 +39,7 @@ describe('CssMinimizerPlugin', () => { afterEach(() => Promise.all([removeCache()])); - it('should respect the hash options #1', () => { + it('should respect the hash options #1', async () => { const compiler = getCompiler({ output: { pathinfo: false, @@ -61,16 +61,11 @@ describe('CssMinimizerPlugin', () => { }, }).apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - if (/\.js$/.test(file)) continue; - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } - }); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); it('should write stdout and stderr of workers to stdout and stderr of main process in parallel mode', async () => { diff --git a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 index 1eb3526..80bfccc 100644 --- a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 +++ b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 @@ -49,7 +49,15 @@ Array [ ] `; -exports[`CssMinimizerPlugin should respect the hash options #1: entry.css 1`] = `"a{text-align:center}"`; +exports[`CssMinimizerPlugin should respect the hash options #1: assets 1`] = ` +Object { + "entry.css": "a{text-align:center}", +} +`; + +exports[`CssMinimizerPlugin should respect the hash options #1: errors 1`] = `Array []`; + +exports[`CssMinimizerPlugin should respect the hash options #1: warnings 1`] = `Array []`; exports[`CssMinimizerPlugin should work with assets using querystring: entry.css.map?v=test 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,SACF,CACA,EACE,UACF\\",\\"file\\":\\"entry.css?v=test\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\na {\\\\n color: blue;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; diff --git a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 index 1eb3526..80bfccc 100644 --- a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 +++ b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 @@ -49,7 +49,15 @@ Array [ ] `; -exports[`CssMinimizerPlugin should respect the hash options #1: entry.css 1`] = `"a{text-align:center}"`; +exports[`CssMinimizerPlugin should respect the hash options #1: assets 1`] = ` +Object { + "entry.css": "a{text-align:center}", +} +`; + +exports[`CssMinimizerPlugin should respect the hash options #1: errors 1`] = `Array []`; + +exports[`CssMinimizerPlugin should respect the hash options #1: warnings 1`] = `Array []`; exports[`CssMinimizerPlugin should work with assets using querystring: entry.css.map?v=test 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,SACF,CACA,EACE,UACF\\",\\"file\\":\\"entry.css?v=test\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\na {\\\\n color: blue;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; diff --git a/test/__snapshots__/sourceMap-option.test.js.snap.webpack4 b/test/__snapshots__/sourceMap-option.test.js.snap.webpack4 index 79beb3e..197ec7f 100644 --- a/test/__snapshots__/sourceMap-option.test.js.snap.webpack4 +++ b/test/__snapshots__/sourceMap-option.test.js.snap.webpack4 @@ -1,56 +1,79 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: entry.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; - -exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: entry2.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center}", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center}", +} +`; -exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: entry.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: errors 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: entry2.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center}", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center}", +} `; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: errors 1`] = `Array []`; + +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry2.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry2.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry.css.map*/", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry2.css.map*/", +} `; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry.css.map*/" -`; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: errors 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry2.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry2.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry.css.map*/", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry2.css.map*/", +} `; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): dist/entry.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=https://example.com/project/sourcemaps/entry.css.map*/" -`; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: errors 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): dist/entry2.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=https://example.com/project/sourcemaps/entry2.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: warnings 1`] = `Array []`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): assets 1`] = ` +Object { + "dist/entry.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=https://example.com/project/sourcemaps/entry.css.map*/", + "dist/entry2.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=https://example.com/project/sourcemaps/entry2.css.map*/", +} `; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.scss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"dist/entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): errors 1`] = `Array []`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"dist/entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"dist/entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"dist/entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: error 1`] = ` +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: errors 1`] = ` Array [ "Error: broken-source-map.css from Css Minimizer Error: \\"version\\" is a required argument.", @@ -59,7 +82,7 @@ Error: broken-source-map.css from Css Minimizer", ] `; -exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: warning 1`] = ` +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: warnings 1`] = ` Array [ "Error: broken-source-map.css contains invalid source map", ] diff --git a/test/__snapshots__/sourceMap-option.test.js.snap.webpack5 b/test/__snapshots__/sourceMap-option.test.js.snap.webpack5 index 79beb3e..197ec7f 100644 --- a/test/__snapshots__/sourceMap-option.test.js.snap.webpack5 +++ b/test/__snapshots__/sourceMap-option.test.js.snap.webpack5 @@ -1,56 +1,79 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: entry.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; - -exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: entry2.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center}", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center}", +} +`; -exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: entry.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: errors 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: entry2.css 1`] = `"body{font-weight:700;color:red}body a{text-align:center}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, using previous sourcemap: warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center}", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center}", +} `; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: errors 1`] = `Array []`; + +exports[`when applied with "sourceMap" option matches snapshot for "false" value, without previous sourcemap: warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry2.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry2.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry.css.map*/", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry2.css.map*/", +} `; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry.css.map*/" -`; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: errors 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, using previous sourcemap: warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry2.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=entry2.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: assets 1`] = ` +Object { + "entry.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry.css.map*/", + "entry2.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=entry2.css.map*/", +} `; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): dist/entry.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=https://example.com/project/sourcemaps/entry.css.map*/" -`; +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: errors 1`] = `Array []`; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): dist/entry2.css 1`] = ` -"body{font-weight:700;color:red}body a{text-align:center} -/*# sourceMappingURL=https://example.com/project/sourcemaps/entry2.css.map*/" +exports[`when applied with "sourceMap" option matches snapshot for "true" value, without previous sourcemap: warnings 1`] = `Array []`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): assets 1`] = ` +Object { + "dist/entry.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=https://example.com/project/sourcemaps/entry.css.map*/", + "dist/entry2.css": "body{font-weight:700;color:red}body a{text-align:center} +/*# sourceMappingURL=https://example.com/project/sourcemaps/entry2.css.map*/", +} `; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.scss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"dist/entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): errors 1`] = `Array []`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"dist/entry.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; + +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"dist/entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; -exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): sourcemaps/entry2.css.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///./test/fixtures/sourcemap/bar.scss\\",\\"webpack:///./test/fixtures/sourcemap/foo.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,gBCEA,SDFiB,CCGlB,OAGC,iBAAkB\\",\\"file\\":\\"dist/entry2.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n}\\\\n\\\\nbody a {\\\\n text-align: center;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; +exports[`when applied with "sourceMap" option matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options): warnings 1`] = `Array []`; -exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: error 1`] = ` +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: errors 1`] = ` Array [ "Error: broken-source-map.css from Css Minimizer Error: \\"version\\" is a required argument.", @@ -59,7 +82,7 @@ Error: broken-source-map.css from Css Minimizer", ] `; -exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: warning 1`] = ` +exports[`when applied with "sourceMap" option should emit warning when broken sourcemap: warnings 1`] = ` Array [ "Error: broken-source-map.css contains invalid source map", ] diff --git a/test/__snapshots__/test-option.test.js.snap.webpack4 b/test/__snapshots__/test-option.test.js.snap.webpack4 index 6de26e2..39cc226 100644 --- a/test/__snapshots__/test-option.test.js.snap.webpack4 +++ b/test/__snapshots__/test-option.test.js.snap.webpack4 @@ -1,31 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; - -exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; - -exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): foo.css 1`] = ` -"a { +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): assets 1`] = ` +Object { + "bar1.css": "body{color:red;font-size:20px}a{color:#00f}", + "bar2.css": "h1{color:green}h2{color:#ff0}", + "foo.css": "a { text-align: center; } -" +", +} `; -exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): errors 1`] = `Array []`; -exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): warnings 1`] = `Array []`; -exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): foo.css 1`] = ` -"a { +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): assets 1`] = ` +Object { + "bar1.css": "body{color:red;font-size:20px}a{color:#00f}", + "bar2.css": "h1{color:green}h2{color:#ff0}", + "foo.css": "a { text-align: center; } -" +", +} `; -exports[`when applied with "test" option matches snapshot with empty value: bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): errors 1`] = `Array []`; + +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): warnings 1`] = `Array []`; + +exports[`when applied with "test" option matches snapshot with empty value: assets 1`] = ` +Object { + "bar1.css": "body{color:red;font-size:20px}a{color:#00f}", + "bar2.css": "h1{color:green}h2{color:#ff0}", + "foo.css": "a{text-align:center}", +} +`; -exports[`when applied with "test" option matches snapshot with empty value: bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; +exports[`when applied with "test" option matches snapshot with empty value: errors 1`] = `Array []`; -exports[`when applied with "test" option matches snapshot with empty value: foo.css 1`] = `"a{text-align:center}"`; +exports[`when applied with "test" option matches snapshot with empty value: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/test-option.test.js.snap.webpack5 b/test/__snapshots__/test-option.test.js.snap.webpack5 index 6de26e2..39cc226 100644 --- a/test/__snapshots__/test-option.test.js.snap.webpack5 +++ b/test/__snapshots__/test-option.test.js.snap.webpack5 @@ -1,31 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; - -exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; - -exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): foo.css 1`] = ` -"a { +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): assets 1`] = ` +Object { + "bar1.css": "body{color:red;font-size:20px}a{color:#00f}", + "bar2.css": "h1{color:green}h2{color:#ff0}", + "foo.css": "a { text-align: center; } -" +", +} `; -exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): errors 1`] = `Array []`; -exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; +exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): warnings 1`] = `Array []`; -exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): foo.css 1`] = ` -"a { +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): assets 1`] = ` +Object { + "bar1.css": "body{color:red;font-size:20px}a{color:#00f}", + "bar2.css": "h1{color:green}h2{color:#ff0}", + "foo.css": "a { text-align: center; } -" +", +} `; -exports[`when applied with "test" option matches snapshot with empty value: bar1.css 1`] = `"body{color:red;font-size:20px}a{color:#00f}"`; +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): errors 1`] = `Array []`; + +exports[`when applied with "test" option matches snapshot for multiple "test" value (RegExp): warnings 1`] = `Array []`; + +exports[`when applied with "test" option matches snapshot with empty value: assets 1`] = ` +Object { + "bar1.css": "body{color:red;font-size:20px}a{color:#00f}", + "bar2.css": "h1{color:green}h2{color:#ff0}", + "foo.css": "a{text-align:center}", +} +`; -exports[`when applied with "test" option matches snapshot with empty value: bar2.css 1`] = `"h1{color:green}h2{color:#ff0}"`; +exports[`when applied with "test" option matches snapshot with empty value: errors 1`] = `Array []`; -exports[`when applied with "test" option matches snapshot with empty value: foo.css 1`] = `"a{text-align:center}"`; +exports[`when applied with "test" option matches snapshot with empty value: warnings 1`] = `Array []`; diff --git a/test/sourceMap-option.test.js b/test/sourceMap-option.test.js index fb14405..6c0fdec 100644 --- a/test/sourceMap-option.test.js +++ b/test/sourceMap-option.test.js @@ -7,6 +7,7 @@ import { getCompiler, compile, readAsset, + readAssets, normalizedSourceMap, removeCache, getErrors, @@ -40,48 +41,45 @@ describe('when applied with "sourceMap" option', () => { afterEach(() => Promise.all([removeCache()])); - it('matches snapshot for "false" value, without previous sourcemap', () => { + it('matches snapshot for "false" value, without previous sourcemap', async () => { const compiler = getCompiler(baseConfig); new CssMinimizerPlugin().apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - if (/\.js/.test(file)) continue; - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } + const maps = readAssets(compiler, stats, '.css.map'); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + + Object.keys(maps).forEach((assetKey) => { + expect(normalizedSourceMap(maps[assetKey])).toMatchSnapshot(assetKey); }); + + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); - it('matches snapshot for "true" value, without previous sourcemap', () => { + it('matches snapshot for "true" value, without previous sourcemap', async () => { const compiler = getCompiler(baseConfig); new CssMinimizerPlugin({ sourceMap: true, }).apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - // eslint-disable-next-line guard-for-in - for (const file in stats.compilation.assets) { - if (/\.css$/.test(file)) { - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } + const maps = readAssets(compiler, stats, '.css.map'); - // eslint-disable-next-line no-continue - if (!/\.css.map/.test(file)) continue; - expect( - normalizedSourceMap(readAsset(file, compiler, stats)) - ).toMatchSnapshot(file); - } + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + + Object.keys(maps).forEach((assetKey) => { + expect(normalizedSourceMap(maps[assetKey])).toMatchSnapshot(assetKey); }); + + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); - it('matches snapshot for "false" value, using previous sourcemap', () => { + it('matches snapshot for "false" value, using previous sourcemap', async () => { const config = Object.assign(baseConfig, { module: { rules: [ @@ -102,19 +100,21 @@ describe('when applied with "sourceMap" option', () => { sourceMap: false, }).apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - if (/\.js/.test(file)) continue; - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } + const maps = readAssets(compiler, stats, '.css.map'); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + + Object.keys(maps).forEach((assetKey) => { + expect(normalizedSourceMap(maps[assetKey])).toMatchSnapshot(assetKey); }); + + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); - it('matches snapshot for "true" value, using previous sourcemap', () => { + it('matches snapshot for "true" value, using previous sourcemap', async () => { const config = Object.assign(baseConfig, { module: { rules: [ @@ -135,23 +135,18 @@ describe('when applied with "sourceMap" option', () => { sourceMap: true, }).apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - // eslint-disable-next-line guard-for-in - for (const file in stats.compilation.assets) { - if (/\.css$/.test(file)) { - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } + const maps = readAssets(compiler, stats, '.css.map'); - // eslint-disable-next-line no-continue - if (!/\.css.map/.test(file)) continue; - expect( - normalizedSourceMap(readAsset(file, compiler, stats)) - ).toMatchSnapshot(file); - } + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + + Object.keys(maps).forEach((assetKey) => { + expect(normalizedSourceMap(maps[assetKey])).toMatchSnapshot(assetKey); }); + + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); it('matches snapshot for "inline" value', () => { @@ -178,7 +173,7 @@ describe('when applied with "sourceMap" option', () => { }); }); - it('matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options)', () => { + it('matches snapshot when using SourceMapDevToolPlugin (with filename, publicPath and fileContext options)', async () => { const config = Object.assign(baseConfig, { devtool: false, module: { @@ -211,19 +206,21 @@ describe('when applied with "sourceMap" option', () => { sourceMap: true, }).apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - if (/\.js/.test(file)) continue; - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } + const maps = readAssets(compiler, stats, '.css.map'); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + + Object.keys(maps).forEach((assetKey) => { + expect(normalizedSourceMap(maps[assetKey])).toMatchSnapshot(assetKey); }); + + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); - it('should emit warning when broken sourcemap', () => { + it('should emit warning when broken sourcemap', async () => { const emitBrokenSourceMapPlugin = new (class EmitBrokenSourceMapPlugin { apply(pluginCompiler) { pluginCompiler.hooks.compilation.tap( @@ -282,9 +279,9 @@ describe('when applied with "sourceMap" option', () => { sourceMap: true, }).apply(compiler); - return compile(compiler).then((stats) => { - expect(getErrors(stats)).toMatchSnapshot('error'); - expect(getWarnings(stats)).toMatchSnapshot('warning'); - }); + const stats = await compile(compiler); + + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); }); diff --git a/test/test-option.test.js b/test/test-option.test.js index a2d196c..a8cbf02 100644 --- a/test/test-option.test.js +++ b/test/test-option.test.js @@ -1,6 +1,13 @@ import CssMinimizerPlugin from '../src/index'; -import { getCompiler, compile, readAsset, removeCache } from './helpers'; +import { + getCompiler, + compile, + readAssets, + removeCache, + getErrors, + getWarnings, +} from './helpers'; describe('when applied with "test" option', () => { let compiler; @@ -19,52 +26,37 @@ describe('when applied with "test" option', () => { afterEach(() => Promise.all([removeCache()])); - it('matches snapshot with empty value', () => { + it('matches snapshot with empty value', async () => { new CssMinimizerPlugin().apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - if (/\.js$/.test(file)) continue; - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } - }); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); - it('matches snapshot for a single "test" value (RegExp)', () => { + it('matches snapshot for a single "test" value (RegExp)', async () => { new CssMinimizerPlugin({ test: /bar.*\.css$/, }).apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - if (/\.js$/.test(file)) continue; - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } - }); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); - it('matches snapshot for multiple "test" value (RegExp)', () => { + it('matches snapshot for multiple "test" value (RegExp)', async () => { new CssMinimizerPlugin({ test: [/bar1.*\.css$/, /bar2.*\.css$/], }).apply(compiler); - return compile(compiler).then((stats) => { - expect(stats.compilation.errors).toEqual([]); - expect(stats.compilation.warnings).toEqual([]); + const stats = await compile(compiler); - for (const file in stats.compilation.assets) { - // eslint-disable-next-line no-continue - if (/\.js$/.test(file)) continue; - expect(readAsset(file, compiler, stats)).toMatchSnapshot(file); - } - }); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); }); From ffc71c2c5269ba12c794be87c3257390fdd9c926 Mon Sep 17 00:00:00 2001 From: Alexey Lavinsky Date: Tue, 4 Aug 2020 16:00:48 +0300 Subject: [PATCH 4/7] fix: skip double compression for child compilation (#18) --- src/Webpack5Cache.js | 2 +- src/index.js | 55 +++++++++++++++---- src/minify.js | 4 +- test/CssMinimizerPlugin.test.js | 31 +++++++++++ .../CssMinimizerPlugin.test.js.snap.webpack4 | 10 ++++ .../CssMinimizerPlugin.test.js.snap.webpack5 | 10 ++++ test/helpers/preLoader.js | 42 ++++++++++++++ test/worker.test.js | 10 ++-- 8 files changed, 144 insertions(+), 20 deletions(-) create mode 100644 test/helpers/preLoader.js diff --git a/src/Webpack5Cache.js b/src/Webpack5Cache.js index 897a938..5b8c770 100644 --- a/src/Webpack5Cache.js +++ b/src/Webpack5Cache.js @@ -14,7 +14,7 @@ export default class Cache { async get(task) { // eslint-disable-next-line no-param-reassign task.cacheIdent = - task.cacheIdent || `${task.file}|${serialize(task.cacheKeys)}`; + task.cacheIdent || `${task.name}|${serialize(task.cacheKeys)}`; // eslint-disable-next-line no-param-reassign task.cacheETag = task.cacheETag || this.cache.getLazyHashedEtag(task.assetSource); diff --git a/src/index.js b/src/index.js index 25cf36a..cda8764 100644 --- a/src/index.js +++ b/src/index.js @@ -171,8 +171,38 @@ class CssMinimizerPlugin { : Math.min(Number(parallel) || 0, cpus.length - 1); } - *taskGenerator(compiler, compilation, file) { - const assetSource = compilation.assets[file]; + // eslint-disable-next-line consistent-return + static getAsset(compilation, name) { + // New API + if (compilation.getAsset) { + return compilation.getAsset(name); + } + + if (compilation.assets[name]) { + return { name, source: compilation.assets[name], info: {} }; + } + } + + static updateAsset(compilation, name, newSource, assetInfo) { + // New API + if (compilation.updateAsset) { + compilation.updateAsset(name, newSource, assetInfo); + } + + // eslint-disable-next-line no-param-reassign + compilation.assets[name] = newSource; + } + + *taskGenerator(compiler, compilation, name) { + const { info, source: assetSource } = CssMinimizerPlugin.getAsset( + compilation, + name + ); + + // Skip double minimize assets from child compilation + if (info.minimized) { + yield false; + } let input; let inputSourceMap; @@ -190,7 +220,7 @@ class CssMinimizerPlugin { inputSourceMap = map; compilation.warnings.push( - new Error(`${file} contains invalid source map`) + new Error(`${name} contains invalid source map`) ); } } @@ -222,7 +252,7 @@ class CssMinimizerPlugin { compilation.errors.push( CssMinimizerPlugin.buildError( error, - file, + name, sourceMap, new RequestShortener(compiler.context) ) @@ -236,7 +266,7 @@ class CssMinimizerPlugin { if (map) { outputSource = new SourceMapSource( code, - file, + name, map, input, inputSourceMap, @@ -246,16 +276,17 @@ class CssMinimizerPlugin { outputSource = new RawSource(code); } - // Updating assets - // eslint-disable-next-line no-param-reassign - compilation.assets[file] = outputSource; + CssMinimizerPlugin.updateAsset(compilation, name, outputSource, { + ...info, + minimized: true, + }); // Handling warnings if (warnings && warnings.length > 0) { warnings.forEach((warning) => { const builtWarning = CssMinimizerPlugin.buildWarning( warning, - file, + name, sourceMap, new RequestShortener(compiler.context), this.options.warningsFilter @@ -269,7 +300,7 @@ class CssMinimizerPlugin { }; const task = { - file, + name, input, inputSourceMap, map: this.options.sourceMap, @@ -299,11 +330,11 @@ class CssMinimizerPlugin { 'css-minimizer-webpack-plugin': require('../package.json').version, 'css-minimizer-webpack-plugin-options': this.options, nodeVersion: process.version, - filename: file, + filename: name, contentHash: digest.substr(0, hashDigestLength), }; - task.cacheKeys = this.options.cacheKeys(defaultCacheKeys, file); + task.cacheKeys = this.options.cacheKeys(defaultCacheKeys, name); } } else { // For webpack@5 cache diff --git a/src/minify.js b/src/minify.js index e1a4397..99620f2 100644 --- a/src/minify.js +++ b/src/minify.js @@ -10,7 +10,7 @@ function warningsToString(warnings) { const minify = async (options) => { const { - file, + name, input, minimizerOptions, map, @@ -18,7 +18,7 @@ const minify = async (options) => { minify: minifyFn, } = options; - const postcssOptions = { to: file, from: file }; + const postcssOptions = { to: name, from: name }; if (minifyFn) { const result = await minifyFn( diff --git a/test/CssMinimizerPlugin.test.js b/test/CssMinimizerPlugin.test.js index 32991cc..e72e919 100644 --- a/test/CssMinimizerPlugin.test.js +++ b/test/CssMinimizerPlugin.test.js @@ -340,4 +340,35 @@ describe('CssMinimizerPlugin', () => { } }); }); + + it('should work with child compilation', async () => { + const compiler = getCompiler({ + entry: { + entry: `${__dirname}/fixtures/entry.js`, + }, + module: { + rules: [ + { + test: /entry.js$/i, + use: [ + { + loader: path.resolve(__dirname, './helpers/preLoader'), + }, + ], + }, + { + test: /.s?css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader'], + }, + ], + }, + }); + new CssMinimizerPlugin().apply(compiler); + + const stats = await compile(compiler); + + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); }); diff --git a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 index 80bfccc..b241ee6 100644 --- a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 +++ b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 @@ -66,6 +66,16 @@ exports[`CssMinimizerPlugin should work with assets using querystring: entry.css /*# sourceMappingURL=entry.css.map?v=test*/" `; +exports[`CssMinimizerPlugin should work with child compilation: assets 1`] = ` +Object { + "entry.css": ".entry{text-align:center}", +} +`; + +exports[`CssMinimizerPlugin should work with child compilation: errors 1`] = `Array []`; + +exports[`CssMinimizerPlugin should work with child compilation: warnings 1`] = `Array []`; + exports[`CssMinimizerPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: assets 1`] = ` Object { "one.css": ".minify {};", diff --git a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 index 80bfccc..b241ee6 100644 --- a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 +++ b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 @@ -66,6 +66,16 @@ exports[`CssMinimizerPlugin should work with assets using querystring: entry.css /*# sourceMappingURL=entry.css.map?v=test*/" `; +exports[`CssMinimizerPlugin should work with child compilation: assets 1`] = ` +Object { + "entry.css": ".entry{text-align:center}", +} +`; + +exports[`CssMinimizerPlugin should work with child compilation: errors 1`] = `Array []`; + +exports[`CssMinimizerPlugin should work with child compilation: warnings 1`] = `Array []`; + exports[`CssMinimizerPlugin should write stdout and stderr of workers to stdout and stderr of main process in parallel mode: assets 1`] = ` Object { "one.css": ".minify {};", diff --git a/test/helpers/preLoader.js b/test/helpers/preLoader.js new file mode 100644 index 0000000..46bba79 --- /dev/null +++ b/test/helpers/preLoader.js @@ -0,0 +1,42 @@ +import { RawSource } from 'webpack-sources'; + +class PreCopyPlugin { + constructor(options = {}) { + this.options = options.options || {}; + } + + // eslint-disable-next-line class-methods-use-this + apply(compiler) { + const plugin = { name: 'PreCopyPlugin' }; + + compiler.hooks.compilation.tap(plugin, (compilation) => { + compilation.hooks.additionalAssets.tapAsync(plugin, (callback) => { + compilation.emitAsset( + 'entry.css', + new RawSource('.entry {\n text-align: center;\n}\n\n') + ); + + callback(); + }); + }); + } +} + +export default function loader() { + const callback = this.async(); + + const childCompiler = this._compilation.createChildCompiler( + `preloader`, + this.options + ); + + new PreCopyPlugin().apply(childCompiler); + + childCompiler.runAsChild((error) => { + if (error) { + return callback(error); + } + + return callback(null, 'export default 1'); + }); +} diff --git a/test/worker.test.js b/test/worker.test.js index 09f995e..9466921 100644 --- a/test/worker.test.js +++ b/test/worker.test.js @@ -7,7 +7,7 @@ import { normalizeErrors } from './helpers'; describe('worker', () => { it('should minify css', async () => { const options = { - file: 'entry.css', + name: 'entry.css', input: '.foo{color:red;}\n.bar{color:coral;}', inputSourceMap: { version: 3, @@ -27,7 +27,7 @@ describe('worker', () => { it('should work inputSourceMap as prev', async () => { const options = { - file: 'entry.css', + name: 'entry.css', input: '.foo{color:red;}\n.bar{color:coral;}', minimizerOptions: { discardComments: false }, inputSourceMap: { @@ -47,7 +47,7 @@ describe('worker', () => { it('should work options.minify function', async () => { const options = { - file: 'entry.css', + name: 'entry.css', input: '.foo{color:red;}\n.bar{color:coral;}', minimizerOptions: { discardComments: false }, minify: () => { @@ -62,7 +62,7 @@ describe('worker', () => { it('should emit error', async () => { const options = { - file: 'entry.css', + name: 'entry.css', input: false, }; @@ -79,7 +79,7 @@ describe('worker', () => { it('should emit minimizer error', async () => { const options = { - file: 'entry.css', + name: 'entry.css', input: false, minify: () => { return { error: new Error('css minimizer error') }; From cb038b91b15e934a56c260635506df4f02efd747 Mon Sep 17 00:00:00 2001 From: Alexey Lavinsky Date: Tue, 4 Aug 2020 17:16:42 +0300 Subject: [PATCH 5/7] feat: show minimized assets in stats for webpack@5 (#19) --- src/index.js | 11 +++++++++++ test/CssMinimizerPlugin.test.js | 19 +++++++++++++++++++ .../CssMinimizerPlugin.test.js.snap.webpack4 | 10 ++++++++++ .../CssMinimizerPlugin.test.js.snap.webpack5 | 10 ++++++++++ 4 files changed, 50 insertions(+) diff --git a/src/index.js b/src/index.js index cda8764..60bea02 100644 --- a/src/index.js +++ b/src/index.js @@ -526,6 +526,17 @@ class CssMinimizerPlugin { plugin, optimizeFn.bind(this, compilation) ); + + compilation.hooks.statsPrinter.tap(plugin, (stats) => { + stats.hooks.print + .for('asset.info.minimized') + .tap( + 'css-minimizer-webpack-plugin', + (minimized, { green, formatFlag }) => + // eslint-disable-next-line no-undefined + minimized ? green(formatFlag('minimized')) : undefined + ); + }); } }); } diff --git a/test/CssMinimizerPlugin.test.js b/test/CssMinimizerPlugin.test.js index e72e919..1f35340 100644 --- a/test/CssMinimizerPlugin.test.js +++ b/test/CssMinimizerPlugin.test.js @@ -371,4 +371,23 @@ describe('CssMinimizerPlugin', () => { expect(getErrors(stats)).toMatchSnapshot('errors'); expect(getWarnings(stats)).toMatchSnapshot('warnings'); }); + + it('should work and show minimized assets in stats', async () => { + const compiler = getCompiler({ + entry: { + foo: `${__dirname}/fixtures/entry.js`, + }, + }); + + new CssMinimizerPlugin().apply(compiler); + + const stats = await compile(compiler); + + expect(stats.toString().indexOf('[minimized]') !== -1).toBe( + !getCompiler.isWebpack4() + ); + expect(readAssets(compiler, stats, '.css')).toMatchSnapshot('assets'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + }); }); diff --git a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 index b241ee6..b782d2c 100644 --- a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 +++ b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack4 @@ -59,6 +59,16 @@ exports[`CssMinimizerPlugin should respect the hash options #1: errors 1`] = `Ar exports[`CssMinimizerPlugin should respect the hash options #1: warnings 1`] = `Array []`; +exports[`CssMinimizerPlugin should work and show minimized assets in stats: assets 1`] = ` +Object { + "foo.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`CssMinimizerPlugin should work and show minimized assets in stats: errors 1`] = `Array []`; + +exports[`CssMinimizerPlugin should work and show minimized assets in stats: warnings 1`] = `Array []`; + exports[`CssMinimizerPlugin should work with assets using querystring: entry.css.map?v=test 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,SACF,CACA,EACE,UACF\\",\\"file\\":\\"entry.css?v=test\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\na {\\\\n color: blue;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; exports[`CssMinimizerPlugin should work with assets using querystring: entry.css?v=test 1`] = ` diff --git a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 index b241ee6..b782d2c 100644 --- a/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 +++ b/test/__snapshots__/CssMinimizerPlugin.test.js.snap.webpack5 @@ -59,6 +59,16 @@ exports[`CssMinimizerPlugin should respect the hash options #1: errors 1`] = `Ar exports[`CssMinimizerPlugin should respect the hash options #1: warnings 1`] = `Array []`; +exports[`CssMinimizerPlugin should work and show minimized assets in stats: assets 1`] = ` +Object { + "foo.css": "body{color:red}a{color:#00f}", +} +`; + +exports[`CssMinimizerPlugin should work and show minimized assets in stats: errors 1`] = `Array []`; + +exports[`CssMinimizerPlugin should work and show minimized assets in stats: warnings 1`] = `Array []`; + exports[`CssMinimizerPlugin should work with assets using querystring: entry.css.map?v=test 1`] = `"{\\"version\\":3,\\"sources\\": [replaced for tests], \\"names\\":[],\\"mappings\\":\\"AAAA,KACE,SACF,CACA,EACE,UACF\\",\\"file\\":\\"entry.css?v=test\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\na {\\\\n color: blue;\\\\n}\\"],\\"sourceRoot\\":\\"\\"}"`; exports[`CssMinimizerPlugin should work with assets using querystring: entry.css?v=test 1`] = ` From 01462f6903210806ee085a77f16a09b43994b0c1 Mon Sep 17 00:00:00 2001 From: Alexey Lavinsky Date: Tue, 4 Aug 2020 18:17:16 +0300 Subject: [PATCH 6/7] refactor: migrate on processAssets hook (#20) --- src/Webpack5Cache.js | 6 ++---- src/index.js | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/Webpack5Cache.js b/src/Webpack5Cache.js index 5b8c770..2ed3841 100644 --- a/src/Webpack5Cache.js +++ b/src/Webpack5Cache.js @@ -1,5 +1,3 @@ -import serialize from 'serialize-javascript'; - export default class Cache { // eslint-disable-next-line no-unused-vars constructor(compilation, ignored) { @@ -13,8 +11,8 @@ export default class Cache { async get(task) { // eslint-disable-next-line no-param-reassign - task.cacheIdent = - task.cacheIdent || `${task.name}|${serialize(task.cacheKeys)}`; + task.cacheIdent = task.cacheIdent || `${task.name}`; + // eslint-disable-next-line no-param-reassign task.cacheETag = task.cacheETag || this.cache.getLazyHashedEtag(task.assetSource); diff --git a/src/index.js b/src/index.js index 60bea02..7765157 100644 --- a/src/index.js +++ b/src/index.js @@ -339,13 +339,6 @@ class CssMinimizerPlugin { } else { // For webpack@5 cache task.assetSource = assetSource; - - task.cacheKeys = { - cssMinimizer: CssMinimizerPackageJson.version, - // eslint-disable-next-line global-require - 'css-minimizer-webpack-plugin': require('../package.json').version, - 'css-minimizer-webpack-plugin-options': this.options, - }; } yield task; @@ -505,11 +498,11 @@ class CssMinimizerPlugin { return Promise.resolve(); }; - const plugin = { name: this.constructor.name }; + const pluginName = this.constructor.name; - compiler.hooks.compilation.tap(plugin, (compilation) => { + compiler.hooks.compilation.tap(pluginName, (compilation) => { if (this.options.sourceMap) { - compilation.hooks.buildModule.tap(plugin, (moduleArg) => { + compilation.hooks.buildModule.tap(pluginName, (moduleArg) => { // to get detailed location info about errors // eslint-disable-next-line no-param-reassign moduleArg.useSourceMap = true; @@ -518,16 +511,22 @@ class CssMinimizerPlugin { if (CssMinimizerPlugin.isWebpack4()) { compilation.hooks.optimizeChunkAssets.tapPromise( - plugin, + pluginName, optimizeFn.bind(this, compilation) ); } else { - compilation.hooks.optimizeAssets.tapPromise( - plugin, + // eslint-disable-next-line global-require + const Compilation = require('webpack/lib/Compilation'); + + compilation.hooks.processAssets.tapPromise( + { + name: pluginName, + stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE, + }, optimizeFn.bind(this, compilation) ); - compilation.hooks.statsPrinter.tap(plugin, (stats) => { + compilation.hooks.statsPrinter.tap(pluginName, (stats) => { stats.hooks.print .for('asset.info.minimized') .tap( From 0fd095b73207bd3bf2dcd6ad568f3f9a2322e953 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 4 Aug 2020 18:19:18 +0300 Subject: [PATCH 7/7] chore(release): 1.1.0 --- CHANGELOG.md | 13 +++++++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 195b1fd..e5124d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.1.0](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/compare/v1.0.0...v1.1.0) (2020-08-04) + + +### Features + +* show minimized assets in stats for webpack@5 ([#19](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/issues/19)) ([cb038b9](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/commit/cb038b91b15e934a56c260635506df4f02efd747)) + + +### Bug Fixes + +* compatibility cache feature with webpack@5 ([#16](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/issues/16)) ([997e00f](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/commit/997e00f66298219dccfdff8c01c71bebc973df49)) +* skip double compression for child compilation ([#18](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/issues/18)) ([ffc71c2](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/commit/ffc71c2c5269ba12c794be87c3257390fdd9c926)) + ## 1.0.0 - 2020-08-01 Initial release diff --git a/package-lock.json b/package-lock.json index ee3cc4e..ddc84dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "css-minimizer-webpack-plugin", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 663bb83..9320cc7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "css-minimizer-webpack-plugin", - "version": "1.0.0", + "version": "1.1.0", "description": "cssnano plugin for Webpack", "license": "MIT", "repository": "webpack-contrib/css-minimizer-webpack-plugin",