Search code examples
javascriptruby-on-railsminifyuglifyjspdfmake

Error when using uglifier to minify the min.js file in rails


I have a rails project, which includes a pdfmake js plugin. I put the pdfmake.min.js file in the assets\javascripts folder and added it into application.js:

//= require pdfmake.min

In staging server, I have related asset settings:

  config.serve_static_assets = true

  config.assets.js_compressor = :uglifier

  # Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = true

  # Generate digests for assets URLs.
  config.assets.digest = true

However, I got an error on staging server:

ReferenceError: Can't find variable: n

This error is not on development environment, so I am guessing it is caused by the js compile. To be detailed, caused when using uglifier:

related source code:

function(module, exports, __webpack_require__) {

    /* WEBPACK VAR INJECTION */(function(Buffer) {// Generated by CoffeeScript 1.7.1
    (function() {
      var DecodeStream, iconv;

      try {
        iconv = __webpack_require__(87);
      } catch (_error) {}

      DecodeStream = (function() {
        var key;

        function DecodeStream(buffer) {
          this.buffer = buffer;
          this.pos = 0;
          this.length = this.buffer.length;
        }

        ......

      })();

      module.exports = DecodeStream;

    }).call(this);  

min.js and the same in local without uglifier

function(t, e, n) {
        (function(e) {
            (function() {
                var r,
                    i;
                try {
                    i = n(84)
                } catch (t) {}
                r = function() {
                    function t(t) {
                        this.buffer = t, this.pos = 0, this.length = this.buffer.length
                    }
                    var n;
                    ......
                }(), t.exports = r
            }).call(this) 

code in application.js after uglifier in staging

function(A, t, e) {
        (function(A) {
            (function() {
                var t,
                    i;
                try {
                    i = e(84)
                } catch (n) {}
                t = function() {
                    function t(A) {
                        this.buffer = A, this.pos = 0, this.length = this.buffer.length
                    }
                    var e;
                    ......
                }(), n.exports = t
            }).call(this) 

According to the above code, we can find that the uglifier assign both module and Buffer to A incorrectly. How can I fix this?

I have some thoughts:

  • Disable uglifier on staging. Is it good for staging and production?
  • Replace the pdfmake.min.js to pdfmake.js.
  • Any other thoughts?

Solution

  • Based on previous experience, I have found that previously minified Javascript can cause uglifier some issues. This may be related to older bugs in uglifier where if it was run with multiple passes over the same code it would fail.

    For a reliable result, use the unminified pdfmake.js so that uglifier should have no issues.

    Also, given that your version of the uglifier gem is from 2014 (see https://github.com/lautis/uglifier/releases?after=v2.5.2 ) you should definitely consider upgrading the uglifier gem to avoid other issues.