Removing code for production

245 views
Skip to first unread message

Tauren Mills

unread,
Apr 8, 2012, 2:07:11 PM4/8/12
to ugli...@googlegroups.com
I'd like to remove some code for production and think UglifyJS is the tool for the job. Before I begin to tackle this, can anyone confirm that Uglify can be used to solve the problem described below?  I'd really appreciate it if someone could point me to any examples that do this or would give some suggestions on how to get started.

I have a logger implementation that support contexts, loglevels, and appenders used during development. I'd like to remove all logging code for production. Below is an example of a module in my codebase. I've added comments around what I want to be removed.

```js
!function($, Application, Logger, exports) {

  // START REMOVE 
  Logger.configure([
    {context: 'nike.profile.core.Application', level: Logger.LOG, save: true},
    {context: 'nike.profile.models.Account', level: Logger.WARN, save: true},
    {context: 'nike.profile.models.User', level: Logger.INFO, save: true}
  ]);
  // END REMOVE

  // START REMOVE 
  var logger = Logger.getLogger(exports.namespace+'.app');
  // END REMOVE
  
  // Create an instance of Application
  var app = new Application();

  // Only one Application instance should exist
  exports.app = app;

  $(function() {
    // START REMOVE
    logger.log('Log');
    logger.debug('Debug');
    logger.info('Info');
    logger.warn('Warning');
    logger.error('Error');
    // END REMOVE
    app.start();
  });

}(
  window.jQuery,
  window.nike.profile.core.Application,
  window.nike.util.Logger,
  window.nike.ns('nike.profile')
);
```js

As you can see, I'd like to find any use of the `Logger` class and remove it. In addition, I'd like to remove all code that uses instances of the Logger class as well. 

I need to analyze the code to determine when an instance of Logger is created, note the name of that instance, and then remove any code that use that name. Obviously, this could get complex if usage is embedded within lines of code.

To simplify things, I can make sure that all usage of the code I'm trying to replace is limited to lines of code that follow the following formats:

Logger.configure(...);
var logger = Logger.getLogger(...);
logger.log(...);
logger.debug(...);
logger.warn(...);
logger.error(...);

I can also make sure to be consistent about how I name logger instances. I can make sure that all instances begin with the name `logger`. This would include `logger`, `logger1`, `logger_xyz`, etc. No other non-logging variable names used anywhere in the application would start with the word `logger`.

Thanks,
Tauren

Tim Meadowcroft

unread,
May 9, 2012, 1:42:33 PM5/9/12
to ugli...@googlegroups.com


On Sunday, 8 April 2012 19:07:11 UTC+1, Tauren Mills wrote:
I'd like to remove some code for production and think UglifyJS is the tool for the job. Before I begin to tackle this, can anyone confirm that Uglify can be used to solve the problem described below?  I'd really appreciate it if someone could point me to any examples that do this or would give some suggestions on how to get started.


I added a feature to uglifyjs for precisely this sort of "production" use - in this way I use uglifyjs in a way similar to the C preprocessor to entirely remove code blocks by telling uglifyjs it should consider certain symbols to have specific defined values, and then using the inherent "dead code removal" feature.


In particular, my "un-uglified code" includes 

 if (typeof DEVELOPMENT === "undefined") DEVELOPMENT = true;
 if (typeof PRODUCTION === "undefined") PRODUCTION = false;

This way, in development, I can have things like

  if (DEVELOPMENT) {
    Logger.configure([
    {context: 'nike.profile.core.Application', level: Logger.LOG, save: true},
    {context: 'nike.profile.models.Account', level: Logger.WARN, save: true},
    {context: 'nike.profile.models.User', level: Logger.INFO, save: true}
    ]);
  }

and then, when I uglify my code with command lines args "--define PRODUCTION=true --define DEVELOPMENT=false" (in addition to any others) then the entire block will be removed (including the 'if' test itself).

I don't really need both symbols, but it sometimes makes my intent clearer.

I also use this for setting certain flags or initialising values in debug/production mode etc

Cheers

--
Tim

Reply all
Reply to author
Forward
Message has been deleted
0 new messages