Skip to content

Commit

Permalink
Anonymous AMD Support
Browse files Browse the repository at this point in the history
This adds an option named `amdModule` to app.import. It causes any anonymous AMD module in the imported file to be registered under the given name.

    app.import('bower_components/some-dep/some-dep.js', { amdModule: 'some-dep' });

This should work correctly with a large number of libraries that:

 - check for `typeof define === 'function' && define.amd`
 - call `define` with just a factory function, or a dependency list and factory function.
  • Loading branch information
ef4 committed Feb 24, 2016
1 parent 3967130 commit 5953a31
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 3 deletions.
19 changes: 19 additions & 0 deletions lib/broccoli/amd-shim.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';
var stew = require('broccoli-stew');

module.exports = function shimAmd(tree, nameMapping) {
return stew.map(tree, function(content, relativePath) {
var name = nameMapping[relativePath];
if (name) {
return [
'(function(define){',
content,
'})((function(){ function newDefine(){ var args = Array.prototype.slice.call(arguments); args.unshift("',
name,
'"); return define.apply(null, args); }; newDefine.amd = true; return newDefine; })());'
].join('');
} else {
return content;
}
});
};
11 changes: 8 additions & 3 deletions lib/broccoli/ember-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var concat = require('broccoli-concat');
var ConfigReplace = require('broccoli-config-replace');
var ConfigLoader = require('broccoli-config-loader');
var mergeTrees = require('./merge-trees');
var shimAmd = require('./amd-shim');
var WatchedDir = require('broccoli-source').WatchedDir;
var UnwatchedDir = require('broccoli-source').UnwatchedDir;

Expand Down Expand Up @@ -95,6 +96,7 @@ function EmberApp() {

this.legacyFilesToAppend = {};
this.vendorStaticStyles = {};
this.amdModuleNames = {};

this.otherAssetPaths = [];
this.legacyTestFilesToAppend = [];
Expand Down Expand Up @@ -898,9 +900,9 @@ EmberApp.prototype._processedExternalTree = function() {
trees.unshift(bower);
}

return this._cachedExternalTree = mergeTrees(trees, {
return this._cachedExternalTree = shimAmd(mergeTrees(trees, {
annotation: 'TreeMerger (ExternalTree)'
});
}), this.amdModuleNames);
};

/**
Expand Down Expand Up @@ -1404,6 +1406,10 @@ EmberApp.prototype._import = function(assetPath, options, directory, subdirector
var basename = path.basename(assetPath);

if (isType(assetPath, 'js', {registry: this.registry})) {
if (options.amdModule) {
this.amdModuleNames[assetPath] = options.amdModule;
}

if (options.type === 'vendor') {
options.outputFile = options.outputFile || this.options.outputPaths.vendor.js;
addOutputFile(this.legacyFilesToAppend, assetPath, options);
Expand Down Expand Up @@ -1667,4 +1673,3 @@ function addOutputFile(container, assetPath, options) {
container[outputFile].push(assetPath);
}
}

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"broccoli-plugin": "^1.2.0",
"broccoli-sane-watcher": "^1.1.1",
"broccoli-source": "^1.1.0",
"broccoli-stew": "^1.2.0",
"broccoli-viz": "^2.0.1",
"chalk": "^1.1.1",
"clean-base-url": "^1.0.0",
Expand Down
24 changes: 24 additions & 0 deletions tests/acceptance/brocfile-smoke-test-slow.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,30 @@ describe('Acceptance: brocfile-smoke-test', function() {
});
});

it('specifying amdModule converts anonymous AMD to named AMD', function() {
return copyFixtureFiles('brocfile-tests/app-import-anonymous-amd')
.then(function () {
return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build');
})
.then(function() {
var outputJS = fs.readFileSync(path.join('.', 'dist', 'assets', 'output.js'), {
encoding: 'utf8'
});

(function(){
function define(name, deps, factory) {
expect(name).to.equal('hello-world');
expect(deps).to.deep.equal([]);
expect(factory()()).to.equal('Hello World');
}
/* eslint-disable no-eval */
eval(outputJS);
/* eslint-enable no-eval */
})();
});
});


// skipped because of potentially broken assertion that should be fixed correctly at a later point
it.skip('specifying partial `outputPaths` hash deep merges options correctly', function() {
return copyFixtureFiles('brocfile-tests/custom-output-paths')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* global require, module */

var EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function (defaults) {
var app = new EmberApp(defaults, {
});

app.import('vendor/anonymous-amd-example.js', {
amdModule: 'hello-world',
outputFile: '/assets/output.js'
});

return app.toTree();
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(function() {
function helloWorld() {
return "Hello World";
}
if (typeof define === "function" && define.amd) {
define([], function () { return helloWorld; });
} else {
throw new Error("No amd loader found");
}
})();

0 comments on commit 5953a31

Please sign in to comment.