diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d549f81f9b2..003147be00c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Don't output duplicate utilities ([#9208](https://github.com/tailwindlabs/tailwindcss/pull/9208)) - Fix `fontFamily` config TypeScript types ([#9214](https://github.com/tailwindlabs/tailwindcss/pull/9214)) - Handle variants on complex selector utilities ([#9262](https://github.com/tailwindlabs/tailwindcss/pull/9262)) +- Don't mutate shared config objects ([#9294](https://github.com/tailwindlabs/tailwindcss/pull/9294)) ## [3.1.8] - 2022-08-05 diff --git a/src/util/resolveConfig.js b/src/util/resolveConfig.js index 9a4845af5625..35b0cef5fe31 100644 --- a/src/util/resolveConfig.js +++ b/src/util/resolveConfig.js @@ -29,7 +29,7 @@ function mergeWith(target, ...sources) { if (merged === undefined) { if (isObject(target[k]) && isObject(source[k])) { - target[k] = mergeWith(target[k], source[k], customizer) + target[k] = mergeWith({}, target[k], source[k], customizer) } else { target[k] = source[k] } diff --git a/tests/resolveConfig.test.js b/tests/resolveConfig.test.js index 2c435e5a6eb3..60776a39a88b 100644 --- a/tests/resolveConfig.test.js +++ b/tests/resolveConfig.test.js @@ -1763,3 +1763,30 @@ test('all helpers can be destructured from the first function argument', () => { }, }) }) + +test('does not duplicate extended configs every time resolveConfig is called', () => { + let shared = { + foo: { bar: { baz: [{ color: 'red' }] } }, + } + + const createConfig = (color) => + resolveConfig([ + { + theme: { + foo: shared.foo, + extend: { + foo: { bar: { baz: { color } } }, + }, + }, + }, + ]) + + createConfig('orange') + createConfig('yellow') + createConfig('green') + + const result = createConfig('blue') + + expect(shared.foo.bar.baz).toMatchObject([{ color: 'red' }]) + expect(result.theme.foo.bar.baz).toMatchObject([{ color: 'red' }, { color: 'blue' }]) +})