Skip to content

An AMD build tool that converts AMD code to standard JavaScript

License

Notifications You must be signed in to change notification settings

Rich-Harris/amdclean

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

#amdclean

A build tool that converts AMD code to standard JavaScript.

Build Status

npm install amdclean

Use Case

Single file client-side JavaScript libraries that want to use AMD to structure and build their code, but don't want an AMD footprint.

Why

Many developers like to use the AMD API to write modular JavaScript, but do not want to include a full AMD loader (e.g. require.js), or AMD shim (e.g. almond.js) because of file size/source code readability.

By incorporating amdclean.js into the build process, there is no need for Require or Almond.

Since AMDclean rewrites your source code into standard JavaScript, it is a great fit for JavaScript library authors who want a tiny download in one file after using the RequireJS Optimizer.

So, you get great code cleanliness with AMD, reduced file sizes, improved code readability, and easy integration with other developers who may not use AMD.

Restrictions

Note: Same restrictions as almond.js, plus a few more.

It is best used for libraries or apps that use AMD and:

  • optimize all the modules into one file -- no dynamic code loading.
  • do not use AMD loader plugins (e.g. text! plugin)
  • only have one require.config() call

##What is Supported

  • define() and require() calls.

  • Simplified CJS wrapper

  • Exporting global modules to the window object

  • Storing all local modules inside of a global object (Helps scoping issues for certain use cases)

Download

Node - npm install amdclean

Web - Latest release

Usage

There are a few different ways that amdclean can be used including:

  • With the RequireJS Optimizer (Grunt is also supported)

  • As a standalone node module

  • As a client-side library

###RequireJS Optimizer

paths: {

	'first': '../modules/firstModule',

	'second': '../modules/secondModule',

	'third': '../modules/thirdModule'

}
  • Update the onBuildWrite property in your RequireJS build configuration file. Like this:
onBuildWrite: function (moduleName, path, contents) {
    return module.require('amdclean').clean(contents);
}
  • Run the optimizer using Node (also works in Java). More details can be found in the the r.js repo.

  • If you are using the RequireJS optimizer Grunt task, then it is very easy to integrate amdclean using the onBuildWrite config option. Here is an example Grunt file that includes the RequireJS optimizer plugin with amdclean support:

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    requirejs: {
      js: {
        options: {
          findNestedDependencies: true,
          baseUrl: 'src/js/app/modules',
          wrap: true,
          preserveLicenseComments: false,
          optimize: 'none',
          mainConfigFile: 'src/js/app/config/config.js',
          include: ['first'],
          out: 'src/js/app/exampleLib.js',
          onBuildWrite: function( name, path, contents ) {
            return require('amdclean').clean(contents);
          }
        }
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.registerTask('build', ['requirejs:js']);
  grunt.registerTask('default', ['build']);
};

###Node Module

  • npm install amdclean

  • Require the module

var cleanAMD = require('amdclean');
  • Call the clean method
var code = 'define("exampleModule", function() {});'
var cleanedCode = cleanAMD.clean(code);

###Client-side Library

  • Include all dependencies
<script src="http://esprima.org/esprima.js"></script>
<script src="http://esprima.org/test/3rdparty/escodegen.browser.js"></script>
<script src="http://gregfranko.com/javascripts/estraverse.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.2.1/lodash.js"></script>
<script src="http://gregfranko.com/javascripts/amdclean.js"></script>
  • Use the global amdclean object and clean() method
var cleanedCode = amdclean.clean('define("example", [], function() { var a = true; });');

Requirements

Optional Dependencies

How it works

amdclean uses Esprima to generate an AST (Abstract Syntax Tree) from the provided source code, estraverse to traverse and update the AST, and escodegen to generate the new standard JavaScript code. There are a few different techniques that amdclean uses to convert AMD to standard JavaScript code:

###Define Calls

AMD

define('example', [], function() {

});

Standard

var example = function () {

}();

AMD

define('example', ['example1', 'example2'], function(one, two) {

});

Standard

var example = function (one, two) {

}(example1, example2);

AMD

define('third',{
	exampleProp: 'This is an example'
});

Standard

var third = {
	exampleProp: 'This is an example'
};

###Require Calls

Note: require(['someModule']) calls are removed from the built source code

AMD

require([], function() {
	var example = true;
});

Standard

(function () {
    var example = true;
}());

AMD

require(['anotherModule'], function(anotherModule) {
	var example = true;
});

Standard

(function (anotherModule) {
    var example = true;
}(anotherModule));

##Options

The amdclean clean() method accepts a string or an object. Below is an example objects with all of the available configuration options:

amdclean.clean({
	// The source code you would like to be 'cleaned'
	code: 'define("example", [], function(one, two) {});',
  // The modules that you would like to set as window properties
  // An array of strings (module names)
  globalModules: [],
  // Determines if all of your local modules are stored in a single global object (helps with scoping in certain cases)
  globalObject: false,
  // Determines the name of your global object that stores all of your global modules
  globalObjectName: 'amdclean',
	// All esprima API options are supported: http://esprima.org/doc/
	esprima: {},
	// All escodegen API options are supported: https://github.com/Constellation/escodegen/wiki/API
	escodegen: {}
})

Unit Tests

All unit tests are written using the jasmine-node library and can be found in the test/specs/ folder.

FAQ

Why would I use amdclean instead of Almond.js?

  • Although Almond is very small (~1k gzipped and minified), most JavaScript library authors do not want to have to include it in their library's source code. If you are not using an AMD plugin, then amdclean provides the benefit of AMD without increasing your library's file size.

What if I don't want all define() and require() method calls to be removed?

  • If you don't want one or more define() and require() methods to be removed by amdclean, then you must put a comment with only the words amdclean on the same line or one line above the method in question. For example, amdclean would not remove the define() method below:
// amdclean
define('example', [], function() {});

Why are define() method placeholder functions inserted into my source?

  • This is the default behavior of r.js when a module(s) is not wrapped in a define() method. Luckily, this behavior can be overridden by setting the skipModuleInsertion option to true in your build configuration.

How would I expose one or more modules as a global window property?

  • You can use the globalModules option to list all of the modules that you would like to expose as a window property

I am having a scope problem with all of the local module variables. What can I do?

  • You can use the globalObject option to store all of your modules in a global object that uses the top-most function scope.

License

Copyright (c) 2013 Greg Franko Licensed under the MIT license.

About

An AMD build tool that converts AMD code to standard JavaScript

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%