clean-css: Having a non-breaking space in css leads to error

Environment

Using clean-css through Angular CLI 1.7.0 which moved to clean-css. clean-css is imported through webpack plugin as it can seen here: https://github.com/angular/angular-cli/blob/master/packages/@angular/cli/plugins/cleancss-webpack-plugin.ts

Configuration options

 const cleancss = new CleanCSS({
          compatibility: 'ie9',
          level: 2,
          inline: false,
          returnPromise: true,
          sourceMap: this._options.sourceMap,
        });

Input SCSS

Image, since non-breaking space would not show up properly (screenshot taken on VSCode on faulty scss code, with Highlight bad characters VSCode plugin):

bad_char

This code was transpiled to CSS, which still contains the non-breaking space. Resulting in following error.

Error

/project/node_modules/clean-css/lib/reader/input-source-map-tracker.js:37 if (originalPosition.line === null && line > 1 && selectorFallbacks > 0) {

TypeError: Cannot read property ‘line’ of undefined at originalPositionFor (/project/node_modules/clean-css/lib/reader/input-source-map-tracker.js:37:24) at originalMetadata (/project/node_modules/clean-css/lib/tokenizer/tokenize.js:486:43) at intoTokens (/project/node_modules/clean-css/lib/tokenizer/tokenize.js:435:68) at tokenize (/project/node_modules/clean-css/lib/tokenizer/tokenize.js:74:10) at fromStyles (/project/node_modules/clean-css/lib/reader/read-sources.js:147:12) at fromString (/project/node_modules/clean-css/lib/reader/read-sources.js:48:10) at doReadSources (/project/node_modules/clean-css/lib/reader/read-sources.js:33:12) at readSources (/project/node_modules/clean-css/lib/reader/read-sources.js:24:10) at /project/node_modules/clean-css/lib/clean.js:99:12 at _combinedTickCallback (internal/process/next_tick.js:131:7) at process._tickCallback (internal/process/next_tick.js:180:9)

Expected behavior

Presence of non-breaking space should not block the production of css since these kind of spaces should be deleted in the minification process.

Potential fix

We could add a marker for no-break space and replace the character with standard space.

NO_BREAK_SPACE: /\u00A0|\u202F|\uFEFF/g,

then in tokenize:

isNoBreakSpace = Marker.NO_BREAK_SPACE.test(character);
...
else if (isNoBreakSpace) {
      // Replace any kind of no-break-space with standard space
      character = Marker.SPACE;
      buffer.push(character);
    }

Can’t open a PR as I don’t know how to test that in your test suit.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 17
  • Comments: 27

Commits related to this issue

Most upvoted comments

Please fix this! Angular CLI cant build because of this!

@barocsi @blackholegalaxy for me the error came from a third party lib (materialize-css) i’m using in my project. I can’t update those css or scss file.

It’s fixed in 4.1.10.

@jakubpawlowicz not sure is it could help but here is a minimal setup to reproduce the issue with angular cli :

$ npm install -g @angular/cli
$ ng new testproject
$ cd testproject
$ npm install materialize-css

Then you have to add materialize.min.css in .angular-cli.json:

...
      "styles": [
        "styles.css",
        "../node_modules/materialize-css/dist/css/materialize.min.css"
      ],
...

And then:

$ ng build --prod
 92% chunk asset optimization/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/reader/input-source-map-tracker.js:37
  if (originalPosition.line === null && line > 1 && selectorFallbacks > 0) {
                      ^

TypeError: Cannot read property 'line' of undefined
    at originalPositionFor (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/reader/input-source-map-tracker.js:37:23)
    at originalMetadata (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/tokenizer/tokenize.js:486:43)
    at intoTokens (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/tokenizer/tokenize.js:435:68)
    at tokenize (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/tokenizer/tokenize.js:74:10)
    at fromStyles (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/reader/read-sources.js:147:12)
    at fromString (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/reader/read-sources.js:48:10)
    at doReadSources (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/reader/read-sources.js:33:12)
    at readSources (/Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/reader/read-sources.js:24:10)
    at /Users/navarro/workspace/tmp/testproject/node_modules/clean-css/lib/clean.js:99:12
    at _combinedTickCallback (internal/process/next_tick.js:95:7)
    at process._tickCallback (internal/process/next_tick.js:161:9)

I’ve been able to reproduce the issue locally, however it’s not entirely clean-css bug but also sass building incorrect source map. I found couple cases when line:column data inside it is invalid (e.g. column being negative causing source-map to explode when verifying it).

However I’ll add some code to handle such cases gracefully.

@angular/cli version must be greater than 1.6.8.

Just a quick real project test with invalid char on scss source. Removed node_modules and let npm install latest clean-css. Tested under 1.6.8, 1.7.0, 1.7.1, 1.7.2:

works

So the fix works. Thanks @jakubpawlowicz

Sure, will fix it in 4.1.10 coming out (hopefully) today.