Search code examples
requirejsobfuscationamdrequirejs-optimizer

Replace module ids with fake names


Imagine an AMD Java-Script Application consisting of three modules with those IDs:

  • common/core/api
  • common/data/foo
  • common/remote/bar

When I'm building the optimized file with r.js, those ids are still inside compiled file. IMO this is unnecessary. For example, the optimized file would still work when I search-and-replace the following:

  • common/core/api -> a
  • common/data/foo -> b
  • common/remote/bar -> c

The advantages of the substitutions are:

  1. smaller filesize
  2. better obscurity
    (Yes, you should never trust the client. Still, substituting the module names would require a reverse engeneer to guess a lot more than finding imporant parts of the application right away through module names)

Is there a reason I'm missing why this isn't done or an additional tool/command to substitute those IDs with some auto generated id?


Solution

  • The advantages of the substitutions are:

    1. smaller filesize

    Barely. I doubt on real projects you'd be able to even get 1% size reduction.

    1. better obscurity

    The obscurity would be nominally better but I doubt someone who would be okay dealing with minified code would be fazed by this additional obfuscation.

    Is there a reason I'm missing why this isn't done

    The reasons this isn't done:

    1. RequireJS would still have to operate as it currently does because for many uses, renaming modules to arbitrary values is not acceptable. (It is the case everywhere I use RequireJS.) So this would add additional code paths to r.js, that would have to be tested.

    2. There would be cases where RequireJS would be flat out incapable of performing the renaming. Consider this:

      define(function (require) {
      var deps = ['a', 'b'];
      if (some_condition)
          deps.push('c');
      require(deps, function () { ... });
      });
      

      RequireJS is unable to trace the dependencies in the require call because the token deps is not a literal array of strings. However, it is currently possible to compensate in the configuration passed to r.js: a, b, c can be listed as explicit inclusions. Problem solved. However, if r.js renames modules, the names a, b, and c would have to be automatically altered. To do this, r.js would have to use a JavaScript parser to parse the code and alter it. It is unclear that in the general case it would be able to figure out what it needs to alter.

    3. Ultimately, if r.js were altered to do it when it can, it would make r.js much more complex than it is in order to deal with a rather specialized need, which can be handled outside r.js.

    or an additional tool/command to substitute those IDs with some auto generated id?

    There is no tool or configuration option to do this for you. Whatever r.js would do for you could in theory be done as a build phase before r.js is invoked. You'd have to write your own tool to perform the transformation before passing the files to r.js.