From 005e211d53a4a1a34509400e41402b8910875fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 22 Aug 2022 16:20:20 +0200 Subject: [PATCH] Fixed an issue in the styles minifier that caused interpolations to be sometimes included more than once in the output (#2858) --- .changeset/rare-rats-tap.md | 5 +++ .../__tests__/__snapshots__/styled.js.snap | 44 +++++++++++++++++++ ...e-in-at-rule-preceeded-by-interpolation.js | 16 +++++++ .../styled-macro/__snapshots__/index.js.snap | 35 +++++++++++++++ packages/babel-plugin/src/utils/minify.js | 16 ++----- 5 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 .changeset/rare-rats-tap.md create mode 100644 packages/babel-plugin/__tests__/styled-macro/__fixtures__/auto-inserted-rule-in-at-rule-preceeded-by-interpolation.js diff --git a/.changeset/rare-rats-tap.md b/.changeset/rare-rats-tap.md new file mode 100644 index 000000000..857ef92b1 --- /dev/null +++ b/.changeset/rare-rats-tap.md @@ -0,0 +1,5 @@ +--- +'@emotion/babel-plugin': patch +--- + +Fixed an issue in the styles minifier that caused interpolations to be sometimes included more than once in the output. diff --git a/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap b/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap index 8fa4e56a4..2fbba924f 100644 --- a/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap +++ b/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap @@ -45,6 +45,50 @@ const SomeComponent = /*#__PURE__*/_styled('div', process.env.NODE_ENV === "prod })(_templateObject());" `; +exports[`emotion-babel-plugin styled auto-inserted-rule-in-at-rule-preceeded-by-interpolation 1`] = ` +"import styled from '@emotion/styled' +import { css } from '@emotion/react' + +const fullWidth = css\` + width: 100%; +\` + +const StyledRoot = styled.div\` + \${fullWidth} + + button { + @media (min-width: 768px) { + color: red; + } + } +\` + + + ↓ ↓ ↓ ↓ ↓ ↓ + +import _styled from "@emotion/styled/base"; + +function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop)."; } + +import { css } from '@emotion/react'; +const fullWidth = process.env.NODE_ENV === "production" ? { + name: "1d3w5wq", + styles: "width:100%" +} : { + name: "329gto-fullWidth", + styles: "width:100%;label:fullWidth;", + map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImF1dG8taW5zZXJ0ZWQtcnVsZS1pbi1hdC1ydWxlLXByZWNlZWRlZC1ieS1pbnRlcnBvbGF0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdxQiIsImZpbGUiOiJhdXRvLWluc2VydGVkLXJ1bGUtaW4tYXQtcnVsZS1wcmVjZWVkZWQtYnktaW50ZXJwb2xhdGlvbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkJ1xuaW1wb3J0IHsgY3NzIH0gZnJvbSAnQGVtb3Rpb24vcmVhY3QnXG5cbmNvbnN0IGZ1bGxXaWR0aCA9IGNzc2BcbiAgd2lkdGg6IDEwMCU7XG5gXG5cbmNvbnN0IFN0eWxlZFJvb3QgPSBzdHlsZWQuZGl2YFxuICAke2Z1bGxXaWR0aH1cblxuICBidXR0b24ge1xuICAgIEBtZWRpYSAobWluLXdpZHRoOiA3NjhweCkge1xuICAgICAgY29sb3I6IHJlZDtcbiAgICB9XG4gIH1cbmBcbiJdfQ== */", + toString: _EMOTION_STRINGIFIED_CSS_ERROR__ +}; + +const StyledRoot = /*#__PURE__*/_styled("div", process.env.NODE_ENV === "production" ? { + target: "e10xv6gg0" +} : { + target: "e10xv6gg0", + label: "StyledRoot" +})(fullWidth, " button{@media (min-width: 768px){color:red;}}" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImF1dG8taW5zZXJ0ZWQtcnVsZS1pbi1hdC1ydWxlLXByZWNlZWRlZC1ieS1pbnRlcnBvbGF0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU82QiIsImZpbGUiOiJhdXRvLWluc2VydGVkLXJ1bGUtaW4tYXQtcnVsZS1wcmVjZWVkZWQtYnktaW50ZXJwb2xhdGlvbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkJ1xuaW1wb3J0IHsgY3NzIH0gZnJvbSAnQGVtb3Rpb24vcmVhY3QnXG5cbmNvbnN0IGZ1bGxXaWR0aCA9IGNzc2BcbiAgd2lkdGg6IDEwMCU7XG5gXG5cbmNvbnN0IFN0eWxlZFJvb3QgPSBzdHlsZWQuZGl2YFxuICAke2Z1bGxXaWR0aH1cblxuICBidXR0b24ge1xuICAgIEBtZWRpYSAobWluLXdpZHRoOiA3NjhweCkge1xuICAgICAgY29sb3I6IHJlZDtcbiAgICB9XG4gIH1cbmBcbiJdfQ== */"));" +`; + exports[`emotion-babel-plugin styled basic 1`] = ` "import styled from '@emotion/styled' diff --git a/packages/babel-plugin/__tests__/styled-macro/__fixtures__/auto-inserted-rule-in-at-rule-preceeded-by-interpolation.js b/packages/babel-plugin/__tests__/styled-macro/__fixtures__/auto-inserted-rule-in-at-rule-preceeded-by-interpolation.js new file mode 100644 index 000000000..e3801f64a --- /dev/null +++ b/packages/babel-plugin/__tests__/styled-macro/__fixtures__/auto-inserted-rule-in-at-rule-preceeded-by-interpolation.js @@ -0,0 +1,16 @@ +import styled from '@emotion/styled/macro' +import { css } from '@emotion/react' + +const fullWidth = css` + width: 100%; +` + +const StyledRoot = styled.div` + ${fullWidth} + + button { + @media (min-width: 768px) { + color: red; + } + } +` diff --git a/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap b/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap index b702ad9b4..75c64a11b 100644 --- a/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap +++ b/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap @@ -45,6 +45,41 @@ const SomeComponent = /*#__PURE__*/_styled('div', process.env.NODE_ENV === "prod })(_templateObject());" `; +exports[`@emotion/styled.macro auto-inserted-rule-in-at-rule-preceeded-by-interpolation 1`] = ` +"import styled from '@emotion/styled/macro' +import { css } from '@emotion/react' + +const fullWidth = css\` + width: 100%; +\` + +const StyledRoot = styled.div\` + \${fullWidth} + + button { + @media (min-width: 768px) { + color: red; + } + } +\` + + + ↓ ↓ ↓ ↓ ↓ ↓ + +import _styled from "@emotion/styled/base"; +import { css } from '@emotion/react'; +const fullWidth = css\` + width: 100%; +\`; + +const StyledRoot = /*#__PURE__*/_styled("div", process.env.NODE_ENV === "production" ? { + target: "e10xv6gg0" +} : { + target: "e10xv6gg0", + label: "StyledRoot" +})(fullWidth, " button{@media (min-width: 768px){color:red;}}" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImF1dG8taW5zZXJ0ZWQtcnVsZS1pbi1hdC1ydWxlLXByZWNlZWRlZC1ieS1pbnRlcnBvbGF0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU82QiIsImZpbGUiOiJhdXRvLWluc2VydGVkLXJ1bGUtaW4tYXQtcnVsZS1wcmVjZWVkZWQtYnktaW50ZXJwb2xhdGlvbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkL21hY3JvJ1xuaW1wb3J0IHsgY3NzIH0gZnJvbSAnQGVtb3Rpb24vcmVhY3QnXG5cbmNvbnN0IGZ1bGxXaWR0aCA9IGNzc2BcbiAgd2lkdGg6IDEwMCU7XG5gXG5cbmNvbnN0IFN0eWxlZFJvb3QgPSBzdHlsZWQuZGl2YFxuICAke2Z1bGxXaWR0aH1cblxuICBidXR0b24ge1xuICAgIEBtZWRpYSAobWluLXdpZHRoOiA3NjhweCkge1xuICAgICAgY29sb3I6IHJlZDtcbiAgICB9XG4gIH1cbmBcbiJdfQ== */"));" +`; + exports[`@emotion/styled.macro basic 1`] = ` "import styled from '@emotion/styled/macro' diff --git a/packages/babel-plugin/src/utils/minify.js b/packages/babel-plugin/src/utils/minify.js index f8e500ee0..14281a98e 100644 --- a/packages/babel-plugin/src/utils/minify.js +++ b/packages/babel-plugin/src/utils/minify.js @@ -5,18 +5,10 @@ const haveSameLocation = (element1, element2) => { return element1.line === element2.line && element1.column === element2.column } -const isAutoInsertedRule = element => { - if (element.type !== 'rule' || !element.parent) { - return false - } - - let parent = element - do { - parent = parent.parent - } while (parent && parent.type !== 'rule') - - return !!parent && haveSameLocation(element, parent) -} +const isAutoInsertedRule = element => + element.type === 'rule' && + element.parent && + haveSameLocation(element, element.parent) const toInputTree = (elements, tree) => { for (let i = 0; i < elements.length; i++) {