feat(v2): introduce new minification of CSS bundle (#3716)

* feat(v2): optimize CSS bundle

* Move to separate preset

* Move custom scrollbar styles to separate class

* Cleanup styles

* Remove unactual styles

* Various CSS optimizations, cleanup styles for NProgress

* Add ability to back to old way of minifying CSS

* chore(v2): downgrade babel-plugin-dynamic-import-node to 2.3.0

* Use env var for back to simple CSS minifier

* remove unnecessary typing [skip-ci]

* Remove missing dep

* Update website/docs/cli.md

Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
This commit is contained in:
Alexey Pyltsyn 2020-11-13 16:06:24 +03:00 committed by GitHub
parent 9afe4b5447
commit 487a9f98e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 386 additions and 107 deletions

View file

@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const advancedBasePreset = require('cssnano-preset-advanced');
const postCssCombineDuplicatedSelectors = require('postcss-combine-duplicated-selectors');
const postCssSortMediaQueries = require('postcss-sort-media-queries');
const postCssRemoveOverriddenCustomProperties = require('./src/remove-overridden-custom-properties');
const preset = advancedBasePreset({autoprefixer: {add: true}});
preset.plugins.unshift(
[postCssCombineDuplicatedSelectors, {removeDuplicatedProperties: true}],
[postCssSortMediaQueries],
[postCssRemoveOverriddenCustomProperties],
);
module.exports = preset;

View file

@ -0,0 +1,21 @@
{
"name": "@docusaurus/cssnano-preset",
"version": "2.0.0-alpha.66",
"description": "Advanced cssnano preset for maximum optimization",
"main": "index.js",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/facebook/docusaurus.git",
"directory": "packages/docusaurus-cssnano-preset"
},
"dependencies": {
"postcss": "^7.0.2",
"postcss-combine-duplicated-selectors": "^9.1.0",
"postcss-sort-media-queries": "^1.7.26",
"cssnano-preset-advanced": "^4.0.7"
},
"devDependencies": {
"to-vfile": "^6.0.0"
}
}

View file

@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`remove-overridden-custom-properties overridden custom properties should be removed 1`] = `
":root {
--color-secondary: green;
--color-primary: blue;
--color-header: gray;
}
"
`;
exports[`remove-overridden-custom-properties overridden custom properties with \`!important\` rule should not be removed 1`] = `
":root {
--color-primary: blue;
--color-header: gray !important;
--color-secondary: yellow !important;
}
"
`;

View file

@ -0,0 +1,8 @@
:root {
--color-primary: red;
--color-secondary: green;
--color-primary: blue;
--color-header: gray !important;
--color-header: black;
--color-secondary: yellow !important;
}

View file

@ -0,0 +1,7 @@
:root {
--color-primary: red;
--color-primary: red;
--color-secondary: green;
--color-primary: blue;
--color-header: gray;
}

View file

@ -0,0 +1,33 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const path = require('path');
const vfile = require('to-vfile');
const postcss = require('postcss');
const postCssRemoveOverriddenCustomProperties = require('../index');
const processFixture = (name) => {
const input = vfile.readSync(
path.join(__dirname, 'fixtures', `${name}.css`),
'utf8',
);
const output = postcss([postCssRemoveOverriddenCustomProperties]).process(
input,
);
return output.css;
};
describe('remove-overridden-custom-properties', () => {
test('overridden custom properties should be removed', () => {
expect(processFixture('normal')).toMatchSnapshot();
});
test('overridden custom properties with `!important` rule should not be removed', () => {
expect(processFixture('important_rule')).toMatchSnapshot();
});
});

View file

@ -0,0 +1,42 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const postcss = require('postcss');
/*
This PostCSS plugin will remove duplicate/same custom properties (which are actually overridden ones) **only** from `:root` selector.
Depending on the presence of an `!important` rule in value of custom property, the following actions will happens:
- If the same custom properties do **not** have an `!important` rule, then all of them will be removed except for the last one (which will actually be applied).
- If the same custom properties have at least one `!important` rule, then only those properties that do not have this rule will be removed.
*/
module.exports = postcss.plugin(
'postcss-remove-overridden-custom-properties',
() => {
return (root) => {
root.walkDecls((decl) => {
if (decl.parent.selector !== ':root') {
return;
}
const sameProperties =
decl.parent.nodes.filter((n) => n.prop === decl.prop) || [];
const hasImportantProperties = sameProperties.some((p) =>
p.hasOwnProperty('important'),
);
const overriddenProperties = hasImportantProperties
? sameProperties.filter((p) => !p.hasOwnProperty('important'))
: sameProperties.slice(0, -1);
overriddenProperties.map((p) => p.remove());
});
};
},
);

