From 7e90f110b119f36ef9def4f66cf4e17ccf1438cd Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sat, 10 Oct 2020 19:51:22 +0530 Subject: [PATCH] feat: assign config paths in build dependencies in cache config (#1900) --- .../webpack-cli/lib/utils/flag-defaults.js | 23 ++++++ packages/webpack-cli/lib/webpack-cli.js | 28 ++++--- test/cache/cache.test.js | 4 +- test/cache/webpack.config.js | 1 + test/core-flags/cache-flags.test.js | 80 ++++++++++++++++++- test/core-flags/src/index.js | 1 + test/core-flags/webpack.cache.config.js | 12 +++ test/core-flags/webpack.config.js | 2 +- 8 files changed, 132 insertions(+), 19 deletions(-) create mode 100644 packages/webpack-cli/lib/utils/flag-defaults.js create mode 100644 test/core-flags/src/index.js create mode 100644 test/core-flags/webpack.cache.config.js diff --git a/packages/webpack-cli/lib/utils/flag-defaults.js b/packages/webpack-cli/lib/utils/flag-defaults.js new file mode 100644 index 00000000000..10940d05d42 --- /dev/null +++ b/packages/webpack-cli/lib/utils/flag-defaults.js @@ -0,0 +1,23 @@ +const cacheDefaults = (finalConfig, parsedArgs) => { + // eslint-disable-next-line no-prototype-builtins + const hasCache = finalConfig.hasOwnProperty('cache'); + let cacheConfig = {}; + if (hasCache && parsedArgs.config) { + if (finalConfig.cache && finalConfig.cache.type === 'filesystem') { + cacheConfig.buildDependencies = { + config: parsedArgs.config, + }; + } + return { cache: cacheConfig }; + } + return cacheConfig; +}; + +const assignFlagDefaults = (compilerConfig, parsedArgs) => { + if (Array.isArray(compilerConfig)) { + return compilerConfig.map((config) => cacheDefaults(config, parsedArgs)); + } + return cacheDefaults(compilerConfig, parsedArgs); +}; + +module.exports = assignFlagDefaults; diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index c2697145575..f6079011096 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -5,6 +5,7 @@ const { groups, core } = require('./utils/cli-flags'); const argParser = require('./utils/arg-parser'); const { outputStrategy } = require('./utils/merge-strategies'); const { toKebabCase } = require('./utils/helpers'); +const assignFlagDefaults = require('./utils/flag-defaults'); // CLI arg resolvers const handleConfigResolution = require('./groups/ConfigGroup'); @@ -44,19 +45,20 @@ class WebpackCLI extends GroupHelper { * @private\ * @returns {void} */ - _handleCoreFlags() { - if (!this.groupMap.has('core')) { - return; + _handleCoreFlags(parsedArgs) { + if (this.groupMap.has('core')) { + const coreFlags = this.groupMap.get('core'); + + // convert all the flags from map to single object + const coreConfig = coreFlags.reduce((allFlag, curFlag) => ({ ...allFlag, ...curFlag }), {}); + const coreCliHelper = require('webpack').cli; + const coreCliArgs = coreCliHelper.getArguments(); + // Merge the core flag config with the compilerConfiguration + coreCliHelper.processArguments(coreCliArgs, this.compilerConfiguration, coreConfig); + // Assign some defaults to core flags } - const coreFlags = this.groupMap.get('core'); - - // convert all the flags from map to single object - const coreConfig = coreFlags.reduce((allFlag, curFlag) => ({ ...allFlag, ...curFlag }), {}); - - const coreCliHelper = require('webpack').cli; - const coreCliArgs = coreCliHelper.getArguments(); - // Merge the core flag config with the compilerConfiguration - coreCliHelper.processArguments(coreCliArgs, this.compilerConfiguration, coreConfig); + const configWithDefaults = assignFlagDefaults(this.compilerConfiguration, parsedArgs); + this._mergeOptionsToConfiguration(configWithDefaults); } async _baseResolver(cb, parsedArgs, strategy) { @@ -193,7 +195,7 @@ class WebpackCLI extends GroupHelper { .then(() => this._baseResolver(handleConfigResolution, parsedArgs)) .then(() => this._baseResolver(resolveMode, parsedArgs)) .then(() => this._baseResolver(resolveOutput, parsedArgs, outputStrategy)) - .then(() => this._handleCoreFlags()) + .then(() => this._handleCoreFlags(parsedArgs)) .then(() => this._baseResolver(basicResolver, parsedArgs)) .then(() => this._baseResolver(resolveAdvanced, parsedArgs)) .then(() => this._baseResolver(resolveStats, parsedArgs)) diff --git a/test/cache/cache.test.js b/test/cache/cache.test.js index 8eebde0b56a..a183ac4b7d7 100644 --- a/test/cache/cache.test.js +++ b/test/cache/cache.test.js @@ -4,9 +4,9 @@ const { run, isWebpack5 } = require('../utils/test-utils'); describe('cache related tests', () => { it('should log warning in case of single compiler', () => { - let { stderr, stdout } = run(__dirname, ['-c', 'webpack.config.js'], false); + let { stderr, stdout } = run(__dirname, ['-c', './webpack.config.js'], false); // run 2nd compilation - ({ stderr, stdout } = run(__dirname, ['-c', 'webpack.config.js'], false)); + ({ stderr, stdout } = run(__dirname, ['-c', './webpack.config.js'], false)); if (isWebpack5) { expect(stderr).toContain('starting to restore cache content'); diff --git a/test/cache/webpack.config.js b/test/cache/webpack.config.js index 96c9da4834b..0a609684e07 100644 --- a/test/cache/webpack.config.js +++ b/test/cache/webpack.config.js @@ -3,6 +3,7 @@ const path = require('path'); module.exports = { cache: { type: 'filesystem', + name: 'cache-config-tests', buildDependencies: { config: [__filename], }, diff --git a/test/core-flags/cache-flags.test.js b/test/core-flags/cache-flags.test.js index 69cfcd29829..81f56648c2a 100644 --- a/test/core-flags/cache-flags.test.js +++ b/test/core-flags/cache-flags.test.js @@ -1,13 +1,12 @@ 'use strict'; -const { run } = require('../utils/test-utils'); -const { existsSync } = require('fs'); +const { run, isWindows } = require('../utils/test-utils'); +const { existsSync, writeFileSync, unlinkSync } = require('fs'); const { resolve } = require('path'); describe('cache related flags from core', () => { it('should be successful with --cache ', () => { const { stderr, stdout } = run(__dirname, ['--cache']); - expect(stderr).toBeFalsy(); expect(stdout).toContain(`type: 'memory'`); }); @@ -69,4 +68,79 @@ describe('cache related flags from core', () => { expect(stderr).toBeFalsy(); expect(stdout).toContain(`version: '1.1.3'`); }); + + it('should assign cache build dependencies correctly when cache type is filesystem', () => { + // TODO: Fix on windows + if (isWindows) return; + const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '-c', './webpack.config.js']); + expect(stderr).toBeFalsy(); + expect(stdout).toContain('buildDependencies'); + expect(stdout).toContain("config: [ './webpack.config.js' ]"); + expect(stdout).not.toContain('[cached] 1 module'); + // 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.stderr).toBeFalsy(); + expect(newRun.exitCode).toEqual(0); + }); + + it('should assign cache build dependencies correctly when cache type is filesystem in config', () => { + // TODO: Fix on windows + if (isWindows) return; + const { stderr, stdout } = run(__dirname, ['-c', './webpack.cache.config.js']); + expect(stderr).toBeFalsy(); + expect(stdout).toContain('buildDependencies'); + expect(stdout).toContain("config: [ './webpack.cache.config.js' ]"); + 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.stderr).toBeFalsy(); + expect(newRun.exitCode).toEqual(0); + }); + + it('should assign cache build dependencies with multiple configs', () => { + // TODO: Fix on windows + if (isWindows) return; + const { stderr, stdout, exitCode } = run(__dirname, ['-c', './webpack.cache.config.js', '-c', './webpack.config.js']); + expect(stderr).toBeFalsy(); + expect(stdout).toContain('buildDependencies'); + expect(stdout).toContain("config: [ './webpack.cache.config.js', './webpack.config.js' ]"); + expect(stdout).toContain("type: 'filesystem'"); + expect(exitCode).toEqual(0); + }); + + it('should assign cache build dependencies with merged configs', () => { + // TODO: Fix on windows + if (isWindows) return; + const { stderr, stdout, exitCode } = run(__dirname, ['-c', './webpack.cache.config.js', '-c', './webpack.config.js', '--merge']); + expect(stderr).toBeFalsy(); + expect(stdout).toContain('buildDependencies'); + expect(stdout).toContain("config: [ './webpack.cache.config.js', './webpack.config.js' ]"); + expect(stdout).toContain("type: 'filesystem'"); + expect(exitCode).toEqual(0); + }); + + it('should invalidate cache when config changes', () => { + // TODO: Fix on windows + if (isWindows) return; + // Creating a temporary webpack config + 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(); + // modules should not be cached on first run + expect(stdout).not.toContain('[cached] 1 module'); + + // 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'); + + // 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.exitCode).toEqual(0); + }); }); diff --git a/test/core-flags/src/index.js b/test/core-flags/src/index.js new file mode 100644 index 00000000000..b2db5af3651 --- /dev/null +++ b/test/core-flags/src/index.js @@ -0,0 +1 @@ +console.log("Mizuhara Chizuru") diff --git a/test/core-flags/webpack.cache.config.js b/test/core-flags/webpack.cache.config.js new file mode 100644 index 00000000000..26f5a7534ea --- /dev/null +++ b/test/core-flags/webpack.cache.config.js @@ -0,0 +1,12 @@ +const WebpackCLITestPlugin = require('../utils/webpack-cli-test-plugin'); + +module.exports = { + entry: './src/main.js', + mode: 'development', + cache: { + type: 'filesystem', + name: 'config-cache', + }, + name: 'compiler-cache', + plugins: [new WebpackCLITestPlugin(['cache'])], +}; diff --git a/test/core-flags/webpack.config.js b/test/core-flags/webpack.config.js index 086a628bd33..2dc85759ef6 100644 --- a/test/core-flags/webpack.config.js +++ b/test/core-flags/webpack.config.js @@ -4,5 +4,5 @@ module.exports = { entry: './src/main.js', mode: 'development', name: 'compiler', - plugins: [new WebpackCLITestPlugin(['module', 'entry', 'resolve', 'resolveLoader'])], + plugins: [new WebpackCLITestPlugin(['module', 'entry', 'resolve', 'resolveLoader', 'cache'])], };