From fa216a0c3adc70ff74deca872e295a154fa147c8 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 24 Apr 2020 09:59:52 -0400 Subject: [PATCH] feat(compiler-sfc): built-in support for css modules --- .../__tests__/compileStyle.spec.ts | 127 +++++++---- packages/compiler-sfc/package.json | 5 +- packages/compiler-sfc/src/compileStyle.ts | 39 +++- yarn.lock | 214 +++++++++++++++++- 4 files changed, 333 insertions(+), 52 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index b4af3c0972d..08d50c1173d 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -1,70 +1,76 @@ -import { compileStyle } from '../src/compileStyle' +import { compileStyle, compileStyleAsync } from '../src/compileStyle' import { mockWarn } from '@vue/shared' -function compile(source: string): string { - const res = compileStyle({ - source, - filename: 'test.css', - id: 'test' - }) - if (res.errors.length) { - res.errors.forEach(err => { - console.error(err) - }) - expect(res.errors.length).toBe(0) - } - return res.code -} - describe('SFC scoped CSS', () => { mockWarn() + function compileScoped(source: string): string { + const res = compileStyle({ + source, + filename: 'test.css', + id: 'test', + scoped: true + }) + if (res.errors.length) { + res.errors.forEach(err => { + console.error(err) + }) + expect(res.errors.length).toBe(0) + } + return res.code + } + test('simple selectors', () => { - expect(compile(`h1 { color: red; }`)).toMatch(`h1[test] { color: red;`) - expect(compile(`.foo { color: red; }`)).toMatch(`.foo[test] { color: red;`) + expect(compileScoped(`h1 { color: red; }`)).toMatch( + `h1[test] { color: red;` + ) + expect(compileScoped(`.foo { color: red; }`)).toMatch( + `.foo[test] { color: red;` + ) }) test('descendent selector', () => { - expect(compile(`h1 .foo { color: red; }`)).toMatch( + expect(compileScoped(`h1 .foo { color: red; }`)).toMatch( `h1 .foo[test] { color: red;` ) }) test('multiple selectors', () => { - expect(compile(`h1 .foo, .bar, .baz { color: red; }`)).toMatch( + expect(compileScoped(`h1 .foo, .bar, .baz { color: red; }`)).toMatch( `h1 .foo[test], .bar[test], .baz[test] { color: red;` ) }) test('pseudo class', () => { - expect(compile(`.foo:after { color: red; }`)).toMatch( + expect(compileScoped(`.foo:after { color: red; }`)).toMatch( `.foo[test]:after { color: red;` ) }) test('pseudo element', () => { - expect(compile(`::selection { display: none; }`)).toMatch( + expect(compileScoped(`::selection { display: none; }`)).toMatch( '[test]::selection {' ) }) test('spaces before pseudo element', () => { - const code = compile(`.abc, ::selection { color: red; }`) + const code = compileScoped(`.abc, ::selection { color: red; }`) expect(code).toMatch('.abc[test],') expect(code).toMatch('[test]::selection {') }) test('::v-deep', () => { - expect(compile(`::v-deep(.foo) { color: red; }`)).toMatchInlineSnapshot(` + expect(compileScoped(`::v-deep(.foo) { color: red; }`)) + .toMatchInlineSnapshot(` "[test] .foo { color: red; }" `) - expect(compile(`::v-deep(.foo .bar) { color: red; }`)) + expect(compileScoped(`::v-deep(.foo .bar) { color: red; }`)) .toMatchInlineSnapshot(` "[test] .foo .bar { color: red; }" `) - expect(compile(`.baz .qux ::v-deep(.foo .bar) { color: red; }`)) + expect(compileScoped(`.baz .qux ::v-deep(.foo .bar) { color: red; }`)) .toMatchInlineSnapshot(` ".baz .qux[test] .foo .bar { color: red; }" @@ -72,16 +78,17 @@ describe('SFC scoped CSS', () => { }) test('::v-slotted', () => { - expect(compile(`::v-slotted(.foo) { color: red; }`)).toMatchInlineSnapshot(` + expect(compileScoped(`::v-slotted(.foo) { color: red; }`)) + .toMatchInlineSnapshot(` ".foo[test-s] { color: red; }" `) - expect(compile(`::v-slotted(.foo .bar) { color: red; }`)) + expect(compileScoped(`::v-slotted(.foo .bar) { color: red; }`)) .toMatchInlineSnapshot(` ".foo .bar[test-s] { color: red; }" `) - expect(compile(`.baz .qux ::v-slotted(.foo .bar) { color: red; }`)) + expect(compileScoped(`.baz .qux ::v-slotted(.foo .bar) { color: red; }`)) .toMatchInlineSnapshot(` ".baz .qux .foo .bar[test-s] { color: red; }" @@ -89,17 +96,18 @@ describe('SFC scoped CSS', () => { }) test('::v-global', () => { - expect(compile(`::v-global(.foo) { color: red; }`)).toMatchInlineSnapshot(` + expect(compileScoped(`::v-global(.foo) { color: red; }`)) + .toMatchInlineSnapshot(` ".foo { color: red; }" `) - expect(compile(`::v-global(.foo .bar) { color: red; }`)) + expect(compileScoped(`::v-global(.foo .bar) { color: red; }`)) .toMatchInlineSnapshot(` ".foo .bar { color: red; }" `) // global ignores anything before it - expect(compile(`.baz .qux ::v-global(.foo .bar) { color: red; }`)) + expect(compileScoped(`.baz .qux ::v-global(.foo .bar) { color: red; }`)) .toMatchInlineSnapshot(` ".foo .bar { color: red; }" @@ -107,7 +115,7 @@ describe('SFC scoped CSS', () => { }) test('media query', () => { - expect(compile(`@media print { .foo { color: red }}`)) + expect(compileScoped(`@media print { .foo { color: red }}`)) .toMatchInlineSnapshot(` "@media print { .foo[test] { color: red @@ -116,7 +124,7 @@ describe('SFC scoped CSS', () => { }) test('supports query', () => { - expect(compile(`@supports(display: grid) { .foo { display: grid }}`)) + expect(compileScoped(`@supports(display: grid) { .foo { display: grid }}`)) .toMatchInlineSnapshot(` "@supports(display: grid) { .foo[test] { display: grid @@ -125,7 +133,7 @@ describe('SFC scoped CSS', () => { }) test('scoped keyframes', () => { - const style = compile(` + const style = compileScoped(` .anim { animation: color 5s infinite, other 5s; } @@ -184,13 +192,7 @@ describe('SFC scoped CSS', () => { // vue-loader/#1370 test('spaces after selector', () => { - const { code } = compileStyle({ - source: `.foo , .bar { color: red; }`, - filename: 'test.css', - id: 'test' - }) - - expect(code).toMatchInlineSnapshot(` + expect(compileScoped(`.foo , .bar { color: red; }`)).toMatchInlineSnapshot(` ".foo[test], .bar[test] { color: red; }" `) @@ -198,11 +200,12 @@ describe('SFC scoped CSS', () => { describe('deprecated syntax', () => { test('::v-deep as combinator', () => { - expect(compile(`::v-deep .foo { color: red; }`)).toMatchInlineSnapshot(` + expect(compileScoped(`::v-deep .foo { color: red; }`)) + .toMatchInlineSnapshot(` "[test] .foo { color: red; }" `) - expect(compile(`.bar ::v-deep .foo { color: red; }`)) + expect(compileScoped(`.bar ::v-deep .foo { color: red; }`)) .toMatchInlineSnapshot(` ".bar[test] .foo { color: red; }" @@ -213,7 +216,7 @@ describe('SFC scoped CSS', () => { }) test('>>> (deprecated syntax)', () => { - const code = compile(`>>> .foo { color: red; }`) + const code = compileScoped(`>>> .foo { color: red; }`) expect(code).toMatchInlineSnapshot(` "[test] .foo { color: red; }" @@ -224,7 +227,7 @@ describe('SFC scoped CSS', () => { }) test('/deep/ (deprecated syntax)', () => { - const code = compile(`/deep/ .foo { color: red; }`) + const code = compileScoped(`/deep/ .foo { color: red; }`) expect(code).toMatchInlineSnapshot(` "[test] .foo { color: red; }" @@ -235,3 +238,35 @@ describe('SFC scoped CSS', () => { }) }) }) + +describe('SFC CSS modules', () => { + test('should include resulting classes object in result', async () => { + const result = await compileStyleAsync({ + source: `.red { color: red }\n.green { color: green }\n:global(.blue) { color: blue }`, + filename: `test.css`, + id: 'test', + modules: true + }) + expect(result.modules).toBeDefined() + expect(result.modules!.red).toMatch('_red_') + expect(result.modules!.green).toMatch('_green_') + expect(result.modules!.blue).toBeUndefined() + }) + + test('postcss-modules options', async () => { + const result = await compileStyleAsync({ + source: `:local(.foo-bar) { color: red }\n.baz-qux { color: green }`, + filename: `test.css`, + id: 'test', + modules: true, + modulesOptions: { + scopeBehaviour: 'global', + generateScopedName: `[name]__[local]__[hash:base64:5]`, + localsConvention: 'camelCaseOnly' + } + }) + expect(result.modules).toBeDefined() + expect(result.modules!.fooBar).toMatch('__foo-bar__') + expect(result.modules!.bazQux).toBeUndefined() + }) +}) diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index 906a1a79343..9fa76a1e13f 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -30,15 +30,16 @@ "vue": "3.0.0-beta.3" }, "dependencies": { - "@vue/shared": "3.0.0-beta.3", "@vue/compiler-core": "3.0.0-beta.3", "@vue/compiler-dom": "3.0.0-beta.3", "@vue/compiler-ssr": "3.0.0-beta.3", + "@vue/shared": "3.0.0-beta.3", "consolidate": "^0.15.1", "hash-sum": "^2.0.0", "lru-cache": "^5.1.1", "merge-source-map": "^1.1.0", - "postcss": "^7.0.21", + "postcss": "^7.0.27", + "postcss-modules": "^2.0.0", "postcss-selector-parser": "^6.0.2", "source-map": "^0.6.1" }, diff --git a/packages/compiler-sfc/src/compileStyle.ts b/packages/compiler-sfc/src/compileStyle.ts index a5c513319f0..c0a510c0b5a 100644 --- a/packages/compiler-sfc/src/compileStyle.ts +++ b/packages/compiler-sfc/src/compileStyle.ts @@ -25,6 +25,20 @@ export interface SFCStyleCompileOptions { 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' + } } export interface SFCStyleCompileResults { @@ -32,6 +46,7 @@ export interface SFCStyleCompileResults { map: RawSourceMap | undefined rawResult: LazyResult | Result | undefined errors: Error[] + modules?: Record } export function compileStyle( @@ -44,7 +59,7 @@ export function compileStyle( } export function compileStyleAsync( - options: SFCStyleCompileOptions + options: SFCAsyncStyleCompileOptions ): Promise { return doCompileStyle({ ...options, isAsync: true }) as Promise< SFCStyleCompileResults @@ -57,8 +72,10 @@ export function doCompileStyle( const { filename, id, - scoped = true, + scoped = false, trim = true, + modules = false, + modulesOptions = {}, preprocessLang, postcssOptions, postcssPlugins @@ -75,6 +92,23 @@ export function doCompileStyle( if (scoped) { plugins.push(scopedPlugin(id)) } + let cssModules: Record | undefined + if (modules) { + if (options.isAsync) { + plugins.push( + require('postcss-modules')({ + ...modulesOptions, + getJSON: (cssFileName: string, json: Record) => { + cssModules = json + } + }) + ) + } else { + throw new Error( + '`modules` option can only be used with compileStyleAsync().' + ) + } + } const postCSSOptions: ProcessOptions = { ...postcssOptions, @@ -108,6 +142,7 @@ export function doCompileStyle( code: result.css || '', map: result.map && (result.map.toJSON() as any), errors, + modules: cssModules, rawResult: result })) .catch(error => ({ diff --git a/yarn.lock b/yarn.lock index 2fb512b69af..030f655fff6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1319,6 +1319,11 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + bluebird@^3.1.1: version "3.7.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de" @@ -2044,6 +2049,27 @@ crypto-random-string@^1.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= +css-modules-loader-core@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz#5908668294a1becd261ae0a4ce21b0b551f21d16" + integrity sha1-WQhmgpShvs0mGuCkziGwtVHyHRY= + dependencies: + icss-replace-symbols "1.1.0" + postcss "6.0.1" + postcss-modules-extract-imports "1.1.0" + postcss-modules-local-by-default "1.2.0" + postcss-modules-scope "1.1.0" + postcss-modules-values "1.3.0" + +css-selector-tokenizer@^0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz#11e5e27c9a48d90284f22d45061c303d7a25ad87" + integrity sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw== + dependencies: + cssesc "^3.0.0" + fastparse "^1.1.2" + regexpu-core "^4.6.0" + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -2281,6 +2307,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -2596,6 +2627,11 @@ fast-url-parser@1.1.3: dependencies: punycode "^1.3.2" +fastparse@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + fastq@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2" @@ -2747,6 +2783,13 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +generic-names@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-2.0.1.tgz#f8a378ead2ccaa7a34f0317b05554832ae41b872" + integrity sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ== + dependencies: + loader-utils "^1.1.0" + gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" @@ -2983,6 +3026,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3094,6 +3142,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +icss-replace-symbols@1.1.0, icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + ignore@^4.0.3: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -4015,6 +4068,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -4042,6 +4100,13 @@ json5@2.x, json5@^2.1.0, json5@^2.1.2: dependencies: minimist "^1.2.5" +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -4216,6 +4281,15 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" +loader-utils@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -4244,6 +4318,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.get@^4.0.0: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -5160,6 +5239,48 @@ 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@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz#b614c9720be6816eaee35fb3a5faa1dba6a05ddb" + integrity sha1-thTJcgvmgW6u41+zpfqh26agXds= + dependencies: + postcss "^6.0.1" + +postcss-modules-local-by-default@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" + integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-scope@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" + integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-values@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" + +postcss-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-2.0.0.tgz#473d0d7326651d8408585c2a154115d5cb36cce0" + integrity sha512-eqp+Bva+U2cwQO7dECJ8/V+X+uH1HduNeITB0CPPFAu6d/8LKQ32/j+p9rQ2YL1QytVcrNU0X+fBqgGmQIA1Rw== + dependencies: + css-modules-loader-core "^1.1.0" + generic-names "^2.0.1" + lodash.camelcase "^4.3.0" + postcss "^7.0.1" + string-hash "^1.1.1" + 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" @@ -5169,7 +5290,25 @@ postcss-selector-parser@^6.0.2: indexes-of "^1.0.1" uniq "^1.0.1" -postcss@^7.0.21: +postcss@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.1.tgz#000dbd1f8eef217aa368b9a212c5fc40b2a8f3f2" + integrity sha1-AA29H47vIXqjaLmiEsX8QLKo8/I= + dependencies: + chalk "^1.1.3" + source-map "^0.5.6" + supports-color "^3.2.3" + +postcss@^6.0.1: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^7.0.1, postcss@^7.0.27: version "7.0.27" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== @@ -5531,6 +5670,18 @@ redent@^2.0.0: indent-string "^3.0.0" strip-indent "^2.0.0" +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" @@ -5544,6 +5695,18 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpu-core@^4.6.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + registry-auth-token@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" @@ -5567,6 +5730,18 @@ registry-url@3.1.0, registry-url@^3.0.3: dependencies: rc "^1.0.1" +regjsgen@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" + integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -6136,6 +6311,11 @@ string-argv@^0.3.0: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.0.tgz#0ea99e7257fea5e97a1bfcdfc19cf12d68e6ec6a" integrity sha512-NGZHq3nkSXVtGZXTBjFru3MNfoZyIzN25T7BmvdgnSC0LCJczAGLLMQLyjywSIaAoqSemgLzBRHOsnrHbt60+Q== +string-hash@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" + integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= + string-length@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" @@ -6294,7 +6474,14 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -supports-color@^5.3.0: +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -6643,6 +6830,29 @@ uglify-to-browserify@~1.0.0: resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"