diff --git a/package.json b/package.json index 4fca4ff154d..248cb7f4e3a 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "strip-ansi": "^6.0.0", "ts-jest": "^25.5.1", "typescript": "^3.9.7", - "webpack": "^5.0.0", + "webpack": "^5.1.0", "webpack-bundle-analyzer": "^3.9.0", "webpack-dev-server": "3.10.3", "yeoman-test": "^2.7.0" diff --git a/packages/webpack-cli/lib/utils/Compiler.js b/packages/webpack-cli/lib/utils/Compiler.js index d17579d5034..0b9bc34098f 100644 --- a/packages/webpack-cli/lib/utils/Compiler.js +++ b/packages/webpack-cli/lib/utils/Compiler.js @@ -1,3 +1,4 @@ +const { options: coloretteOptions } = require('colorette'); const { packageExists } = require('./package-exists'); const webpack = packageExists('webpack') ? require('webpack') : undefined; const logger = require('./logger'); @@ -85,9 +86,24 @@ class Compiler { process.exitCode = 1; } + const getStatsOptions = (stats) => { + // TODO remove after drop webpack@4 + if (webpack.Stats && webpack.Stats.presetToOptions) { + if (!stats) { + stats = {}; + } else if (typeof stats === 'boolean' || typeof stats === 'string') { + stats = webpack.Stats.presetToOptions(stats); + } + } + + stats.colors = typeof stats.colors !== 'undefined' ? stats.colors : coloretteOptions.enabled; + + return stats; + }; + const foundStats = this.compiler.compilers - ? { children: this.compiler.compilers.map((compiler) => compiler.options.stats) } - : this.compiler.options.stats; + ? { children: this.compiler.compilers.map((compiler) => getStatsOptions(compiler.options.stats)) } + : getStatsOptions(this.compiler.options.stats); if (outputOptions.json === true) { process.stdout.write(JSON.stringify(stats.toJson(foundStats), null, 2) + '\n'); diff --git a/test/build-errors/errors.test.js b/test/build-errors/errors.test.js index 23d13c1fe35..5ff6bbc617b 100644 --- a/test/build-errors/errors.test.js +++ b/test/build-errors/errors.test.js @@ -7,7 +7,7 @@ describe('errors', () => { it('should output by default', () => { const { stdout, exitCode } = run(__dirname); - expect(stdout).toMatch(/ERROR in/); + expect(stdout).toMatch(/ERROR/); expect(stdout).toMatch(/Error: Can't resolve/); expect(exitCode).toBe(1); }); diff --git a/test/build-warnings/warnings.test.js b/test/build-warnings/warnings.test.js index 6b880996301..cb049a150b8 100644 --- a/test/build-warnings/warnings.test.js +++ b/test/build-warnings/warnings.test.js @@ -7,7 +7,7 @@ describe('warnings', () => { it('should output by default', () => { const { stdout, exitCode } = run(__dirname); - expect(stdout).toMatch(/WARNING in/); + expect(stdout).toMatch(/WARNING/); expect(stdout).toMatch(/Error: Can't resolve/); expect(exitCode).toBe(0); }); diff --git a/test/cache/cache.test.js b/test/cache/cache.test.js index a183ac4b7d7..66a923670b1 100644 --- a/test/cache/cache.test.js +++ b/test/cache/cache.test.js @@ -10,7 +10,7 @@ describe('cache related tests', () => { if (isWebpack5) { expect(stderr).toContain('starting to restore cache content'); - expect(stdout).toContain('[cached] 1 module'); + expect(stdout).toContain('[cached]'); } }); }); diff --git a/test/colors/colors-false.webpack.config.js b/test/colors/colors-false.webpack.config.js new file mode 100644 index 00000000000..b0f58638bfa --- /dev/null +++ b/test/colors/colors-false.webpack.config.js @@ -0,0 +1,5 @@ +module.exports = { + stats: { + colors: false, + }, +}; diff --git a/test/colors/colors-true.webpack.config.js b/test/colors/colors-true.webpack.config.js new file mode 100644 index 00000000000..15fc57eafd8 --- /dev/null +++ b/test/colors/colors-true.webpack.config.js @@ -0,0 +1,5 @@ +module.exports = { + stats: { + colors: true, + }, +}; diff --git a/test/colors/colors.test.js b/test/colors/colors.test.js new file mode 100644 index 00000000000..4bc9e30fbfb --- /dev/null +++ b/test/colors/colors.test.js @@ -0,0 +1,92 @@ +'use strict'; +const { run, isWebpack5 } = require('../utils/test-utils'); +const { resolve } = require('path'); +const { options: coloretteOptions } = require('colorette'); + +describe('colorts', () => { + it('should output by default', () => { + const { stderr, stdout, exitCode } = run(__dirname); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from flags', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--stats=verbose']); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from flags and from configuration', () => { + const { stderr, stdout, exitCode } = run(__dirname, [ + '--stats=verbose', + `--config=${resolve(__dirname, './no-stats.webpack.config.js')}`, + ]); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from flags and from configuration #2', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--stats=verbose', '--config=stats-string.webpack.config.js']); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from the configuration', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--config=stats-string.webpack.config.js']); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from the configuration #1', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--config=stats-boolean.webpack.config.js']); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from the configuration #2', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--config=no-stats.webpack.config.js']); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from the configuration #3', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--config=colors-true.webpack.config.js']); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + expect(stdout).toContain(coloretteOptions.enabled ? `\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m` : output); + expect(exitCode).toBe(0); + }); + + it('should work with the "stats" option from the configuration #4', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--config=colors-false.webpack.config.js']); + + expect(stderr).toBeFalsy(); + const output = isWebpack5 ? 'successfully' : 'main.js'; + console.log(stdout); + expect(stdout).not.toContain(`\u001b[1m\u001b[32m${output}\u001b[39m\u001b[22m`); + expect(stdout).toContain(output); + expect(exitCode).toBe(0); + }); +}); diff --git a/test/colors/no-stats.webpack.config.js b/test/colors/no-stats.webpack.config.js new file mode 100644 index 00000000000..34672801b3d --- /dev/null +++ b/test/colors/no-stats.webpack.config.js @@ -0,0 +1,3 @@ +module.exports = { + name: 'test', +}; diff --git a/test/colors/src/index.js b/test/colors/src/index.js new file mode 100644 index 00000000000..bdc9aeaf2d1 --- /dev/null +++ b/test/colors/src/index.js @@ -0,0 +1,3 @@ +const foo = 'bar'; + +export default foo diff --git a/test/colors/stats-boolean.webpack.config.js b/test/colors/stats-boolean.webpack.config.js new file mode 100644 index 00000000000..1c9b636be33 --- /dev/null +++ b/test/colors/stats-boolean.webpack.config.js @@ -0,0 +1,3 @@ +module.exports = { + stats: true, +}; diff --git a/test/colors/stats-string.webpack.config.js b/test/colors/stats-string.webpack.config.js new file mode 100644 index 00000000000..5c13e746a6a --- /dev/null +++ b/test/colors/stats-string.webpack.config.js @@ -0,0 +1,3 @@ +module.exports = { + stats: 'verbose', +}; diff --git a/test/core-flags/cache-flags.test.js b/test/core-flags/cache-flags.test.js index f8e55dcc496..8a2cb8ccbb8 100644 --- a/test/core-flags/cache-flags.test.js +++ b/test/core-flags/cache-flags.test.js @@ -76,10 +76,10 @@ describe('cache related flags from core', () => { expect(stderr).toBeFalsy(); expect(stdout).toContain('buildDependencies'); expect(stdout).toContain("config: [ './webpack.config.js' ]"); - expect(stdout).not.toContain('[cached] 1 module'); + expect(stdout).not.toContain('[cached]'); // Run again to check for cache const newRun = run(__dirname, ['--cache-type', 'filesystem', '-c', './webpack.config.js']); - expect(newRun.stdout).toContain('[cached] 1 module'); + expect(newRun.stdout).toContain('[cached]'); expect(newRun.stderr).toBeFalsy(); expect(newRun.exitCode).toEqual(0); }); @@ -94,7 +94,7 @@ describe('cache related flags from core', () => { expect(stdout).toContain("type: 'filesystem'"); // Run again to check for cache const newRun = run(__dirname, ['-c', './webpack.cache.config.js']); - expect(newRun.stdout).toContain('[cached] 1 module'); + expect(newRun.stdout).toContain('[cached]'); expect(newRun.stderr).toBeFalsy(); expect(newRun.exitCode).toEqual(0); }); @@ -128,18 +128,18 @@ describe('cache related flags from core', () => { writeFileSync(resolve(__dirname, './webpack.test.config.js'), 'module.exports = {mode: "development"}'); const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '-c', './webpack.test.config.js']); expect(stderr).toBeFalsy(); - expect(stdout).not.toContain('[cached] 1 module'); + expect(stdout).not.toContain('[cached]'); // Running again should use the cache const newRun = run(__dirname, ['--cache-type', 'filesystem', '-c', './webpack.test.config.js']); - expect(newRun.stdout).toContain('[cached] 1 module'); + expect(newRun.stdout).toContain('[cached]'); // Change config to invalidate cache writeFileSync(resolve(__dirname, './webpack.test.config.js'), 'module.exports = {mode: "production"}'); const newRun2 = run(__dirname, ['--cache-type', 'filesystem', '-c', './webpack.test.config.js']); unlinkSync(resolve(__dirname, './webpack.test.config.js')); - expect(newRun2).not.toContain('[cached] 1 module'); + expect(newRun2).not.toContain('[cached]'); expect(newRun2.exitCode).toEqual(0); }); }); diff --git a/test/watch/watch-flag.test.js b/test/watch/watch-flag.test.js index 92ce02b6079..362c01c3615 100644 --- a/test/watch/watch-flag.test.js +++ b/test/watch/watch-flag.test.js @@ -5,7 +5,7 @@ const { writeFileSync } = require('fs'); const { resolve } = require('path'); const wordsInStatsv4 = ['Hash', 'Version', 'Time', 'Built at:', 'main.js']; -const wordsInStatsv5 = ['asset', 'index.js', 'compiled successfully']; +const wordsInStatsv5 = ['asset', 'index.js', `compiled \u001b[1m\u001b[32msuccessfully\u001b[39m\u001b[22m`]; describe('--watch flag', () => { it('should recompile upon file change', (done) => { diff --git a/yarn.lock b/yarn.lock index 4fa0f70ded0..b38096ae911 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11681,10 +11681,10 @@ webpack-sources@^2.0.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.0.0.tgz#c028b2f0c1db2322de1f4a30cc36f6e373d5a26a" - integrity sha512-OK+Q9xGgda3idw/DgCf75XsVFxRLPu48qPwygqI3W9ls5sDdKif5Ay4SM/1UVob0w4juJy14Zv9nNv0WeyV0aA== +webpack@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.1.0.tgz#7ba2fc8f587ecf0a412477d2e977b3a8818db83c" + integrity sha512-ZJDq7dpVs479C6zCSF/CwOVsqqobjCusa+BgbXCEROZMS0RcBzQzDgc+hB2YXye8Y/JOvcFwJIqsVtTyHW7t8A== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.45"