最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Uglify the global variable - Stack Overflow

programmeradmin2浏览0评论

I have an app in nodejs. In it, I define some global variables that are shared across multiple files. For example:

//mon.js
async = requires("async");
isAuthenticated = function() {
  //...
  return false;
};

//run.js
require("mon.js");
async.series([function () {
  isAuthenicated();
}], function () {
  console.log("done");
});

I want the async and isAuthenticated variables to be minified, but minified to the same thing in all files. It would look like the following:

//mon.min.js
a = requires("async");
b = function() {
  //...
  return false;
};

//run.min.js
require("mon.js");
a.series([function () {
  b();
}], function () {
  console.log("done");
});

How to do it in uglifyjs?

I'm currently looping through the files and using the mand uglifyjs $file -m "sort,toplevel" -c > $file.min on each.

I have an app in nodejs. In it, I define some global variables that are shared across multiple files. For example:

//mon.js
async = requires("async");
isAuthenticated = function() {
  //...
  return false;
};

//run.js
require("mon.js");
async.series([function () {
  isAuthenicated();
}], function () {
  console.log("done");
});

I want the async and isAuthenticated variables to be minified, but minified to the same thing in all files. It would look like the following:

//mon.min.js
a = requires("async");
b = function() {
  //...
  return false;
};

//run.min.js
require("mon.js");
a.series([function () {
  b();
}], function () {
  console.log("done");
});

How to do it in uglifyjs?

I'm currently looping through the files and using the mand uglifyjs $file -m "sort,toplevel" -c > $file.min on each.

Share Improve this question edited Dec 26, 2014 at 9:46 ATNASGDWNGTH asked Dec 22, 2014 at 6:30 ATNASGDWNGTHATNASGDWNGTH 87612 silver badges26 bronze badges 9
  • 3 Sharing the global scope between multiple files is an anti-pattern, not to mention you are talking about a savings of mere bytes. – Evan Davis Commented Dec 24, 2014 at 19:23
  • Why do you need this at all? – Vsevolod Goloviznin Commented Dec 24, 2014 at 21:23
  • 2 Uglyfying will make reverse engineering (and debugging of course) only harder but not impossible. – try-catch-finally Commented Dec 26, 2014 at 10:36
  • 1 My situation is delivering the codes and not providing a web service. Of course, I know there is no something which can pletely prevent from reverse engineering in any languages. In JavaScript world, what I know the possible way to achieve it is uglifying the code. Otherwise how do you protect your code if you need to deliver the code. As for the testing, I will not do the debugging in the uglified code. In my build process, I will test the original code first before uglifying. – ATNASGDWNGTH Commented Dec 26, 2014 at 13:58
  • 1 If you want to protect your code, write it in a piled language and provide binaries. – user663031 Commented Dec 27, 2014 at 7:42
 |  Show 4 more ments

4 Answers 4

Reset to default 6 +25
  • Don't use globals.
  • Use var async = reuqire('async') where needed.
  • Use module.exports in your specific modules you require.
  • Use something like browserify to generate a single js.
  • Uglify (or use a browserify transform named uglifyify)

For example, the simplest form (without using uglifyify)

$ browserify run.js | uglifyjs -c > run.min.js

Note that if you use your own code, like mon.js, you should require it using a relative path, var mon = require("./mon").

I suggest you use the exports syntax:

// mon.js code

exports.isAuthenticated = function() {
  //...
  return false;
};

And of course use it just as you would with async.js:

//run.js
var mon = require("./mon");
var async = require("async")
async.series([function () {
  mon.isAuthenicated();
}], function () {
  console.log("done");
});

assuming both mon.js & run.js reside in the same directory.

related question: How to get minified output with browserify?

A Side Note

The way you used async.series in your question has no real advantage. You could have just:

//run.js
var mon = require("./mon");

mon.isAuthenicated();
console.log("done");

in Async series you usually call async functions:

async.series([
    function(callback){
        // do some stuff ...
        callback(null, 'one');
    },
    function(callback){
        // do some more stuff ...
        callback(null, 'two');
    }
],
// optional callback
function(err, results){
    // results is now equal to ['one', 'two']
}); 

so, I would expect to see something like:

// mon.js code

exports.isAuthenticated = function(callback) {
  //...
  callback(null, false);
};

and then

//run.js
var mon = require("./mon");
var async = require("async")
async.series([mon.isAuthenicated], function (err, results) {
  console.log("done with", results[0]);
});

I usually prefer a different "syntax"

// an example using an object instead of an array
async.series({
    one: function(callback){
        setTimeout(function(){
            callback(null, 1);
        }, 200);
    },
    two: function(callback){
        setTimeout(function(){
            callback(null, 2);
        }, 100);
    }
},
function(err, results) {
    // results is now equal to: {one: 1, two: 2}
});

But it's your call. The async examples were taken from https://github./caolan/async#seriestasks-callback

You would want to concat the files before you go ahead and uglify them. Concatenation is the process of bining multiple files of code into one monolithic creature that knows everything about all parts of your code. This is often done in conjunction with uglyfying for several reasons, mainly for performance benefits (your app runs a lot faster if you only send 1 file to the client).

That being said, this is typically a practice that is done when your serving code to a client, not necessarily for back-end / server-side logic. Ideally no one but you or people with access to whatever service you're using to deploy said server code should see that side of your code. If your main concern is to prevent reverse-engineering, or make your code unreadable, I suggest obfuscating your code.

"This is omega site. Best encrypted level he has. Looks like obfuscated code to conceal its true purpose. Security through obscurity." - Q Skyfall 2012

If your globals are confined to mon.js, you may try

uglifyjs --define-from-module mon.js $file...

and remove require()s.

In NodeJs there is the concept of defining global variables like posted in this thread:

global.myGlobalVar = "something visible to all modules";

I am too using uglify in my node apps, and it turned out that when using global.xyz, xyz does not get uglified.

disclaimer: I am totally aware that exposing global info is an anti pattern. But sometimes there is a good reason for it.

Hope that helps!

发布评论

评论列表(0)

  1. 暂无评论