]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-sfc): upgrade to postcss 8 (#2710)
authorEvan You <yyx990803@gmail.com>
Thu, 4 Feb 2021 13:37:55 +0000 (08:37 -0500)
committerGitHub <noreply@github.com>
Thu, 4 Feb 2021 13:37:55 +0000 (14:37 +0100)
packages/compiler-sfc/package.json
packages/compiler-sfc/src/compileStyle.ts
packages/compiler-sfc/src/cssVars.ts
packages/compiler-sfc/src/stylePluginScoped.ts
packages/compiler-sfc/src/stylePluginTrim.ts
yarn.lock

index e2fb15a31f75e2da97ab643333944e617450c9e3..bceb0223e73b0b47f20c812edd747869ad295afb 100644 (file)
@@ -46,8 +46,8 @@
     "lru-cache": "^5.1.1",
     "magic-string": "^0.25.7",
     "merge-source-map": "^1.1.0",
-    "postcss": "^7.0.32",
-    "postcss-modules": "^3.2.2",
+    "postcss": "^8.1.10",
+    "postcss-modules": "^4.0.0",
     "postcss-selector-parser": "^6.0.4",
     "source-map": "^0.6.1"
   },
index f9b7cbe417d49237e936ea193b38d32567b5a007..7da2713c4a095709a0862745edf95bcb59b4e148 100644 (file)
@@ -1,9 +1,9 @@
 import postcss, {
   ProcessOptions,
-  LazyResult,
   Result,
-  ResultMap,
-  ResultMessage
+  SourceMap,
+  Message,
+  LazyResult
 } from 'postcss'
 import trimPlugin from './stylePluginTrim'
 import scopedPlugin from './stylePluginScoped'
@@ -35,28 +35,33 @@ export interface SFCStyleCompileOptions {
   map?: RawSourceMap
 }
 
