Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
#AMDclean
A build tool that converts AMD code to standard JavaScript.
npm install amdclean --save-dev
Single file client-side JavaScript libraries or web apps that want to use AMD and/or CommonJS modules to structure and build their code, but don't want any additional footprint.
AMDclean - A build tool that converts AMD code to standard JavaScript (this is not a typo)
GifShot - JavaScript library that can create animated GIFs from media streams, videos, or images
Ractive.js - Next-generation DOM manipulation
Mod.js - JavaScript Workflow Tooling
Formatter.js - Format user input to match a specified pattern
Backbone-Require-Boilerplate - A Rad Backbone.js and Require.js Boilerplate Project
AddThis Smart Layers - Third-party social widgets suite
Extended JavaScript Console - Better browser console methods
Many developers like to use the AMD and/or CommonJS (CJS) module APIs to write modular JavaScript, but do not want to include a full AMD or CJS loader (e.g. require.js), or shim (e.g. almond.js, browserify) because of file size/source code readability concerns.
By incorporating AMDclean.js into the build process, you no longer need to include Require.js or Almond.js in production, or use Browserify.
Since AMDclean rewrites your source code into standard JavaScript, it is a great fit for JavaScript library/web app authors who want a tiny download in one file after using the RequireJS Optimizer. AMDclean uses multiple different optimization algorithms to create the smallest file possible, while still making your code readable.
Note: Same restrictions as almond.js.
It is best used for libraries or apps that use AMD or CommonJS (using the cjsTranslate Require.js optimizer option) and optimize all modules into one file or multiple bundles. If you do not include Require.js or a similar loader, you cannot dynamically load code.
Can be used for both full-fledged web apps and/or individual JavaScript libraries.
transformAMDChecks
option is set to false
. Like this: {
// Will not transform conditional AMD checks - Libraries use this to provide optional AMD support
'transformAMDChecks': false
}
define()
and require()
calls.
window
objectNode - npm install amdclean --save-dev
Web - Latest release
There are a few different ways that AMDclean can be used including:
With the RequireJS Optimizer (plain node, Grunt, Gulp, etc)
As a standalone node module
As a client-side library
Note: AMDclean does not have any module ordering logic, so if you do not use the RequireJS optimizer then you need to find another solution for resolving module dependencies before your files can be "cleaned".
npm install amdclean --save-dev
Add a onModuleBundleComplete
config property to your RequireJS build configuration file instead. Like this:
onModuleBundleComplete: function (data) {
var fs = module.require('fs'),
amdclean = module.require('amdclean'),
outputFile = data.path,
cleanedCode = amdclean.clean({
'filePath': outputFile
});
fs.writeFileSync(outputFile, cleanedCode);
}
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 onModuleBundleComplete
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',
'optimize': 'none',
'mainConfigFile': 'src/js/app/config/config.js',
'include': ['first'],
'out': 'src/js/app/exampleLib.js',
'onModuleBundleComplete': function (data) {
var fs = require('fs'),
amdclean = require('amdclean'),
outputFile = data.path;
fs.writeFileSync(outputFile, amdclean.clean({
'filePath': outputFile
}));
}
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('build', ['requirejs:js']);
grunt.registerTask('default', ['build']);
};
onModuleBundleComplete
config option. Here is an example Gulp task that includes the RequireJS optimizer node module with AMDclean support:gulp.task('build', function() {
var requirejs = require('requirejs');
requirejs.optimize({
'findNestedDependencies': true,
'baseUrl': './src/',
'optimize': 'none',
'include': ['first'],
'out': './build/example.js',
'onModuleBundleComplete': function(data) {
var fs = require('fs'),
amdclean = require('amdclean'),
outputFile = data.path;
fs.writeFileSync(outputFile, amdclean.clean({
'filePath': outputFile
}));
}
});
});
npm install amdclean --save-dev
Require the module
var amdclean = require('amdclean');
var code = 'define("exampleModule", function() {});'
var cleanedCode = amdclean.clean(code);
<script src="http://esprima.org/esprima.js"></script>
<script src="http://constellation.github.io/escodegen/escodegen.browser.js"></script>
<script src="https://rawgithub.com/Constellation/estraverse/master/estraverse.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.2.1/lodash.js"></script>
<script src="https://rawgithub.com/gfranko/amdclean/master/src/amdclean.js"></script>
amdclean
object and clean()
methodvar cleanedCode = amdclean.clean('define("example", [], function() { var a = true; });');
Esprima 1.0+
Lodash 2.2.1+
Estraverse 1.3.1+
Escodegen 0.0.27+
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.
Note: If you are interested in how this works, watch this presentation about building Static Code Analysis Tools.
Here are a few different techniques that AMDclean uses to convert AMD to standard JavaScript code:
AMD
define('example', [], function() {
});
Standard
var example;
example = undefined;
AMD
define('example', [], function() {
var test = true;
});
Standard
var example;
example = function () {
var test = true;
}();
AMD
define('example', [], function() {
return function(name) {
return 'Hello ' + name;
};
});
Standard
var example;
example = function (name) {
return 'Hello ' + name;
};
AMD
define('example', [], function() {
return 'I love AMDclean';
});
Standard
var example;
example = 'I love AMDclean';
AMD
define('example', ['example1', 'example2'], function(one, two) {
var test = true;
});
Standard
var example;
example = function (one, two) {
var test = true;
}(example1, example2);
AMD
define("backbone", ["underscore","jquery"], (function (global) {
return function () {
var ret, fn;
return ret || global.Backbone;
};
}(this)));
Standard
var backbone;
backbone = window.Backbone;
AMD
define('third',{
exampleProp: 'This is an example'
});
Standard
var third;
third = {
exampleProp: 'This is an example'
};
Note: require(['someModule'])
calls, with no callback function, are removed from the built source code
AMD
require([], function() {
var example = true;
});
Standard
(function () {
var example = true;
}());
AMD
require(['anotherModule'], function(someModule) {
var example = true;
});
Standard
(function (someModule) {
var example = true;
}(anotherModule));
AMDclean uses a few different strategies to decrease file size:
Remove Unused Dependencies/Parameters
AMD
define('example', ['example1', 'example2'], function() {
var test = true;
});
Standard
// Since no callback parameters were provided in the AMD code,
// the 'example1' and 'example2' dependencies/parameters were not added
var example;
example = function() {
var test = true;
}();
Remove Exact Matching Dependencies/Parameters
AMD
define('example', ['example1', 'example2'], function(example1, anotherExample) {
var test = true;
});
Standard
// Since the `example1` callback function parameter exactly matched
// the name of the `example1 dependency, it's `example1` dependency/parameter was removed
var example;
example = function(anotherExample) {
var test = true;
}(example2);
Hoist Common Non-Matching Dependencies
aggressiveOptimizations
option to true
AMD
define('example', ['example1'], function(firstExample) {
var test = true;
});
define('anotherExample', ['example1'], function(firstExample) {
var test = true;
});
Standard
// Since the `firstExample` callback function parameter was used more
// than once between modules, it was hoisted up and reused
var example, firstExample;
firstExample = example1;
example = function() {
var test = true;
};
anotherExample = function() {
var test = true;
};
The amdclean clean()
method accepts a string or an object. Below is an example object with all of the available configuration options:
amdclean.clean({
// The source code you would like to be 'cleaned'
'code': '',
// Provide a source map for the code you'd like to 'clean'
// Output will change from plain code to a hash: {code: ..., map: ...}
// Where code is 'cleaned' code and map is the new source map
'sourceMap': null,
// Determines if certain aggressive file size optimization techniques
// will be used to transform the soure code
'aggressiveOptimizations': false,
// The relative file path of the file to be cleaned. Use this option if you
// are not using the code option.
// Hint: Use the __dirname trick
'filePath': '',
// The modules that you would like to set as window properties
// An array of strings (module names)
'globalModules': [],
// All esprima API options are supported: http://esprima.org/doc/
'esprima': {
'comment': true,
'loc': true,
'range': true,
'tokens': true
},
// All escodegen API options are supported: https://github.com/Constellation/escodegen/wiki/API
'escodegen': {
'comment': true,
'format': {
'indent': {
'style': ' ',
'adjustMultilineComment': true
}
}
},
// If there is a comment (that contains the following text) on the same line
// or one line above a specific module, the module will not be removed
'commentCleanName': 'amdclean',
// The ids of all of the modules that you would not like to be 'cleaned'
'ignoreModules': [],
// Determines which modules will be removed from the cleaned code
'removeModules': [],
// Determines if all of the require() method calls will be removed
'removeAllRequires': false,
// Determines if all of the 'use strict' statements will be removed
'removeUseStricts': true,
// Determines if conditional AMD checks are transformed
// e.g. if(typeof define == 'function') {} -> if(true) {}
'transformAMDChecks': true,
// Determines if a named or anonymous AMD module will be created inside of your conditional AMD check
// Note: This is only applicable to JavaScript libraries, do not change this for web apps
// If set to true: e.g. define('example', [], function() {}) -> define([], function() {})
'createAnonymousAMDModule': false,
// Allows you to pass an expression that will override shimmed modules return
// values e.g. { 'backbone': 'window.Backbone' }
'shimOverrides': {},
// Determines how to prefix a module name with when a non-JavaScript
// compatible character is found
// 'standard' or 'camelCase'
// 'standard' example: 'utils/example' -> 'utils_example'
// 'camelCase' example: 'utils/example' -> 'utilsExample'
'prefixMode': 'standard',
// A hook that allows you add your own custom logic to how each moduleName is
// prefixed/normalized
'prefixTransform': function(postNormalizedModuleName, preNormalizedModuleName) { return postNormalizedModuleName; },
// Wrap any build bundle in a start and end text specified by wrap
// This should only be used when using the onModuleBundleComplete RequireJS
// Optimizer build hook
// If it is used with the onBuildWrite RequireJS Optimizer build hook, each
// module will get wrapped
'wrap': {
// This string is prepended to the file
'start': ';(function() {\n',
// This string is appended to the file
'end': '\n}());'
},
// Configuration info for modules
// Note: Further info can be found here - http://requirejs.org/docs/api.html#config-moduleconfig
'config': {},
// A hook that allows you add your own custom module variable assignment expression, very handly if you need to
// create your own modules global dictionary
'IIFEVariableNameTransform': function(moduleName, moduleId){return 'GlobalModules[\'' + moduleId + '\'] = ' + moduleName; }
})
All unit tests are written using the jasmine-node library and can be found in the test/specs/
folder. You can run the unit tests by typing: npm test
or gulp test
.
Please send all PR's to the dev
branch.
If your PR is a code change:
src/modules
directory.convert.js
inside of the test/specs
foldernpm install
sudo npm install gulp -g
gulp
build/amdclean.min.js
Note: There is a gulp watch
task that will automatically lint, minify, unit test, and build AMDclean whenever a module inside of the src/modules
directory is changed. I recommend using it.
After I build with AMDclean, I am getting JavaScript errors. What gives?
There could be a couple of reasons:
If you are NOT using the Require.js shim
configuration, then make sure to set the Require.js skipModuleInsertion
option to true
. By default, Require.js creates a define()
wrapper for files that are not wrapped in a define()
. This can cause issues with AMDclean.
Make sure you are not pointing to minified files when building with AMDclean. This will definitely cause issues.
There may be a bug with AMDclean (I doubt it, but it is possible). Please report any issues and they will be fixed as soon as possible.
Why should I use AMDclean instead of Browserify?
Browserify Pros
node_modules
file lookup algorithm, which allows you to npm install
an npm module and automatically use itBrowserify Cons
AMDclean Pros
AMDclean Cons
node_modules
file lookup algorithm, which means that you can not automatically use npm
to install modules without having to set up configuration firstWhy should I use AMDclean instead of Almond.js?
Do I have to use the onModuleBundleComplete Require.js hook?
< 2.0
versions of AMDclean, the onBuildWrite
Require.js hook was used instead, but the onBuildWrite
hook has been deprecated. Use the onModuleBundleComplete
Require.js hook like this:onModuleBundleComplete: function (data) {
var fs = require('fs'),
amdclean = require('amdclean'),
outputFile = data.path;
fs.writeFileSync(outputFile, amdclean.clean({
'filePath': outputFile,
'globalObject': true
}));
}
Does AMDclean use AMDclean to build itself?
Yes, it does! With the 2.1.0
release, AMDclean was refactored into AMD modules and builds itself to create a library that can be used in node.js or the browser (AMD environment and web environment).
Is AMDclean only for libraries, or can I use it for my web app?
You can use it for both! The 0.6.0 release provided support for web apps.
By default, AMDclean is set up for use within a web app. If you are developing a JavaScript library with AMDclean, here are the things you should be aware of:
Make sure to set the transformAMDChecks
option to false
if you don't want your conditional UMD (Universal Module Definition) pattern affected.
If your JavaScript library depends on one or external libraries (libraries that will not be included in your library's source code), then you need to do a little hackery and make sure to hoist the local variables, that will hold the external library values, using the AMDclean wrap
option. For more details, take a look at how AMDclean itself handles this situation, or create a Github issue
My comments seem to be getting removed when I use AMDclean. What am I doing wrong?
2.1.0
release, this was the default behavior. If you update to 2.1.0
or later, you should see your comments still there after the cleaning process. Also, if you would like your comments to be removed, then you can set the comment
escodegen option to false
.What if I don't want all define() and require() method calls to be removed?
ignoreModules
option array. Like this:var amdclean = require('amdclean');
amdclean.clean({
'code': 'define("randomExample", function() { console.log("I am a random example"); });',
'ignoreModules': ['randomExample']
});
If there is not an associated module id, 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() {});
If you want to use different text than amdclean
, you can customize the comment name by using the commentCleanName
option.
Why are define() method placeholder functions inserted into my source?
skipModuleInsertion
option to true
in your build configuration.How would I expose one or more modules as a global window property?
globalModules
option to list all of the modules that you would like to expose as a window
propertyI replaced Almond.js with AMDclean and my file is bigger. Why Is This?
There could be a couple of reasons:
Unneccessary files are still being included with your build. Make sure that both Almond.js and the RequireJS text! plugin are not still being included, since they are not needed. You can use the removeModules
option to make sure certain modules are not included (e.g. text plugin).
You are using an old version of AMDclean (0.6.0
or earlier). The latest versions of AMDclean do an amazing job of optimizing modules.
I am building a JavaScript library and want to provide conditional AMD support, but AMDclean seems to be wiping away my if statement. How do I fix this?
You have two options:
Set the transformAMDChecks
option to false
Make sure that you have a comment (that matches your AMDclean commentCleanName
option) one line above your conditional AMD if statement
I am building a JavaScript library and want to create a conditional anonymous AMD module, but Require.js and AMDclean seems to always setting a module ID. How do I fix this?
createAnonymousAMDModule
option to true
,I don't like the way AMDclean normalizes the names of my modules with underscores. Can I change this?
prefixMode
and change it to camelCase, or you can override all of the logic with your own logic by using the prefixTransform
option hook.Require.js supports passing module information, to one or more modules, with the config
option. Does AMDclean support this?
config
option with whatever module information you would like available to you in your modules. Check the Require.js website for more details: http://requirejs.org/docs/api.html#config-moduleconfigI can't seem to get AMDclean 2.0 to work. What gives?
onModuleBundleComplete
Require.js hook and NOT the onBuildWrite
Require.js hook. The onBuildWrite
hook has been deprecated for AMDclean versions >= 2.0
.I'd like to use source map support. What to do?
var amdclean = require('amdclean'),
cleaned = amdclean.clean({
'sourceMap: '{...}', // this is the source map that you already have for the code below
'code': 'define("randomExample", function() { console.log("I am a random example"); });',
'wrap': false, // do not use wrap together with escodegen.sourceMapWithCode since it breaks the logic
'esprima': {
'source': 'myfile.js' // name of your file to appear in sourcemap
},
'escodegen': {
'sourceMap': true,
'sourceMapWithCode': true
}
});
Attention! Result in variable cleaned
is an object {code: ..., map: ...}
where code
is your cleaned code and map
is a source map. Read Escodegen Wiki for more info.
Copyright (c) 2014 Greg Franko Licensed under the MIT license.
FAQs
A build tool that converts AMD code to standard JavaScript
The npm package amdclean receives a total of 2,295 weekly downloads. As such, amdclean popularity was classified as popular.
We found that amdclean demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.