View file

@ -45,11 +45,7 @@
}
.codeBlockTitle:hover + .codeBlockContent .copyButton,
.codeBlockContent:hover > .copyButton {
outline: none;
opacity: 1;
}
.codeBlockContent:hover > .copyButton,
.copyButton:focus {
opacity: 1;
}

View file

@ -107,11 +107,9 @@
width: 24px;
}
/* TODO: Move to Infima */
:global(.menu__list) :global(.menu__list) {
overflow-y: hidden;
will-change: height;
/* Same as "arrow" transition */
transition: height var(--ifm-transition-fast) linear;
}

View file

@ -9,7 +9,6 @@
display: block;
position: relative;
top: -0.5rem;
outline: none;
}
.hash-link {

View file

@ -10,7 +10,6 @@
display: flex;
height: 10px;
justify-content: center;
position: relative;
width: 10px;
}
.toggle::before {
@ -25,21 +24,10 @@
*/
:global(.react-toggle) {
touch-action: pan-x;
display: inline-block;
position: relative;
cursor: pointer;
background-color: transparent;
border: 0;
padding: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
}
@ -50,7 +38,6 @@
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
@ -62,11 +49,8 @@
:global(.react-toggle-track) {
width: 50px;
height: 24px;
padding: 0;
border-radius: 30px;
background-color: #4d4d4d;
-webkit-transition: all 0.2s ease;
-moz-transition: all 0.2s ease;
transition: all 0.2s ease;
}
@ -76,21 +60,16 @@
height: 10px;
top: 0px;
bottom: 0px;
margin-top: auto;
margin-bottom: auto;
margin: auto 0;
line-height: 0;
left: 8px;
opacity: 0;
-webkit-transition: opacity 0.25s ease;
-moz-transition: opacity 0.25s ease;
transition: opacity 0.25s ease;
}
:global([data-theme='dark'] .react-toggle .react-toggle-track-check),
:global(.react-toggle--checked .react-toggle-track-check) {
opacity: 1;
-webkit-transition: opacity 0.25s ease;
-moz-transition: opacity 0.25s ease;
transition: opacity 0.25s ease;
}
@ -100,13 +79,10 @@
height: 10px;
top: 0px;
bottom: 0px;
margin-top: auto;
margin-bottom: auto;
margin: auto 0;
line-height: 0;
right: 10px;
opacity: 1;
-webkit-transition: opacity 0.25s ease;
-moz-transition: opacity 0.25s ease;
transition: opacity 0.25s ease;
}
@ -125,13 +101,6 @@
border: 1px solid #4d4d4d;
border-radius: 50%;
background-color: #fafafa;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: all 0.25s ease;
-moz-transition: all 0.25s ease;
transition: all 0.25s ease;
}
@ -142,13 +111,9 @@
}
:global(.react-toggle--focus .react-toggle-thumb) {
-webkit-box-shadow: 0px 0px 3px 2px #0099e0;
-moz-box-shadow: 0px 0px 3px 2px #0099e0;
box-shadow: 0px 0px 2px 3px #0099e0;
}
:global(.react-toggle:active:not(.react-toggle--disabled) .react-toggle-thumb) {
-webkit-box-shadow: 0px 0px 5px 5px #0099e0;
-moz-box-shadow: 0px 0px 5px 5px #0099e0;
box-shadow: 0px 0px 5px 5px #0099e0;
}

View file

@ -45,6 +45,7 @@
"@babel/preset-typescript": "^7.12.1",
"@babel/runtime": "^7.12.5",
"@babel/runtime-corejs3": "^7.12.5",
"@docusaurus/cssnano-preset": "2.0.0-alpha.66",
"@docusaurus/types": "2.0.0-alpha.66",
"@docusaurus/utils": "2.0.0-alpha.66",
"@docusaurus/utils-validation": "2.0.0-alpha.66",
@ -56,6 +57,7 @@
"cache-loader": "^4.1.0",
"chalk": "^3.0.0",
"chokidar": "^3.4.3",
"clean-css": "^4.2.3",
"commander": "^4.0.1",
"copy-webpack-plugin": "^6.3.0",
"core-js": "^2.6.5",

View file

@ -13,7 +13,7 @@ import clientLifecyclesDispatcher from './client-lifecycles-dispatcher';
import preload from './preload';
import normalizeLocation from './normalizeLocation';
import 'nprogress/nprogress.css';
import './nprogress.css';
nprogress.configure({showSpinner: false});