+/**
+ * Aligns with postcss-modules
+ * https://github.com/css-modules/postcss-modules
+ */
+export interface CSSModulesOptions {
+  scopeBehaviour?: 'global' | 'local'
+  generateScopedName?:
+    | string
+    | ((name: string, filename: string, css: string) => string)
+  hashPrefix?: string
+  localsConvention?: 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly'
+  exportGlobals?: boolean
+  globalModulePaths?: string[]
+}
+
 export interface SFCAsyncStyleCompileOptions extends SFCStyleCompileOptions {
   isAsync?: boolean
   // css modules support, note this requires async so that we can get the
   // resulting json
   modules?: boolean
-  // maps to postcss-modules options
-  // https://github.com/css-modules/postcss-modules
-  modulesOptions?: {
-    scopeBehaviour?: 'global' | 'local'
-    globalModulePaths?: string[]
-    generateScopedName?:
-      | string
-      | ((name: string, filename: string, css: string) => string)
-    hashPrefix?: string
-    localsConvention?: 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly'
-  }
+  modulesOptions?: CSSModulesOptions
 }
 
 export interface SFCStyleCompileResults {
   code: string
   map: RawSourceMap | undefined
-  rawResult: LazyResult | Result | undefined
+  rawResult: Result | LazyResult | undefined
   errors: Error[]
   modules?: Record<string, string>
   dependencies: Set<string>
@@ -149,7 +154,7 @@ export function doCompileStyle(
 
   let result: LazyResult | undefined
   let code: string | undefined
-  let outMap: ResultMap | undefined
+  let outMap: SourceMap | undefined
   // stylus output include plain css. so need remove the repeat item
   const dependencies = new Set(
     preProcessedSource ? preProcessedSource.dependencies : []
@@ -162,7 +167,7 @@ export function doCompileStyle(
     errors.push(...preProcessedSource.errors)
   }
 
-  const recordPlainCssDependencies = (messages: ResultMessage[]) => {
+  const recordPlainCssDependencies = (messages: Message[]) => {
     messages.forEach(msg => {
       if (msg.type === 'dependency') {
         // postcss output path is absolute position path
@@ -226,7 +231,7 @@ function preprocess(
 
   return preprocessor(
     options.source,
-    options.map,
+    options.inMap || options.map,
     {
       filename: options.filename,
       ...options.preprocessOptions
index 7489d1b511d910088ae30bb6fa38144ceaae2713..4fb721f963dd04e1cbdfb1fefdca79b2a1df079f 100644 (file)
@@ -8,7 +8,7 @@ import {
   BindingMetadata
 } from '@vue/compiler-dom'
 import { SFCDescriptor } from './parse'
-import postcss, { Root } from 'postcss'
+import { PluginCreator } from 'postcss'
 import hash from 'hash-sum'
 
 export const CSS_VARS_HELPER = `useCssVars`
@@ -49,20 +49,21 @@ export interface CssVarsPluginOptions {
   isProd: boolean
 }
 
-export const cssVarsPlugin = postcss.plugin<CssVarsPluginOptions>(
-  'vue-scoped',
-  opts => (root: Root) => {
-    const { id, isProd } = opts!
-    root.walkDecls(decl => {
+export const cssVarsPlugin: PluginCreator<CssVarsPluginOptions> = opts => {
+  const { id, isProd } = opts!
+  return {
+    postcssPlugin: 'vue-sfc-vars',
+    Declaration(decl) {
       // rewrite CSS variables
       if (cssVarRE.test(decl.value)) {
         decl.value = decl.value.replace(cssVarRE, (_, $1, $2, $3) => {
           return `var(--${genVarName(id, $1 || $2 || $3, isProd)})`
         })
       }
-    })
+    }
   }
-)
+}
+cssVarsPlugin.postcss = true
 
 export function genCssVarsCode(
   vars: string[],
index 44265d5ba3133e54b3bc648ffa644227b20faee6..87c8795cd79725a97c2ea80934b2a81d6c47360c 100644 (file)
-import postcss, { Root } from 'postcss'
-import selectorParser, { Node, Selector } from 'postcss-selector-parser'
+import { PluginCreator, Rule } from 'postcss'
+import selectorParser from 'postcss-selector-parser'
 import { warn } from './warn'
 
 const animationNameRE = /^(-\w+-)?animation-name$/
 const animationRE = /^(-\w+-)?animation$/
 
-export default postcss.plugin('vue-scoped', (id: any) => (root: Root) => {
+const scopedPlugin: PluginCreator<string> = (id = '') => {
   const keyframes = Object.create(null)
   const shortId = id.replace(/^data-v-/, '')
 
-  root.each(function rewriteSelectors(node) {
-    if (node.type !== 'rule') {
-      // handle media queries
-      if (node.type === 'atrule') {
-        if (node.name === 'media' || node.name === 'supports') {
-          node.each(rewriteSelectors)
-        } else if (/-?keyframes$/.test(node.name)) {
-          // register keyframes
-          keyframes[node.params] = node.params = node.params + '-' + shortId
-        }
+  return {
+    postcssPlugin: 'vue-sfc-scoped',
+    Rule(rule) {
+      processRule(id, rule)
+    },
+    AtRule(node) {
+      if (
+        /-?keyframes$/.test(node.name) &&
+        !node.params.endsWith(`-${shortId}`)
+      ) {
+        // register keyframes
+        keyframes[node.params] = node.params = node.params + '-' + shortId
       }
-      return
-    }
-
-    node.selector = selectorParser(selectors => {
-      function rewriteSelector(selector: Selector, slotted?: boolean) {
-        let node: Node | null = null
-        let shouldInject = true
-        // find the last child node to insert attribute selector
-        selector.each(n => {
-          // DEPRECATED ">>>" and "/deep/" combinator
-          if (
-            n.type === 'combinator' &&
-            (n.value === '>>>' || n.value === '/deep/')
-          ) {
-            n.value = ' '
-            n.spaces.before = n.spaces.after = ''
-            warn(
-              `the >>> and /deep/ combinators have been deprecated. ` +
-                `Use :deep() instead.`
-            )
-            return false
+    },
+    OnceExit(root) {
+      if (Object.keys(keyframes).length) {
+        // If keyframes are found in this <style>, find and rewrite animation names
+        // in declarations.
+        // Caveat: this only works for keyframes and animation rules in the same
+        // <style> element.
+        // individual animation-name declaration
+        root.walkDecls(decl => {
+          if (animationNameRE.test(decl.prop)) {
+            decl.value = decl.value
+              .split(',')
+              .map(v => keyframes[v.trim()] || v.trim())
+              .join(',')
           }
-
-          if (n.type === 'pseudo') {
-            const { value } = n
-            // deep: inject [id] attribute at the node before the ::v-deep
-            // combinator.
-            if (value === ':deep' || value === '::v-deep') {
-              if (n.nodes.length) {
-                // .foo ::v-deep(.bar) -> .foo[xxxxxxx] .bar
-                // replace the current node with ::v-deep's inner selector
-                let last: Selector['nodes'][0] = n
-                n.nodes[0].each(ss => {
-                  selector.insertAfter(last, ss)
-                  last = ss
-                })
-                // insert a space combinator before if it doesn't already have one
-                const prev = selector.at(selector.index(n) - 1)
-                if (!prev || !isSpaceCombinator(prev)) {
-                  selector.insertAfter(
-                    n,
-                    selectorParser.combinator({
-                      value: ' '
-                    })
-                  )
-                }
-                selector.removeChild(n)
-              } else {
-                // DEPRECATED usage
-                // .foo ::v-deep .bar -> .foo[xxxxxxx] .bar
-                warn(
-                  `::v-deep usage as a combinator has ` +
-                    `been deprecated. Use :deep(<inner-selector>) instead.`
-                )
-                const prev = selector.at(selector.index(n) - 1)
-                if (prev && isSpaceCombinator(prev)) {
-                  selector.removeChild(prev)
+          // shorthand
+          if (animationRE.test(decl.prop)) {
+            decl.value = decl.value
+              .split(',')
+              .map(v => {
+                const vals = v.trim().split(/\s+/)
+                const i = vals.findIndex(val => keyframes[val])
+                if (i !== -1) {
+                  vals.splice(i, 1, keyframes[vals[i]])
+                  return vals.join(' ')
+                } else {
+                  return v
                 }
-                selector.removeChild(n)
-              }
-              return false
-            }
-
-            // slot: use selector inside `::v-slotted` and inject [id + '-s']
-            // instead.
-            // ::v-slotted(.foo) -> .foo[xxxxxxx-s]
-            if (value === ':slotted' || value === '::v-slotted') {
-              rewriteSelector(n.nodes[0], true /* slotted */)
-              let last: Selector['nodes'][0] = n
-              n.nodes[0].each(ss => {
-                selector.insertAfter(last, ss)
-                last = ss
               })
-              // selector.insertAfter(n, n.nodes[0])
-              selector.removeChild(n)
-              // since slotted attribute already scopes the selector there's no
-              // need for the non-slot attribute.
-              shouldInject = false
-              return false
-            }
-
-            // global: replace with inner selector and do not inject [id].
-            // ::v-global(.foo) -> .foo
-            if (value === ':global' || value === '::v-global') {
-              selectors.insertAfter(selector, n.nodes[0])
-              selectors.removeChild(selector)
-              return false
-            }
-          }
-
-          if (n.type !== 'pseudo' && n.type !== 'combinator') {
-            node = n
+              .join(',')
           }
         })
+      }
+    }
+  }
+}
 
-        if (node) {
-          ;(node as Node).spaces.after = ''
-        } else {
-          // For deep selectors & standalone pseudo selectors,
-          // the attribute selectors are prepended rather than appended.
-          // So all leading spaces must be eliminated to avoid problems.
-          selector.first.spaces.before = ''
-        }
+const processedRules = new WeakSet<Rule>()
+
+function processRule(id: string, rule: Rule) {
+  if (processedRules.has(rule)) {
+    return
+  }
+  processedRules.add(rule)
+  rule.selector = selectorParser(selectorRoot => {
+    selectorRoot.each(selector => {
+      rewriteSelector(id, selector, selectorRoot)
+    })
+  }).processSync(rule.selector)
+}
+
+function rewriteSelector(
+  id: string,
+  selector: selectorParser.Selector,
+  selectorRoot: selectorParser.Root,
+  slotted = false
+) {
+  let node: selectorParser.Node | null = null
+  let shouldInject = true
+  // find the last child node to insert attribute selector
+  selector.each(n => {
+    // DEPRECATED ">>>" and "/deep/" combinator
+    if (
+      n.type === 'combinator' &&
+      (n.value === '>>>' || n.value === '/deep/')
+    ) {
+      n.value = ' '
+      n.spaces.before = n.spaces.after = ''
+      warn(
+        `the >>> and /deep/ combinators have been deprecated. ` +
+          `Use :deep() instead.`
+      )
+      return false
+    }
 
-        if (shouldInject) {
-          const idToAdd = slotted ? id + '-s' : id
-          selector.insertAfter(
-            // If node is null it means we need to inject [id] at the start
-            // insertAfter can handle `null` here
-            node as any,
-            selectorParser.attribute({
-              attribute: idToAdd,
-              value: idToAdd,
-              raws: {},
-              quoteMark: `"`
-            })
+    if (n.type === 'pseudo') {
+      const { value } = n
+      // deep: inject [id] attribute at the node before the ::v-deep
+      // combinator.
+      if (value === ':deep' || value === '::v-deep') {
+        if (n.nodes.length) {
+          // .foo ::v-deep(.bar) -> .foo[xxxxxxx] .bar
+          // replace the current node with ::v-deep's inner selector
+          let last: selectorParser.Selector['nodes'][0] = n
+          n.nodes[0].each(ss => {
+            selector.insertAfter(last, ss)
+            last = ss
+          })
+          // insert a space combinator before if it doesn't already have one
+          const prev = selector.at(selector.index(n) - 1)
+          if (!prev || !isSpaceCombinator(prev)) {
+            selector.insertAfter(
+              n,
+              selectorParser.combinator({
+                value: ' '
+              })
+            )
+          }
+          selector.removeChild(n)
+        } else {
+          // DEPRECATED usage
+          // .foo ::v-deep .bar -> .foo[xxxxxxx] .bar
+          warn(
+            `::v-deep usage as a combinator has ` +
+              `been deprecated. Use :deep(<inner-selector>) instead.`
           )
+          const prev = selector.at(selector.index(n) - 1)
+          if (prev && isSpaceCombinator(prev)) {
+            selector.removeChild(prev)
+          }
+          selector.removeChild(n)
         }
+        return false
       }
-      selectors.each(selector => rewriteSelector(selector))
-    }).processSync(node.selector)
-  })
 
-  if (Object.keys(keyframes).length) {
-    // If keyframes are found in this <style>, find and rewrite animation names
-    // in declarations.
-    // Caveat: this only works for keyframes and animation rules in the same
-    // <style> element.
-    // individual animation-name declaration
-    root.walkDecls(decl => {
-      if (animationNameRE.test(decl.prop)) {
-        decl.value = decl.value
-          .split(',')
-          .map(v => keyframes[v.trim()] || v.trim())
-          .join(',')
+      // slot: use selector inside `::v-slotted` and inject [id + '-s']
+      // instead.
+      // ::v-slotted(.foo) -> .foo[xxxxxxx-s]
+      if (value === ':slotted' || value === '::v-slotted') {
+        rewriteSelector(id, n.nodes[0], selectorRoot, true /* slotted */)
+        let last: selectorParser.Selector['nodes'][0] = n
+        n.nodes[0].each(ss => {
+          selector.insertAfter(last, ss)
+          last = ss
+        })
+        // selector.insertAfter(n, n.nodes[0])
+        selector.removeChild(n)
+        // since slotted attribute already scopes the selector there's no
+        // need for the non-slot attribute.
+        shouldInject = false
+        return false
       }
-      // shorthand
-      if (animationRE.test(decl.prop)) {
-        decl.value = decl.value
-          .split(',')
-          .map(v => {
-            const vals = v.trim().split(/\s+/)
-            const i = vals.findIndex(val => keyframes[val])
-            if (i !== -1) {
-              vals.splice(i, 1, keyframes[vals[i]])
-              return vals.join(' ')
-            } else {
-              return v
-            }
-          })
-          .join(',')
+
+      // global: replace with inner selector and do not inject [id].
+      // ::v-global(.foo) -> .foo
+      if (value === ':global' || value === '::v-global') {
+        selectorRoot.insertAfter(selector, n.nodes[0])
+        selectorRoot.removeChild(selector)
+        return false
       }
-    })
+    }
+
+    if (n.type !== 'pseudo' && n.type !== 'combinator') {
+      node = n
+    }
+  })
+
+  if (node) {
+    ;(node as selectorParser.Node).spaces.after = ''
+  } else {
+    // For deep selectors & standalone pseudo selectors,
+    // the attribute selectors are prepended rather than appended.
+    // So all leading spaces must be eliminated to avoid problems.
+    selector.first.spaces.before = ''
   }
-})
 
-function isSpaceCombinator(node: Node) {
+  if (shouldInject) {
+    const idToAdd = slotted ? id + '-s' : id
+    selector.insertAfter(
+      // If node is null it means we need to inject [id] at the start
+      // insertAfter can handle `null` here
+      node as any,
+      selectorParser.attribute({
+        attribute: idToAdd,
+        value: idToAdd,
+        raws: {},
+        quoteMark: `"`
+      })
+    )
+  }
+}
+
+function isSpaceCombinator(node: selectorParser.Node) {
   return node.type === 'combinator' && /^\s+$/.test(node.value)
 }
+
+scopedPlugin.postcss = true
+export default scopedPlugin
index 7d2cd9ac6f473ac3f3b07a2f5e4a938a4befe4d2..67c4a3f0f3556d9d4b32642adfba72f64cfc142a 100644 (file)
@@ -1,10 +1,18 @@
-import postcss, { Root } from 'postcss'
+import { PluginCreator } from 'postcss'
 
-export default postcss.plugin('trim', () => (css: Root) => {
-  css.walk(({ type, raws }) => {
-    if (type === 'rule' || type === 'atrule') {
-      if (raws.before) raws.before = '\n'
-      if (raws.after) raws.after = '\n'
+const trimPlugin: PluginCreator<{}> = () => {
+  return {
+    postcssPlugin: 'vue-sfc-trim',
+    Once(root) {
+      root.walk(({ type, raws }) => {
+        if (type === 'rule' || type === 'atrule') {
+          if (raws.before) raws.before = '\n'
+          if ('after' in raws && raws.after) raws.after = '\n'
+        }
+      })
     }
-  })
-})
+  }
+}
+
+trimPlugin.postcss = true
+export default trimPlugin
index d7889320eb0811907c9af5545fda105a9b296a70..504f672221adb80a6fc1a5ac3007b26911c2d668 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -1697,7 +1697,7 @@ chalk@2.4.1:
     escape-string-regexp "^1.0.5"
     supports-color "^5.3.0"
 
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2:
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1:
   version "2.4.2"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
   integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -1879,6 +1879,11 @@ color-name@~1.1.4:
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
   integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
 
+colorette@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
+  integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
+
 colors@~1.2.1:
   version "1.2.5"
   resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc"
@@ -3441,12 +3446,10 @@ icss-replace-symbols@^1.1.0:
   resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
   integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=
 
-icss-utils@^4.0.0, icss-utils@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467"
-  integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==
-  dependencies:
-    postcss "^7.0.14"
+icss-utils@^5.0.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
+  integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
 
 idb-wrapper@^1.5.0:
   version "1.7.2"
@@ -5097,6 +5100,11 @@ ms@2.1.2:
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
   integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
 
+nanoid@^3.1.18:
+  version "3.1.18"
+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.18.tgz#0680db22ab01c372e89209f5d18283d98de3e96d"
+  integrity sha512-rndlDjbbHbcV3xi+R2fpJ+PbGMdfBxz5v1fATIQFq0DP64FsicQdwnKLy47K4kZHdRpmQXtz24eGsxQqamzYTA==
+
 nanomatch@^1.2.9:
   version "1.2.13"
   resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@@ -5628,55 +5636,49 @@ posix-character-classes@^0.1.0:
   resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
   integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
 
-postcss-modules-extract-imports@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e"
-  integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==
-  dependencies:
-    postcss "^7.0.5"
+postcss-modules-extract-imports@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d"
+  integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==
 
-postcss-modules-local-by-default@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915"
-  integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==
+postcss-modules-local-by-default@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c"
+  integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==
   dependencies:
-    icss-utils "^4.1.1"
-    postcss "^7.0.16"
+    icss-utils "^5.0.0"
     postcss-selector-parser "^6.0.2"
-    postcss-value-parser "^4.0.0"
+    postcss-value-parser "^4.1.0"
 
-postcss-modules-scope@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee"
-  integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==
+postcss-modules-scope@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06"
+  integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==
   dependencies:
-    postcss "^7.0.6"
-    postcss-selector-parser "^6.0.0"
+    postcss-selector-parser "^6.0.4"
 
-postcss-modules-values@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10"
-  integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==
+postcss-modules-values@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c"
+  integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==
   dependencies:
-    icss-utils "^4.0.0"
-    postcss "^7.0.6"
+    icss-utils "^5.0.0"
 
-postcss-modules@^3.2.2:
-  version "3.2.2"
-  resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-3.2.2.tgz#ee390de0f9f18e761e1778dfb9be26685c02c51f"
-  integrity sha512-JQ8IAqHELxC0N6tyCg2UF40pACY5oiL6UpiqqcIFRWqgDYO8B0jnxzoQ0EOpPrWXvcpu6BSbQU/3vSiq7w8Nhw==
+postcss-modules@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-4.0.0.tgz#2bc7f276ab88f3f1b0fadf6cbd7772d43b5f3b9b"
+  integrity sha512-ghS/ovDzDqARm4Zj6L2ntadjyQMoyJmi0JkLlYtH2QFLrvNlxH5OAVRPWPeKilB0pY7SbuhO173KOWkPAxRJcw==
   dependencies:
     generic-names "^2.0.1"
     icss-replace-symbols "^1.1.0"
     lodash.camelcase "^4.3.0"
-    postcss "^7.0.32"
-    postcss-modules-extract-imports "^2.0.0"
-    postcss-modules-local-by-default "^3.0.2"
-    postcss-modules-scope "^2.2.0"
-    postcss-modules-values "^3.0.0"
+    postcss-modules-extract-imports "^3.0.0"
+    postcss-modules-local-by-default "^4.0.0"
+    postcss-modules-scope "^3.0.0"
+    postcss-modules-values "^4.0.0"
     string-hash "^1.1.1"
 
-postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2:
+postcss-selector-parser@^6.0.2:
   version "6.0.2"
   resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c"
   integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==
@@ -5695,19 +5697,20 @@ postcss-selector-parser@^6.0.4:
     uniq "^1.0.1"
     util-deprecate "^1.0.2"
 
-postcss-value-parser@^4.0.0:
+postcss-value-parser@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
   integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
 
-postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
-  version "7.0.35"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24"
-  integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==
+postcss@^8.1.10:
+  version "8.1.10"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.1.10.tgz#129834f94c720554d2cfdaeb27d5542ac4a026ea"
+  integrity sha512-iBXEV5VTTYaRRdxiFYzTtuv2lGMQBExqkZKSzkJe+Fl6rvQrA/49UVGKqB+LG54hpW/TtDBMGds8j33GFNW7pg==
   dependencies:
-    chalk "^2.4.2"
+    colorette "^1.2.1"
+    nanoid "^3.1.18"
     source-map "^0.6.1"
-    supports-color "^6.1.0"
+    vfile-location "^3.2.0"
 
 prelude-ls@^1.2.1:
   version "1.2.1"
@@ -6955,13 +6958,6 @@ supports-color@^5.3.0:
   dependencies:
     has-flag "^3.0.0"
 
-supports-color@^6.1.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
-  integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
-  dependencies:
-    has-flag "^3.0.0"
-
 supports-color@^7.0.0, supports-color@^7.1.0:
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
@@ -7433,6 +7429,11 @@ verror@1.10.0:
     core-util-is "1.0.2"
     extsprintf "^1.2.0"
 
+vfile-location@^3.2.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c"
+  integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==
+
 vlq@^0.2.2:
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"