npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

babel-plugin-transform-amd-to-commonjs

v1.6.0

Published

Transforms AMD code to CommonJS

Downloads

50,183

Readme

babel-plugin-transform-amd-to-commonjs

npm version npm downloads build codecov

Babel plugin that transforms AMD to CommonJS. Check out the example project, which uses this plugin to allow jest to synchronously require AMD modules.

Usage

npm install --save-dev babel-plugin-transform-amd-to-commonjs

Add the transform to your .babelrc:

{
  "plugins": ["transform-amd-to-commonjs"]
}

Examples

Define

Input:

define(['jquery', 'underscore', 'myModule'], function($, _) {
  // ...
  return {
    // ...
  };
});

Output:

module.exports = function() {
  var $ = require('jquery');
  var _ = require('underscore');
  require('myModule');
  // ...
  return {
    // ...
  };
}();

Require

Input:

// Nested requires
require(['jquery', 'underscore', 'myModule'], function($, _) {
  // ...
  require(['anotherModule'], function(anotherModule) {
    // ...
  });
});

Output:

(function() {
  var $ = require('jquery');
  var _ = require('underscore');
  require('myModule');
  // ...
  (function() {
    var anotherModule = require('anotherModule');
    // ...
  })();
})();

Options

Specify options in your .babelrc:

{
  "plugins": [
    ["transform-amd-to-commonjs", { "restrictToTopLevelDefine": true }]
  ]
}
  • restrictToTopLevelDefine: (default: true) When true, only transform define calls that appear at the top-level of a program. Set to false to transform all calls to define.

Escape Hatch

If you need to ignore specific modules that are picked up by the plugin (for example, those that are erroneously detected as AMD modules), you can add an ignore comment at the top of the file:

/* transform-amd-to-commonjs-ignore */
define(['stuff', 'here'], function(donkeys, aruba) {
  return {
      llamas: donkeys.version,
      cows: aruba.hi
  };
});

The above module won't be transformed to CommonJS. The ignore comment must be at the beginning of the file and must be the only text in the comment block.

Details

Supported Versions

Only LTS versions of Node.js still in maintenance will be supported going forward. Older versions of the plugin may support older versions of Node.js. See the Node.js site for LTS details.

While this plugin lists @babel/core@^7.0.0 as a peer dependency, it should still work fine with babel-core@^6.0.0. Listing this peer dependency aligns with what is done by the core babel plugins.

AMD

AMD is interpreted as described by the AMD specification.

  • By default, only top-level calls to a define function will be transformed. Use the restrictToTopLevelDefine option to transform calls that are not at the top-level.
  • All calls to require where it is given an array of dependencies as its first argument will be transformed.
  • Explicitly requiring require, module, and exports in an AMD module will not generate a call to require, but instead defer to the global require, module, and exports assumed to be in the CommonJS environment you are transforming to.
  • The module name (optional first argument to define) is ignored, since the module ID in CommonJS is determined by the resolved filename.

Upgrading Versions

1.5.0

Version 1.5.0 stops building against Node.js versions less than 12.x (and the built files target Node.js 12.x), so make sure you're using at least Node.js 12.x. There are no known breaking changes caused by this, but if you for some reason cannot upgrade Node.js and are running into errors, please open an issue.

1.0.0

  • Versions >= 0.2.1 and < 1.0.0 support Node.js 4. 1.0.0 and above only support Node.js 6 and above. To upgrade to >= 1.0.0, first upgrade to Node.js >= 6.
  • If everything works fine with < 1.0.0, you should just be able to drop in >= 1.0.0 after upgrading Node.js. If you have any issues, there is one more edge-case breaking change that might be affecting you (but probably is not):
    • >= 1.0.0 accounts for the case where you're using a combination of return statements and module/exports to define the exports of your AMD modules. Earlier versions don't account for this case, so if you're upgrading, make sure that each AMD module only uses either return statements or module/exports to define its exports. See #26 and the caveats section of the README for more details.

Caveats

One module per file

Make sure that you have only one AMD module defined per file, otherwise you'll experience strange results once transformed to the CommonJS format.

Listing module dependencies inline (v1.6 and above)

In v1.6, require dependencies and factories with unknown types (at build time) are now supported. The dependency list may be a function call or variable name that resolves to an array-like type at runtime. The factory may be a function call or variable name that resolves to a function at runtime.