View file

@ -0,0 +1,36 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Styles for NProgress
* Copied over to remove unused styles for the spinner.
* https://github.com/rstacruz/nprogress/blob/master/nprogress.css
*/
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: #29d;
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
#nprogress .peg {
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #29d, 0 0 5px #29d;
opacity: 1;
transform: rotate(3deg) translate(0px, -4px);
}

View file

@ -7,18 +7,16 @@
import fs from 'fs-extra';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin';
import PnpWebpackPlugin from 'pnp-webpack-plugin';
import path from 'path';
import TerserPlugin from 'terser-webpack-plugin';
import {Configuration, Loader} from 'webpack';
import {Props} from '@docusaurus/types';
import {
getBabelLoader,
getCacheLoader,
getStyleLoaders,
getFileLoaderUtils,
getMinimizer,
} from './utils';
import {BABEL_CONFIG_FILE_NAME} from '../constants';
@ -38,26 +36,17 @@ export function excludeJS(modulePath: string): boolean {
);
}
// See https://github.com/webpack-contrib/terser-webpack-plugin#parallel
let terserParallel: boolean | number = true;
if (process.env.TERSER_PARALLEL === 'false') {
terserParallel = false;
} else if (
process.env.TERSER_PARALLEL &&
parseInt(process.env.TERSER_PARALLEL, 10) > 0
) {
terserParallel = parseInt(process.env.TERSER_PARALLEL, 10);
}
export function createBaseConfig(
props: Props,
isServer: boolean,
minify: boolean,
minify: boolean = true,
): Configuration {
const {outDir, siteDir, baseUrl, generatedFilesDir, routesPaths} = props;
const totalPages = routesPaths.length;
const isProd = process.env.NODE_ENV === 'production';
const minimizeEnabled = minify && isProd && !isServer;
const useSimpleCssMinifier = process.env.USE_SIMPLE_CSS_MINIFIER === 'true';
const customBabelConfigurationPath = path.join(
siteDir,
@ -108,46 +97,10 @@ export function createBaseConfig(
optimization: {
removeAvailableModules: false,
// Only minimize client bundle in production because server bundle is only used for static site generation
minimize: minify && isProd && !isServer,
minimizer:
minify && isProd
? [
new TerserPlugin({
cache: true,
parallel: terserParallel,
sourceMap: false,
terserOptions: {
parse: {
// we want uglify-js to parse ecma 8 code. However, we don't want it
// to apply any minfication steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
},
},
}),
new OptimizeCSSAssetsPlugin({
cssProcessorPluginOptions: {
preset: 'default',
},
}),
]
: undefined,
minimize: minimizeEnabled,
minimizer: minimizeEnabled
? getMinimizer(useSimpleCssMinifier)
: undefined,
splitChunks: isServer
? false
: {

View file

@ -17,11 +17,9 @@ import LogPlugin from './plugins/LogPlugin';
export default function createServerConfig({
props,
minify = true,
onLinksCollected = () => {},
}: {
props: Props;
minify?: boolean;
onLinksCollected?: (staticPagePath: string, links: string[]) => void;
}): Configuration {
const {
@ -34,7 +32,7 @@ export default function createServerConfig({
ssrTemplate,
siteConfig: {noIndex},
} = props;
const config = createBaseConfig(props, true, minify);
const config = createBaseConfig(props, true);
const routesLocation = {};
// Array of paths to be rendered. Relative to output directory

View file

@ -9,12 +9,16 @@ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import env from 'std-env';
import merge from 'webpack-merge';
import webpack, {Configuration, Loader, RuleSetRule, Stats} from 'webpack';
import TerserPlugin from 'terser-webpack-plugin';
import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin';
import CleanCss from 'clean-css';
import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
import chalk from 'chalk';
import {TransformOptions} from '@babel/core';
import {ConfigureWebpackFn} from '@docusaurus/types';
import CssNanoPreset from '@docusaurus/cssnano-preset';
import {version as cacheLoaderVersion} from 'cache-loader/package.json';
import {STATIC_ASSETS_DIR_NAME} from '../constants';
@ -336,3 +340,87 @@ export function getHttpsConfig(): boolean | {cert: Buffer; key: Buffer} {
}
return isHttps;
}
// See https://github.com/webpack-contrib/terser-webpack-plugin#parallel
function getTerserParallel() {
let terserParallel: boolean | number = true;
if (process.env.TERSER_PARALLEL === 'false') {
terserParallel = false;
} else if (
process.env.TERSER_PARALLEL &&
parseInt(process.env.TERSER_PARALLEL, 10) > 0
) {
terserParallel = parseInt(process.env.TERSER_PARALLEL, 10);
}
return terserParallel;
}
export function getMinimizer(useSimpleCssMinifier = false) {
const minimizer = [
new TerserPlugin({
cache: true,
parallel: getTerserParallel(),
sourceMap: false,
terserOptions: {
parse: {
// we want uglify-js to parse ecma 8 code. However, we don't want it
// to apply any minification steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
},
},
}),
];
if (useSimpleCssMinifier) {
minimizer.push(
new OptimizeCSSAssetsPlugin({
cssProcessorPluginOptions: {
preset: 'default',
},
}),
);
} else {
minimizer.push(
...[
new OptimizeCSSAssetsPlugin({
cssProcessorPluginOptions: {
preset: CssNanoPreset,
},
}),
new OptimizeCSSAssetsPlugin({
cssProcessor: CleanCss,
cssProcessorOptions: {
level: {
1: {
all: false,
},
2: {
all: true,
restructureRules: true,
},
},
},
}),
],
);
}
return minimizer;
}

View file

@ -85,6 +85,14 @@ Compiles your site for production.
| `--out-dir` | `build` | The full path for the new output directory, relative to the current workspace. |
| `--no-minify` | `false` | Build website without minimizing JS/CSS bundles. |
:::info
For advanced minification of CSS bundle, we use the [advanced cssnano preset](https://github.com/cssnano/cssnano/tree/master/packages/cssnano-preset-advanced) (along with additional several PostCSS plugins) and [level 2 optimization of clean-css](https://github.com/jakubpawlowicz/clean-css#level-2-optimizations).
If as a result of this advanced CSS minification you find broken CSS, build your website with the environment variable `USE_SIMPLE_CSS_MINIFIER=true` to minify CSS with the [default cssnano preset](https://github.com/cssnano/cssnano/tree/master/packages/cssnano-preset-default).
**Please [fill out an issue](https://github.com/facebook/docusaurus/issues/new?labels=bug%2C+needs+triage&template=bug.md) if you experience CSS minification bugs.**
:::
### `docusaurus swizzle`
:::caution

View file

@ -103,14 +103,12 @@
}
.indexCtasGetStartedButton {
border: 1px solid var(--ifm-color-primary);
display: inline-block;
border: 2px solid var(--ifm-color-primary);
line-height: 1.2em;
text-decoration: none !important;
text-transform: uppercase;
transition: background 0.3s, color 0.3s;
border-radius: 8px;
border-width: 2px;
color: #fff;
font-size: 24px;
font-weight: bold;

View file

@ -5961,6 +5961,19 @@ autolinker@~0.28.0:
dependencies:
gulp-header "^1.7.1"
autoprefixer@^9.4.7:
version "9.8.6"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f"
integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==
dependencies:
browserslist "^4.12.0"
caniuse-lite "^1.0.30001109"
colorette "^1.2.1"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
postcss "^7.0.32"
postcss-value-parser "^4.1.0"
autoprefixer@^9.6.1:
version "9.7.3"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.3.tgz#fd42ed03f53de9beb4ca0d61fb4f7268a9bb50b4"
@ -6987,6 +7000,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000989, can
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001157.tgz"
integrity sha512-gOerH9Wz2IRZ2ZPdMfBvyOi3cjaz4O4dgNwPGzx8EhqAs4+2IL/O+fJsbt+znSigujoZG8bVcIAUM/I/E5K3MA==
caniuse-lite@^1.0.30001109:
version "1.0.30001156"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001156.tgz#75c20937b6012fe2b02ab58b30d475bf0718de97"
integrity sha512-z7qztybA2eFZTB6Z3yvaQBIoJpQtsewRD74adw2UbRWwsRq3jIPvgrQGawBMbfafekQaD21FWuXNcywtTDGGCw==
capture-exit@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4"
@ -8452,6 +8470,18 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
cssnano-preset-advanced@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-4.0.7.tgz#d981527b77712e2f3f3f09c73313e9b71b278b88"
integrity sha512-j1O5/DQnaAqEyFFQfC+Z/vRlLXL3LxJHN+lvsfYqr7KgPH74t69+Rsy2yXkovWNaJjZYBpdz2Fj8ab2nH7pZXw==
dependencies:
autoprefixer "^9.4.7"
cssnano-preset-default "^4.0.7"
postcss-discard-unused "^4.0.1"
postcss-merge-idents "^4.0.1"
postcss-reduce-idents "^4.0.2"
postcss-zindex "^4.0.1"
cssnano-preset-default@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76"
@ -17220,6 +17250,14 @@ postcss-colormin@^4.0.3:
postcss "^7.0.0"
postcss-value-parser "^3.0.0"
postcss-combine-duplicated-selectors@^9.1.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/postcss-combine-duplicated-selectors/-/postcss-combine-duplicated-selectors-9.4.0.tgz#dae866debae5f93b58e13e6cc69419105e91336a"
integrity sha512-rMnO1H3wgR1T6QSlK3i8Slz9p3xD+0yOi4J7qwh/5PGR3z8jbgYvRlNKAIvXDtGBQbJKoWs4df5skL3a/fdUEA==
dependencies:
postcss "^7.0.0"
postcss-selector-parser "^6.0.0"
postcss-convert-values@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f"
@ -17287,6 +17325,15 @@ postcss-discard-overridden@^4.0.1:
dependencies:
postcss "^7.0.0"
postcss-discard-unused@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-4.0.1.tgz#ee7cc66af8c7e8c19bd36f12d09c4bde4039abea"
integrity sha512-/3vq4LU0bLH2Lj4NYN7BTf2caly0flUB7Xtrk9a5K3yLuXMkHMqMO/x3sDq8W2b1eQFSCyY0IVz2L+0HP8kUUA==
dependencies:
postcss "^7.0.0"
postcss-selector-parser "^3.0.0"
uniqs "^2.0.0"
postcss-double-position-gradients@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e"
@ -17415,6 +17462,16 @@ postcss-media-query-parser@^0.2.3:
resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244"
integrity sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=
postcss-merge-idents@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-4.0.1.tgz#b7df282a92f052ea0a66c62d8f8812e6d2cbed23"
integrity sha512-43S/VNdF6II0NZ31YxcvNYq4gfURlPAAsJW/z84avBXQCaP4I4qRHUH18slW/SOlJbcxxCobflPNUApYDddS7A==
dependencies:
cssnano-util-same-parent "^4.0.0"
has "^1.0.0"
postcss "^7.0.0"
postcss-value-parser "^3.0.0"
postcss-merge-longhand@^4.0.11:
version "4.0.11"
resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24"
@ -17680,6 +17737,14 @@ postcss-pseudo-class-any-link@^6.0.0:
postcss "^7.0.2"
postcss-selector-parser "^5.0.0-rc.3"
postcss-reduce-idents@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-4.0.2.tgz#30447a6ec20941e78e21bd4482a11f569c4f455b"
integrity sha512-Tz70Ri10TclPoCtFfftjFVddx3fZGUkr0dEDbIEfbYhFUOFQZZ77TEqRrU0e6TvAvF+Wa5VVzYTpFpq0uwFFzw==
dependencies:
postcss "^7.0.0"
postcss-value-parser "^3.0.0"
postcss-reduce-initial@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df"
@ -17787,6 +17852,14 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2:
indexes-of "^1.0.1"
uniq "^1.0.1"
postcss-sort-media-queries@^1.7.26:
version "1.31.21"
resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-1.31.21.tgz#3225ec6eb490402602284ac99963b80461783cee"
integrity sha512-h+HbXXfOVFeLvCJOzl/Z9SqQ25MNpG/73k71756ftisaaJy75h06/Dn6KOwC4OCMN10ewT2PXMzHV03JNKwBbg==
dependencies:
postcss "^7.0.27"
sort-css-media-queries "1.5.0"
postcss-svgo@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258"
@ -17839,6 +17912,15 @@ postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1:
indexes-of "^1.0.1"
uniq "^1.0.1"
postcss-zindex@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-4.0.1.tgz#8db6a4cec3111e5d3fd99ea70abeda61873d10c1"
integrity sha512-d/8BlQcUdEugZNRM9AdCA2V4fqREUtn/wcixLN3L6ITgc2P/FMcVVYz8QZkhItWT9NB5qr8wuN2dJCE4/+dlrA==
dependencies:
has "^1.0.0"
postcss "^7.0.0"
uniqs "^2.0.0"
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.18, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.23, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.31, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
version "7.0.32"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
@ -20059,6 +20141,11 @@ socks@~2.3.2:
ip "1.1.5"
smart-buffer "^4.1.0"
sort-css-media-queries@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-1.5.0.tgz#8f605ad372caad0b81be010311882c046e738093"
integrity sha512-QofNE7CEVH1AKdhS7L9IPbV9UtyQYNXyw++8lC+xG6iOLlpzsmncZRiKbihTAESvZ8wOhwnPoesHbMrehrQyyw==
sort-keys-length@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188"