Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

build: gulp-cssnano is deprecated and causes audit warnings #11869

Closed
Splaktar opened this issue Mar 6, 2020 · 3 comments
Closed

build: gulp-cssnano is deprecated and causes audit warnings #11869

Splaktar opened this issue Mar 6, 2020 · 3 comments
Assignees
Labels
P3: important Important issues that really should be fixed when possible. type: build
Milestone

Comments

@Splaktar
Copy link
Member

Splaktar commented Mar 6, 2020

Build issue

What is the expected behavior?

Ideally, we'd like to minimize the audit warnings from npm audit.

What is the current behavior?

gulp-cssnano generates a Moderate and High audit warning.

Additionally, the gulp-cssnano repo has been archived and marked DEPRECATED.

What is the use-case or motivation for changing an existing behavior?

npm audit reports the following:

# Run  npm install --save-dev cssnano@4.1.10  to resolve 2 vulnerabilities
SEMVER WARNING: Recommended action is a potentially breaking change
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Denial of Service                                            │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ js-yaml                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ cssnano [dev]                                                │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ cssnano > postcss-svgo > svgo > js-yaml                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/788                             │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Code Injection                                               │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ js-yaml                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ cssnano [dev]                                                │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ cssnano > postcss-svgo > svgo > js-yaml                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/813                             │
└───────────────┴──────────────────────────────────────────────────────────────┘

As you can see the culprit is js-yaml which is brought in by svgo.

Which versions of AngularJS, Material, OS, and browsers are affected?

  • AngularJS: 1.1.21
  • AngularJS Material: 1.7.8
  • OS: macOS
  • Browsers: Chrome
@Splaktar Splaktar self-assigned this Mar 6, 2020
@Splaktar Splaktar added this to the - Backlog milestone Mar 6, 2020
@Splaktar
Copy link
Member Author

Splaktar commented Mar 6, 2020

So I just finished investigating this. NPM tells us that we need to use cssnano@4.1.10.

With gulp-cssnano being deprecated, the new recommendation is to use cssnano with gulp-postcss.

I was able to get everything plumbed together just fine with gulp-postcss using cssnano() as a plugin with their new Preset system:

Before

function minifyCss(extraOptions) {
  const options = {
    autoprefixer: false,
    reduceTransforms: false,
    svgo: false,
    safe: true
  };

  return gulpCssnano(_.assign(options, extraOptions));
}

After

The safe option was removed in cssnano@4.
The autoprefixer is disabled in the default preset.

function minifyCss(extraOptions) {
  const options = {
    reduceTransforms: false,
    svgo: false
  };
  const preset = {
    preset: [
      'default',
      _.assign(options, extraOptions)
    ]
  };

  return gulpPostcss([cssnano(preset)]);
}

Result

Unfortunately the result was unacceptable. The minified output previously was 367 KB of CSS. The new minified output is 390 KB. This is an increase of 23 KB just because we're changing the version of cssnano!

There are some release notes about how cssnano is a smaller download from NPM now. There are also mentions about how the build time performance has improved. Additionally, they've moved some of the less-safe optimizations to the Advanced Preset.

So I thought that I'd try the Advanced Preset. Unfortunately, that did not solve the primary cause of the CSS bloat.

Here's what I was seeing

Output with gulp-cssnano and cssnano@3

.md-dense :not(.md-dense-disabled) .md-button:not(.md-dense-disabled), .md-dense > .md-button:not(.md-dense-disabled) {
  min-height: 32px;
  line-height: 32px;
  font-size: 13px
}

[dir=rtl] md-checkbox {
  margin-left: 16px;
  margin-right: 0
}

  .flex-gt-xs-50, .layout-row > .flex-gt-xs-50 {
    -webkit-box-flex: 1;
    flex: 1 1 100%;
    max-width: 50%;
    max-height: 100%;
    box-sizing: border-box
  }

  .md-datepicker-open .md-datepicker-triangle-button, .md-datepicker-open.md-input-has-placeholder > label, .md-datepicker-open.md-input-has-value > label, .md-datepicker-pos-adjusted .md-datepicker-input-mask {
    display: none
  }

Output with gulp-postcss and cssnano@4

.md-dense :not(.md-dense-disabled) .md-button:not(.md-dense-disabled), .md-dense > .md-button:not(.md-dense-disabled) {
  min-height: 32px
}
.md-dense :not(.md-dense-disabled) .md-button:not(.md-dense-disabled), .md-dense > .md-button:not(.md-dense-disabled) {
  line-height: 32px
}
.md-dense :not(.md-dense-disabled) .md-button:not(.md-dense-disabled), .md-dense > .md-button:not(.md-dense-disabled) {
  font-size: 13px
}

[dir=rtl] md-checkbox {
  margin-left: 16px
}
[dir=rtl] md-checkbox {
  margin-right: 0
}

  .flex-gt-xs-50 {
    -webkit-box-flex: 1;
    flex: 1 1 100%;
    max-width: 50%;
    max-height: 100%;
    box-sizing: border-box
  }

  .layout-row > .flex-gt-xs-50 {
    -webkit-box-flex: 1;
    flex: 1 1 100%;
    max-width: 50%;
    max-height: 100%;
    box-sizing: border-box
  }

  .md-datepicker-open .md-datepicker-triangle-button, .md-datepicker-open.md-input-has-placeholder > label, .md-datepicker-open.md-input-has-value > label {
    display: none
  }
  .md-datepicker-pos-adjusted .md-datepicker-input-mask {
    display: none
  }

There are some bugs (cssnano/cssnano#805, cssnano/cssnano#701) reported against their mergeRules optimization, but I'm not sure if that's the issue or not.

There are also some issues (cssnano/cssnano#620, cssnano/cssnano#385) about the update from cssnano@3 to cssnano@4 increasing the output size. But they are closed out and it's not clear that they are real/current issues.

@Splaktar
Copy link
Member Author

Splaktar commented Mar 6, 2020

Removing gulp-autoprefixer and using autoprefixer() as a plugin to gulp-postcss instead brought the minified CSS down to 333 KB, a 34 KB savings.

The seeming duplication of some selectors mentioned in the previous comment is still happening, but the reduction of many --webkit prefixed rules more than makes up for it.

@Splaktar Splaktar modified the milestones: - Backlog, 1.1.23 Mar 6, 2020
@Splaktar Splaktar modified the milestones: 1.1.23, 1.2.0 May 5, 2020
@Splaktar Splaktar added the P3: important Important issues that really should be fixed when possible. label May 5, 2020
@Splaktar
Copy link
Member Author

PR #11870 closes this in e8e8ac8.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
P3: important Important issues that really should be fixed when possible. type: build
Projects
None yet
Development

No branches or pull requests

1 participant