loader.js [![Build Status](https://travis-ci.org/ember-cli/loader.js.svg?branch=master)](https://travis-ci.org/ember-cli/loader.js) ========= Minimal AMD loader mostly stolen from [@wycats](https://github.com/wycats). ## No Conflict To prevent the loader from overriding `require`, `define`, or `requirejs` you can instruct the loader to use no conflict mode by providing it an alternative name for the various globals that are normally used. Example: ```js loader.noConflict({ define: 'newDefine', require: 'newRequire' }); ``` ## Extra stuff ### `define.alias('new-name', 'old/path')` `define.alias` allows creation of a symlink from one module to another, for example: ```js define('foo/bar/baz', [], () => 'hi'); define.alias('foo', 'foo/bar/baz'); require('foo') // => 'hi'; require('foo') === require('foo/bar/baz'); ``` ### `require('require')` When within a module, one can require `require`. This provides a `require` scoped to the current module. Enabling dynamic, relatively path requires. ```js define('foo/apple', ['require'], function() { return 'apple'; }); define('foo/bar', ['require'], function(require){ return require('./apple');); require('foo/bar'); // 'apple'; ``` This scoped `require` also enables a module some reflection, in this case the ability for a module to see its own `moduleId`; ```js define('my/name/is', ['require'], function(require) { require.moduleId // => 'my/name/is'; }); ``` ### `define.exports('foo', {})` `define.exports` enables a fastpath for non-lazy dependency-less modules, for example: Rather then: ```js define("my-foo-app/templates/application", ["exports"], function (exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Ember.HTMLBars.template({ "id": "VVZNWoRm", "block": "{\"statements\":[[1,[26,[\"welcome-page\"]],false],[0,\"\\n\"],[0,\"\\n\"],[1,[26,[\"outlet\"]],false]],\"locals\":[],\"named\":[],\"yields\":[],\"hasPartials\":false}", "meta": { "moduleName": "my-foo-app/templates/application.hbs" } }); }); ``` We can author: ```js define.exports('my-app/template/apple', { hbs: true, "id": "VVZNWoRm", "block": "{\"statements\":[[1,[26,[\"welcome-page\"]],false],[0,\"\\n\"],[0,\"\\n\"],[1,[26,[\"outlet\"]],false]],\"locals\":[],\"named\":[],\"yields\":[],\"hasPartials\":false}", "meta": { "moduleName": "my-foo-app/templates/application.hbs" }}); ``` benefits: * less bytes * no reification step * no need to juggle pre-parse voodoo. ### `require.unsee('foo');` `require.unsee` allows one to unload a given module. *note* The side-effects of that module cannot be unloaded. This is quite useful, especially for test suites. Being able to unload run tests, mitigates many common memory leaks: example: ```js define('my-app/tests/foo-test.js', ['qunit'], function(qunit) { let app; qunit.module('my module', { beforeEach() { app = new App(); } // forgot to `null` out app in the afterEach }); test('my app exists', function(assert) { assert.ok(app); }) }) ``` --- Note: To be able to take advantage of alternate `define` method name, you will also need to ensure that your build tooling generates using the alternate. An example of this is done in the [emberjs-build](https://github.com/emberjs/emberjs-build) project in the [babel-enifed-module-formatter plugin](https://github.com/emberjs/emberjs-build/blob/v0.4.2/lib/utils/babel-enifed-module-formatter.js). ## wrapModules It is possible to hook loader to augment or transform the loaded code. `wrapModules` is an optional method on the loader that is called as each module is originally loaded. `wrapModules` must be a function of the form `wrapModules(name, callback)`. The `callback` is the original AMD callback. The return value of `wrapModules` is then used in subsequent requests for `name` This functionality is useful for instrumenting code, for instance in code coverage libraries. ```js loader.wrapModules = function(name, callback) { if (shouldTransform(name) { return myTransformer(name, callback); } } return callback; }; ``` ## makeDefaultExport loader.js creates default exports for ember-cli `amdStrict` mode. If you do not need this behavior you can disable it like so: ```js loader.makeDefaultExport = false; ``` ## Tests We use [testem](https://github.com/airportyh/testem) for running our test suite. You may run them with: ```sh npm test ``` You can also launch testem development mode with: ```sh npm run test:dev ``` ## License loader.js is [MIT Licensed](https://github.com/ember-cli/loader.js/blob/master/LICENSE.md).