【问题标题】:Uglify the global variable丑化全局变量
【发布时间】:2015-02-20 06:00:40
【问题描述】:

我在 nodejs 中有一个应用程序。在其中,我定义了一些在多个文件之间共享的全局变量。例如:

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

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

我希望缩小 asyncisAuthenticated 变量,但在所有文件中都缩小为相同的值。如下所示:

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

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

在uglifyjs中怎么做?

我目前正在遍历文件并在每个文件上使用命令 uglifyjs $file -m "sort,toplevel" -c > $file.min

【问题讨论】:

  • 在多个文件之间共享全局范围是一种反模式,更不用说您所说的只是节省 字节
  • 你为什么需要这个?
  • 丑化只会使逆向工程(当然还有调试)变得更加困难,但并非不可能。
  • 我的情况是提供代码而不是提供网络服务。当然,我知道没有任何东西可以完全阻止任何语言的逆向工程。在 JavaScript 世界中,我知道实现它的可能方法是丑化代码。否则,如果您需要交付代码,如何保护您的代码。至于测试,丑化代码中我就不做调试了。在我的构建过程中,我会先测试原始代码,然后再进行丑化。
  • 如果您想保护您的代码,请使用编译语言编写并提供二进制文件。

标签: javascript node.js uglifyjs2


【解决方案1】:

如果您的全局变量仅限于 common.js,您可以尝试

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

并删除require()s

【讨论】:

    【解决方案2】:

    您可能希望在继续丑化文件之前连接文件。 Concatenation 是将多个代码文件组合成一个整体的过程,它知道代码的所有部分。出于多种原因,这通常与丑陋结合一起完成,主要是为了提高性能(如果您只向客户端发送 1 个文件,您的应用运行速度会更快)。

    话虽如此,这通常是在您向客户端提供代码时完成的一种做法,不一定适用于后端/服务器端逻辑。理想情况下,除了您或有权访问您用于部署所述服务器代码的任何服务的人之外,没有人应该看到您代码的那一面。如果您主要关心的是防止逆向工程,或者使您的代码不可读,我建议您的代码obfuscating

    “这是 omega 站点。他拥有的最佳加密级别。看起来像是隐藏其真正目的的混淆代码。通过默默无闻来确保安全。” - Q Skyfall 2012

    【讨论】:

      【解决方案3】:
      • 不要使用全局变量。
      • 在需要时使用var async = reuqire('async')
      • 在您需要的特定模块中使用module.exports
      • 使用 browserify 之类的东西来生成单个 js。
      • Uglify(或使用名为 uglifyify 的 browserify 转换)

      例如最简单的形式(不使用uglifyify)

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

      请注意,如果您使用自己的代码,例如 common.js,您应该要求它使用相对路径,var common = require("./common")

      我建议你使用导出语法:

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

      当然也可以像使用 async.js 一样使用它:

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

      假设common.jsrun.js 位于同一目录中。

      相关问题:How to get minified output with browserify?

      旁注

      您在问题中使用async.series 的方式没有真正的优势。你可以:

      //run.js
      var common = require("./common");
      
      common.isAuthenicated();
      console.log("done");
      

      在异步系列中,您通常调用异步函数:

      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']
      }); 
      

      所以,我希望看到类似的内容:

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

      然后

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

      我通常更喜欢不同的“语法”

      // 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}
      });
      

      但这是你的决定。 异步示例取自https://github.com/caolan/async#seriestasks-callback

      【讨论】:

        【解决方案4】:

        在 NodeJs 中有定义global 变量的概念,就像在this 线程中发布的那样:

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

        我在我的节点应用程序中也使用了 uglify,结果发现在使用 global.xyz 时,xyz 没有得到 uglify。

        免责声明:我完全知道公开全球信息是一种反模式。但有时这样做是有充分理由的。

        希望有帮助!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多