require(getDeps(), myFactoryFunction);

will be transformed to:

(function () {
  var maybeFunction = myFactoryFunction;
  var amdDeps = getDeps();
  if (!Array.isArray(amdDeps)) {
    return require(amdDeps);
  }
  if (typeof maybeFunction !== "function") {
    maybeFunction = function () {};
  }
  maybeFunction.apply(void 0, amdDeps.map(function (dep) {
    return {
      require: require,
      module: module,
      exports: module.exports
    }[dep] || require(dep);
  }));
}).apply(this);

If either the dependency list is known to be an array, or the factory is known to be a function, at build time then the associated runtime type checking for the argument is omitted from the generated code.

Calls to define are transformed in a similar manner, but include code for assigning the value returned by the factory function to module.exports:

(function () {
  var maybeFunction = factory;
  var amdDeps = deps;
  if (typeof amdDeps === 'string') {
    amdDeps = ['require', 'exports', 'module'];
  }
  if (typeof maybeFunction !== "function") {
    var amdFactoryResult = maybeFunction;
    maybeFunction = function () {
      return amdFactoryResult;
    };
  }
  var amdDefineResult = maybeFunction.apply(void 0, amdDeps.map(function (dep) {
    return {
      require: require,
      module: module,
      exports: module.exports
    }[dep] || require(dep);
  }));
  typeof amdDefineResult !== "undefined" && (module.exports = amdDefineResult);
}).apply(this);

Listing module dependencies inline (v1.5)

The following will not be transformed, since the plugin only accounts for dependencies that are specified using an inline array literal:

// DON'T DO THIS! It won't be transformed correctly.
var dependencies = ['one', 'two'];
define(dependencies, function(one, two) {
  one.doStuff();
  return two.doStuff();
});

If you want to be able to define your dependencies as above, please submit an issue. Otherwise, please define your modules as:

define(['one', 'two'], function(one, two) {
  one.doStuff();
  return two.doStuff();
});

However, specifying the factory as a variable is supported (but only for calls to define):

// All's good! Transforming this code is supported
var factory = function(one, two) {
  one.doStuff();
  return two.doStuff();
};
define(['one', 'two'], factory);

A runtime check has to be done to determine what to export, so the transformed code looks like this:

var factory = function(one, two) {
  one.doStuff();
  return two.doStuff();
};
var maybeFactory = factory;
if (typeof maybeFactory === 'function') {
  module.exports = factory(require('one'), require('two'));
} else {
  require('one');
  require('two');
  module.exports = maybeFactory;
};

It looks a bit weird, but it's all necessary. Keep in mind that everything is done with static analysis, so if the factory isn't specified as an inline function literal, it's impossible to tell exactly what value it will take until runtime.

Injecting require, module, or exports as dependencies

It is strongly advised to simply use return statements to define your AMD module's exports. That being said, the plugin takes into account the cases where you may have injected them as dependencies. Beware of the following gotchas when using this pattern:

  • If you're injecting module, exports, and/or require as dependencies, they must be injected as string literals, otherwise you'll end up with things like require('module').

  • Returning any value other than undefined from a factory function will override anything you assign to module or exports. This behaviour is in accordance with the AMD specification. Unless you're doing something really weird in your modules, you don't have to worry about this case, but the plugin handles it by performing a check as needed on the return value of the factory function. For example:

    Input (AMD):

    define(['module'], function(module) {
      module.exports = { hey: 'boi' };
      return { value: 22 };
    });

    Output (CommonJS):

    var amdDefineResult = function() {
      module.exports = { hey: 'boi' };
      return { value: 22 };
    }();
    typeof amdDefineResult !== 'undefined' && (module.exports = amdDefineResult);

    Note that { value: 22 } is correctly exported in both cases. Without the typeof amdDefineResult !== 'undefined' check in place, { hey: 'boi' } would have been erroneously exported once transformed to CommonJS, since the plugin would otherwise transform this module to just:

    (function() {
      module.exports = { hey: 'boi' };
      return { value: 22 };
    })()

    This pattern is only used if necessary. The variable amdDefineResult is generated to be unique in its scope.

Contributors

Thanks goes to these wonderful people (emoji key):

This project follows the all-contributors specification. Contributions of any kind welcome!