js-kyle / mincer

Sprockets inspired web assets compiler for Node.js
http://js-kyle.github.io/mincer/
MIT License
628 stars 84 forks source link

Sourcemaps combined with Autoprefixer fails #214

Closed jeroenvisser101 closed 8 years ago

jeroenvisser101 commented 8 years ago

I've tried to debug this issue a few times already, but never had enough time, but since this issue is getting an issue more and more, I'd like to ask for help here.

For some reason, if I have my configuration with:

environment.enable('autoprefixer');
environment.enable('source_maps');

...there are a few assets (note: these assets are plain CSS, no SASS) fail within the Context.prototype.createSourceMapObject function. It seems that these files pass obj.map as an object, not as a string, and when that happens, JSON.parse fails.

I'm not sure why obj.map is a object here, since this function doesn't expect that at all. I tried to patch this, by catching the JSON parse error, and just passing obj.map as map directly, and that works.

    try {
      map = JSON.parse(obj.map);
    } catch (ex) {
      map = obj.map;
    }

That is again just a workaround, but I wasn't able to dig any further.

(I also have some backtraces, which I don't think are of many help, but attaching them anyways)

SyntaxError: Unexpected token o
  at Object.parse (native)
  at [object Object].Context.createSourceMapObject (/path/to/project/node_modules/mincer/lib/mincer/context.js:584:18)
  at /path/to/project/node_modules/mincer/lib/mincer/assets/bundled.js:78:25
  at Array.forEach (native)
  at new BundledAsset (/path/to/project/node_modules/mincer/lib/mincer/assets/bundled.js:77:20)
  at Index.Base.buildAsset (/path/to/project/node_modules/mincer/lib/mincer/base.js:535:12)
  at /path/to/project/node_modules/mincer/lib/mincer/index.js:141:26
  at Index.module.exports.cacheAsset (/path/to/project/node_modules/mincer/lib/mincer/helpers/caching.js:60:11)
  at Index.buildAsset (/path/to/project/node_modules/mincer/lib/mincer/index.js:140:33)
  at Index.Base.findAsset (/path/to/project/node_modules/mincer/lib/mincer/base.js:348:15)
  at Index.findAsset (/path/to/project/node_modules/mincer/lib/mincer/index.js:114:22)
  at Environment.findAsset (/path/to/project/node_modules/mincer/lib/mincer/environment.js:137:21)
  at /path/to/project/node_modules/mincer/lib/mincer/manifest.js:222:30
  at Array.forEach (native)
  at Manifest.compile (/path/to/project/node_modules/mincer/lib/mincer/manifest.js:219:9)
  at /path/to/project/mincer.js:62:14
  at Array.forEach (native)
  at Object.<anonymous> (/path/to/project/mincer.js:14:10)

And package.json dependencies:

  {
    "npm": "^3.3.0",
    "gulp": "^3.8.8",
    "gulp-shell": "^0.2.9",
    "node-sass": "3.4.2",
    "mincer": "^1.4.0",
    "autoprefixer": "^6.1.0",
    "csswring": "^4.0.0",
    "postcss": ">=4.1.0",
    "coffee-script": "^1.10.0",
    "uglify-js": "^2.4.15",
    "ejs": "^1.0.0",
    "commander": "^2.8.0"
  }
puzrin commented 8 years ago

There was a long story of autoprefixer mutations - package name & signature change. Probably, feature loss happened at some point. It worth to check that atoprefixer map output is in string format, not an object https://github.com/nodeca/mincer/blob/master/lib/mincer/processors/autoprefixer.js#L88.

jeroenvisser101 commented 8 years ago

@puzrin thanks! I'll check that out now, and if that's it, create a PR

puzrin commented 8 years ago

https://github.com/nodeca/mincer/blob/master/lib/mincer/compressors/csswring_compressor.js#L72

Probably csswring can have the same problem, because it uses exactly the same engine.

jeroenvisser101 commented 8 years ago

So typeof this.map == 'string' should evaluate to true, correct?

jeroenvisser101 commented 8 years ago

It seems to be csswring indeed, console.log'ing it's this.map gives an instance of SourceMapGenerator:

SourceMapGenerator {
  _file: 'application.css',
  _sourceRoot: null,
  _skipValidation: false,
  _sources:
   ArraySet {
     _array:
      [ 'application.css',
        ...
        'styleguide/typography.scss' ],
     _set:
      { '$application.css': 0,
        ...
        '$styleguide/typography.scss': 218 } },
  _names: ArraySet { _array: [], _set: {} },
  _mappings:
   MappingList {
     _array:
      [ [Object],
       ...
        [Object],
puzrin commented 8 years ago

https://github.com/mozilla/source-map#sourcemapgeneratorprototypetostring i guess .toString() should help.

jeroenvisser101 commented 8 years ago

@puzrin got it! It was autoprefixer after all, committing now and submitting for review!