├── .gitignore ├── tests ├── data │ ├── demo.js │ ├── with-deps.js │ ├── browser.js │ ├── with-deps-and-alias.js │ └── amd.js ├── amd_loader.js ├── index.js ├── browser.js ├── amd.js ├── browser-with-deps.js ├── browser-with-deps-and-alias.js ├── amd-with-deps.js ├── amd-with-deps-and-alias.js ├── utils.js └── cjs.js ├── .travis.yml ├── demo.js ├── .jshintrc ├── templates ├── umd+rails.hbs ├── umd.hbs ├── unit.hbs └── returnExportsGlobal.hbs ├── package.json ├── LICENSE ├── README.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /tests/data/demo.js: -------------------------------------------------------------------------------- 1 | trigger(); 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | 5 | -------------------------------------------------------------------------------- /tests/data/with-deps.js: -------------------------------------------------------------------------------- 1 | return function testDeps() { 2 | test(); 3 | 4 | window.close(); 5 | }; 6 | -------------------------------------------------------------------------------- /tests/data/browser.js: -------------------------------------------------------------------------------- 1 | return function test() { 2 | console.log('executed'); 3 | 4 | window.close(); 5 | }; 6 | -------------------------------------------------------------------------------- /tests/data/with-deps-and-alias.js: -------------------------------------------------------------------------------- 1 | return function testDeps() { 2 | alias(); 3 | 4 | window.close(); 5 | }; 6 | -------------------------------------------------------------------------------- /tests/data/amd.js: -------------------------------------------------------------------------------- 1 | return { 2 | test: function() { 3 | console.log('executed'); 4 | 5 | window.close(); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var umdify = require('./'); 3 | 4 | 5 | main(); 6 | 7 | function main() { 8 | var result = umdify('demo();', { 9 | deps: { 10 | 'default': ['foobar'], 11 | 'amd': ['foo', 'bar'], 12 | } 13 | }); 14 | 15 | console.log(result); 16 | } 17 | -------------------------------------------------------------------------------- /tests/amd_loader.js: -------------------------------------------------------------------------------- 1 | var modules = {}; 2 | 3 | window.define = function(name, deps, cb) { 4 | modules[name] = cb(); 5 | }; 6 | window.define.amd = true; 7 | 8 | window.require = function(deps, module) { 9 | module.apply(null, getModules(deps)); 10 | 11 | function getModules(names) { 12 | return names.map(function(name) { 13 | return modules[name]; 14 | }); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "browser": true, 4 | "camelcase": false, 5 | "curly": true, 6 | "eqeqeq": true, 7 | "esnext": true, 8 | "immed": true, 9 | "indent": 4, 10 | "latedef": false, 11 | "newcap": true, 12 | "noarg": true, 13 | "node": true, 14 | "quotmark": "single", 15 | "strict": true, 16 | "trailing": true, 17 | "undef": true, 18 | "unused": true, 19 | "sub": true, 20 | "globals": { 21 | "node": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var amd = require('./amd'); 3 | // var amdWithDeps = require('./amd-with-deps'); 4 | var browser = require('./browser'); 5 | var browserWithDeps = require('./browser-with-deps'); 6 | var browserWithDepsAndAlias = require('./browser-with-deps-and-alias'); 7 | var cjs = require('./cjs'); 8 | 9 | tests(); 10 | 11 | function tests() { 12 | amd(); 13 | // amdWithDeps(); 14 | browser(); 15 | browserWithDeps(); 16 | browserWithDepsAndAlias(); 17 | cjs(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tests/browser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | var umdify = require('../'); 4 | var utils = require('./utils'); 5 | 6 | module.exports = function() { 7 | utils.read(function(data) { 8 | var code = umdify(data, { 9 | globalAlias: 'test' 10 | }); 11 | 12 | code += '\nwindow.test();'; 13 | 14 | utils.runInPhantom(code, function(msg) { 15 | console.log('browser ok'); 16 | assert.equal(msg, 'executed'); 17 | }); 18 | }, 'browser.js'); 19 | } 20 | -------------------------------------------------------------------------------- /templates/umd+rails.hbs: -------------------------------------------------------------------------------- 1 | {{{pipelineDependencies}}} 2 | 3 | (function(factory) { 4 | /* jshint undef: true */ 5 | if (typeof define === "function" && define.amd) { 6 | define({{#if amdModuleId}}'{{amdModuleId}}', {{/if}}[ 7 | {{{amdDependencies.wrapped}}} 8 | ], factory); 9 | } 10 | else if (typeof module !== "undefined" && module.exports) { 11 | module.exports = factory( 12 | {{{cjsDependencies.wrapped}}}); 13 | } 14 | else { 15 | factory({{{globalDependencies}}}); 16 | } 17 | }(function({{dependencies}}) { 18 | 19 | {{{code}}} 20 | {{#if objectToExport}} 21 | return {{{objectToExport}}}; 22 | {{/if}} 23 | })); -------------------------------------------------------------------------------- /tests/amd.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var umdify = require('../'); 6 | var utils = require('./utils'); 7 | 8 | module.exports = function() { 9 | var amdLoaderPath = path.join(__dirname, 'amd_loader.js'); 10 | var code = fs.readFileSync(amdLoaderPath, { 11 | encoding: 'utf-8' 12 | }); 13 | 14 | utils.read(function(data) { 15 | code += umdify(data, { 16 | amdModuleId: 'test', 17 | globalAlias: 'test' 18 | }); 19 | 20 | code += '\nrequire([\'test\'], function(test) {test.test();});'; 21 | 22 | utils.runInPhantom(code, function(msg) { 23 | console.log('amd ok'); 24 | assert.equal(msg, 'executed'); 25 | }); 26 | }, 'amd.js'); 27 | } 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libumd", 3 | "description": "Wraps given JavaScript code with UMD", 4 | "author": "Juho Vepsalainen ", 5 | "version": "0.6.1", 6 | "dependencies": { 7 | "alphabet": "^1.0.0", 8 | "annois": "^0.3.2", 9 | "annozip": "^0.2.6", 10 | "handlebars": "^4.0.2", 11 | "object-merge": "^2.5.1" 12 | }, 13 | "devDependencies": { 14 | "localeval": "^15.2.3", 15 | "phantom": "^0.7.2", 16 | "tmp": "0.0.27" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/bebraw/libumd.git" 21 | }, 22 | "homepage": "https://github.com/bebraw/libumd", 23 | "bugs": { 24 | "url": "https://github.com/bebraw/libumd/issues" 25 | }, 26 | "scripts": { 27 | "test": "node tests" 28 | }, 29 | "keywords": [ 30 | "umd" 31 | ], 32 | "license": "MIT" 33 | } 34 | -------------------------------------------------------------------------------- /tests/browser-with-deps.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | var umdify = require('../'); 4 | var utils = require('./utils'); 5 | 6 | var code; 7 | module.exports = function() { 8 | utils.read(function(data) { 9 | code = umdify(data, { 10 | globalAlias: 'test', 11 | }); 12 | 13 | utils.read(function(data) { 14 | code += umdify(data, { 15 | globalAlias: 'testDeps', 16 | deps: { 17 | 'default': ['test'] 18 | } 19 | }); 20 | 21 | code += '\nwindow.testDeps();'; 22 | 23 | utils.runInPhantom(code, function(msg) { 24 | console.log('browser-with-deps ok'); 25 | assert.equal(msg, 'executed'); 26 | }); 27 | }, 'with-deps.js'); 28 | 29 | }, 'browser.js'); 30 | } 31 | -------------------------------------------------------------------------------- /tests/browser-with-deps-and-alias.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | var umdify = require('../'); 4 | var utils = require('./utils'); 5 | 6 | var code; 7 | module.exports = function() { 8 | utils.read(function(data) { 9 | code = umdify(data, { 10 | globalAlias: 'test', 11 | }); 12 | 13 | utils.read(function(data) { 14 | code += umdify(data, { 15 | globalAlias: 'testDeps', 16 | deps: { 17 | 'default': [{'test':'alias'}] 18 | } 19 | }); 20 | 21 | code += '\nwindow.testDeps();'; 22 | 23 | utils.runInPhantom(code, function(msg) { 24 | console.log('browser-with-deps-and-alias ok'); 25 | assert.equal(msg, 'executed'); 26 | }); 27 | }, 'with-deps-and-alias.js'); 28 | 29 | }, 'browser.js'); 30 | } 31 | -------------------------------------------------------------------------------- /templates/umd.hbs: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | // AMD. Register as an anonymous module unless amdModuleId is set 4 | define({{#if amdModuleId}}'{{amdModuleId}}', {{/if}}[{{{amdDependencies.wrapped}}}], function ({{{amdDependencies.params}}}) { 5 | return ({{#if objectToExport}}root['{{{objectToExport}}}'] = {{/if}}factory({{{amdDependencies.params}}})); 6 | }); 7 | } else if (typeof exports === 'object') { 8 | // Node. Does not work with strict CommonJS, but 9 | // only CommonJS-like environments that support module.exports, 10 | // like Node. 11 | module.exports = factory({{{cjsDependencies.wrapped}}}); 12 | } else { 13 | {{#if globalAlias}}root['{{{globalAlias}}}'] = {{else}}{{#if objectToExport}}root['{{{objectToExport}}}'] = {{/if}}{{/if}}factory({{{globalDependencies.normal}}}); 14 | } 15 | }(this, function ({{dependencies}}) { 16 | 17 | {{{code}}} 18 | {{#if objectToExport}} 19 | return {{{objectToExport}}}; 20 | {{/if}} 21 | 22 | })); 23 | -------------------------------------------------------------------------------- /templates/unit.hbs: -------------------------------------------------------------------------------- 1 | {{! UMD template that can be useful to wrap standalone CommonJS/Node modules}} 2 | (function(root, factory) { 3 | if(typeof exports === 'object') { 4 | module.exports = factory({{#if cjsDependencies.wrapped}}{{{cjsDependencies.wrapped}}}, {{/if}}require, exports, module); 5 | } 6 | else if(typeof define === 'function' && define.amd) { 7 | define({{#if amdModuleId}}'{{amdModuleId}}', {{/if}}[{{#if amdDependencies.wrapped}}{{{amdDependencies.wrapped}}}, {{/if}}'require', 'exports', 'module'], factory); 8 | } 9 | else { 10 | var req = function(id) {return root[id];}, 11 | exp = root, 12 | mod = {exports: exp}; 13 | {{#if globalAlias}}root['{{globalAlias}}'] = {{else}}{{#if objectToExport}}root['{{objectToExport}}'] = {{/if}}{{/if}}factory({{#if globalDependencies.normal}}{{{globalDependencies.normal}}}, {{/if}}req, exp, mod); 14 | } 15 | }(this, function({{#if dependencies}}{{dependencies}}, {{/if}}require, exports, module) { 16 | {{{code}}} 17 | return {{#if objectToExport}}{{objectToExport}}{{else}}module.exports{{/if}}; 18 | })); 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Juho Vepsalainen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /tests/amd-with-deps.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var umdify = require('../'); 6 | var utils = require('./utils'); 7 | 8 | module.exports = function() { 9 | var amdLoaderPath = path.join(__dirname, 'amd_loader.js'); 10 | var code = fs.readFileSync(amdLoaderPath, { 11 | encoding: 'utf-8' 12 | }); 13 | 14 | utils.read(function(data) { 15 | code += umdify(data, { 16 | amdModuleId: 'test', 17 | globalAlias: 'test' 18 | }); 19 | 20 | utils.read(function(data) { 21 | code += umdify(data, { 22 | amdModuleId: 'testDeps', 23 | globalAlias: 'testDeps', 24 | deps: { 25 | 'default': ['test'] 26 | } 27 | }); 28 | code += '\nrequire([\'testDeps\'], function(testDeps) {/* testDeps(); */});'; 29 | 30 | utils.runInPhantom(code, function(msg) { 31 | console.log('amd-with-deps ok'); 32 | assert.equal(msg, 'executed'); 33 | }); 34 | }, 'with-deps.js'); 35 | }, 'browser.js'); 36 | } 37 | -------------------------------------------------------------------------------- /tests/amd-with-deps-and-alias.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var umdify = require('../'); 6 | var utils = require('./utils'); 7 | 8 | module.exports = function() { 9 | var amdLoaderPath = path.join(__dirname, 'amd_loader.js'); 10 | var code = fs.readFileSync(amdLoaderPath, { 11 | encoding: 'utf-8' 12 | }); 13 | 14 | utils.read(function(data) { 15 | code += umdify(data, { 16 | amdModuleId: 'test', 17 | globalAlias: 'test' 18 | }); 19 | 20 | utils.read(function(data) { 21 | code += umdify(data, { 22 | amdModuleId: 'testDeps', 23 | globalAlias: 'testDeps', 24 | deps: { 25 | 'default': [{'test': 'alias'}] 26 | } 27 | }); 28 | code += '\nrequire([\'test\'], function(test) {test();});'; 29 | 30 | utils.runInPhantom(code, function(msg) { 31 | console.log('amd-with-deps ok'); 32 | assert.equal(msg, 'executed'); 33 | }); 34 | }, 'with-deps-and-alias.js'); 35 | }, 'browser.js'); 36 | } 37 | -------------------------------------------------------------------------------- /tests/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var tmp = require('tmp'); 5 | var phantom = require('phantom'); 6 | 7 | exports.read = function(cb, file) { 8 | var p = path.join(__dirname, 'data', file || 'demo.js'); 9 | 10 | fs.readFile(p, { 11 | encoding: 'utf-8' 12 | }, function(err, data) { 13 | if(err) { 14 | return console.error(err); 15 | } 16 | 17 | cb(data); 18 | }); 19 | }; 20 | 21 | exports.runInPhantom = function(code, consoleCb) { 22 | tmp.file(function(err, path, fd) { 23 | if(err) { 24 | return console.error(err); 25 | } 26 | 27 | fs.writeFile(path, code, function(err) { 28 | if(err) { 29 | return console.error(err); 30 | } 31 | 32 | phantom.create(function(ph) { 33 | ph.createPage(function(page) { 34 | page.onConsoleMessage(consoleCb); 35 | 36 | page.onError(function(msg, trace) { 37 | console.error(msg, trace); 38 | }); 39 | 40 | page.injectJs(path, function(ok) { 41 | if(!ok) { 42 | return console.error('Failed to inject js'); 43 | } 44 | 45 | ph.exit(); 46 | }); 47 | }); 48 | }); 49 | }); 50 | }); 51 | }; 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![build status](https://secure.travis-ci.org/bebraw/libumd.png)](http://travis-ci.org/bebraw/libumd) 2 | 3 | # libumd - Wraps given JavaScript code with UMD 4 | 5 | ## Usage 6 | 7 | ```js 8 | var umdify = require('libumd'); 9 | 10 | ... 11 | 12 | var result = umdify(js, options); 13 | ``` 14 | 15 | options (all are optional by default): 16 | 17 | ```js 18 | { 19 | template: 'path to template or template name', // defaults to 'umd' 20 | amdModuleId: 'test', // optional AMD module id. defaults to anonymous (not set) 21 | globalAlias: 'alias', // name of the global variable 22 | deps: { // dependencies - `default` acts as a fallback for each! 23 | 'default': ['foo', 'bar'], 24 | amd: ['foobar', 'barbar'], 25 | cjs: ['foo', 'barbar'], 26 | global: ['foobar', 'bar'] 27 | } 28 | } 29 | ``` 30 | 31 | > Note! `libumd` doesn't guarantee pretty formatting. It is better to use something like [js-beautify](https://www.npmjs.com/package/js-beautify) to deal with that. 32 | 33 | ## Default Templates 34 | 35 | The library comes with a couple of UMD variants. See `/templates`. In addition you may use one of your own as long as it is formatted using Handlebars syntax and follows the same naming conventions as the ones provided with the project. 36 | 37 | ## Testing 38 | 39 | Make sure [PhantomJS](http://phantomjs.org/) is installed and it's within your PATH. Hit `npm test` after that. If the UMD wrapper fails to run against the headless browser, you'll know. 40 | 41 | ## Contributors 42 | 43 | * [Stéphane Bachelier](https://github.com/stephanebachelier) - Use existing `objectToExport` instead of hardcoded value `returnExportsGlobal` for AMD 44 | 45 | ## License 46 | 47 | `libumd` is available under MIT. See LICENSE for more details. 48 | 49 | -------------------------------------------------------------------------------- /templates/returnExportsGlobal.hbs: -------------------------------------------------------------------------------- 1 | {{!-- 2 | Uses Node, AMD or browser globals to create a module. This example creates 3 | a global even when AMD is used. This is useful if you have some scripts 4 | that are loaded by an AMD loader, but they still want access to globals. 5 | If you do not need to export a global for the AMD case, 6 | see returnExports.js. 7 | 8 | If you want something that will work in other stricter CommonJS environments, 9 | or if you need to create a circular dependency, see commonJsStrictGlobal.js 10 | 11 | Defines a module "returnExportsGlobal" that depends another module called 12 | "b". Note that the name of the module is implied by the file name. It is 13 | best if the file name and the exported global have matching names. 14 | 15 | If the 'b' module also uses this type of boilerplate, then 16 | in the browser, it will create a global .b that is used below. 17 | --}} 18 | 19 | (function (root, factory) { 20 | if (typeof define === 'function' && define.amd) { 21 | {{! AMD. Register as an anonymous module. }} 22 | define({{#if amdModuleId}}'{{amdModuleId}}', {{/if}}[{{{amdDependencies.wrapped}}}], function ({{dependencies}}) { 23 | return ({{#if globalAlias}} root['{{{globalAlias}}}'] = {{/if}}factory({{dependencies}})); 24 | }); 25 | } else if (typeof exports === 'object') { 26 | {{!-- 27 | Node. Does not work with strict CommonJS, but 28 | only CommonJS-like enviroments that support module.exports, 29 | like Node. 30 | --}} 31 | var module_exports = factory({{{cjsDependencies.wrapped}}}); 32 | module.exports = module_exports; 33 | 34 | {{! FIX FOR BROWSERIFY: Set global alias if we in browserify. }} 35 | {{#if globalAlias}} 36 | if(typeof window !== "undefined"){ 37 | window['{{{globalAlias}}}'] = module_exports; 38 | } 39 | {{/if}} 40 | } else { 41 | {{! Browser globals }} 42 | {{#if globalAlias}}root['{{{globalAlias}}}'] = {{/if}}factory({{{globalDependencies.normal}}}); 43 | } 44 | }(this, function ({{dependencies}}) { 45 | 46 | {{{code}}} 47 | 48 | {{!-- 49 | Just return a value to define the module export. 50 | This example returns an object, but the module 51 | can return a function as the exported value. 52 | --}} 53 | 54 | return {{{objectToExport}}}; 55 | 56 | })); 57 | -------------------------------------------------------------------------------- /tests/cjs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | var path = require('path'); 5 | 6 | var localeval = require('localeval'); 7 | 8 | var umdify = require('../'); 9 | 10 | var read = require('./utils').read; 11 | 12 | 13 | module.exports = function() { 14 | triggered({}); 15 | triggered(); 16 | 17 | okTemplateName(); 18 | invalidTemplateName(); 19 | 20 | okTemplatePath(); 21 | invalidTemplatePath(); 22 | 23 | useDefault(); 24 | preserveDefault(); 25 | 26 | convertParametersToAlphabet(); 27 | 28 | noCode(); 29 | 30 | console.log('cjs ok'); 31 | }; 32 | 33 | function triggered(options) { 34 | read(function(data) { 35 | var code = umdify(data, options); 36 | 37 | var triggered; 38 | localeval(code, { 39 | trigger: function() { 40 | triggered = true; 41 | } 42 | }); 43 | 44 | assert(triggered); 45 | }); 46 | } 47 | 48 | function okTemplateName() { 49 | read(function(data) { 50 | var code = umdify(data, { 51 | template: 'returnExportsGlobal' 52 | }); 53 | 54 | var triggered; 55 | localeval(code, { 56 | trigger: function() { 57 | triggered = true; 58 | } 59 | }); 60 | 61 | assert(triggered); 62 | }); 63 | } 64 | 65 | function invalidTemplateName() { 66 | read(function(data) { 67 | assert.throws(function() { 68 | umdify(data, { 69 | template: 'foobar' 70 | }); 71 | }, 72 | Error); 73 | }); 74 | } 75 | 76 | function okTemplatePath() { 77 | read(function(data) { 78 | var p = path.join(__dirname, '..', 'templates', 'umd.hbs'); 79 | 80 | var code = umdify(data, { 81 | template: p 82 | }); 83 | 84 | var triggered; 85 | localeval(code, { 86 | trigger: function() { 87 | triggered = true; 88 | } 89 | }); 90 | 91 | assert(triggered); 92 | }); 93 | } 94 | 95 | function invalidTemplatePath() { 96 | read(function(data) { 97 | var p = path.join(__dirname, '..', 'templates', 'foo'); 98 | 99 | assert.throws(function() { 100 | umdify(data, { 101 | template: p 102 | }); 103 | }, 104 | Error); 105 | }); 106 | } 107 | 108 | function useDefault() { 109 | var dep = 'foobar'; 110 | var code = umdify('foo()', { 111 | deps: { 112 | 'default': [dep], 113 | }, 114 | }); 115 | 116 | assert(code.indexOf('define(["' + dep + '"]') >= 0); 117 | assert(code.indexOf('factory(require("' + dep + '"))') >= 0); 118 | assert(code.indexOf('factory(' + dep + ')') >= 0); 119 | } 120 | 121 | function preserveDefault() { 122 | var dep = 'foobar'; 123 | var code = umdify('foo()', { 124 | deps: { 125 | 'default': [dep], 126 | 'amd': ['baz', 'bar'], 127 | }, 128 | }); 129 | 130 | assert(code.indexOf('define(["baz","bar"], function (a0,b1) {') >= 0); 131 | assert(code.indexOf('factory(require("' + dep + '"))') >= 0); 132 | assert(code.indexOf('factory(' + dep + ')') >= 0); 133 | } 134 | 135 | function convertParametersToAlphabet() { 136 | var code = umdify('foo()', { 137 | deps: { 138 | 'default': ['foobar'], 139 | 'amd': ['baz', 'bar'], 140 | }, 141 | }); 142 | 143 | assert(code.indexOf('a0,b1') >= 0); 144 | } 145 | 146 | function noCode() { 147 | assert.throws(function() { 148 | umdify(); 149 | }, function(err) { 150 | if(err instanceof Error) { 151 | return true; 152 | } 153 | }); 154 | } 155 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var EventEmitter = require('events').EventEmitter; 4 | var inherits = require('util').inherits; 5 | var fs = require('fs'); 6 | var path = require('path'); 7 | 8 | var alphabet = require('alphabet').lower; 9 | var handlebars = require('handlebars'); 10 | var objectMerge = require('object-merge'); 11 | var is = require('annois'); 12 | var zip = require('annozip'); 13 | 14 | 15 | var UMD = function UMD(code, options) { 16 | if(!code) { 17 | throw new Error('Missing code to convert!'); 18 | } 19 | 20 | EventEmitter.call(this); 21 | this.code = code; 22 | this.options = options || {}; 23 | 24 | this.template = this.loadTemplate(this.options.template); 25 | }; 26 | 27 | inherits(UMD, EventEmitter); 28 | 29 | UMD.prototype.loadTemplate = function loadTemplate(filepath) { 30 | var tplPath, 31 | exists = fs.existsSync; 32 | 33 | if (filepath) { 34 | if (exists(filepath)) { 35 | tplPath = filepath; 36 | } 37 | else { 38 | tplPath = path.join(__dirname, 'templates', filepath + '.hbs'); 39 | 40 | if (!exists(tplPath)) { 41 | tplPath = path.join(__dirname, 'templates', filepath); 42 | 43 | if (!exists(tplPath)) { 44 | this.emit('error', 'Cannot find template file "' + filepath + '".'); 45 | return; 46 | } 47 | } 48 | } 49 | } 50 | else { 51 | tplPath = path.join(__dirname, 'templates', 'umd.hbs'); 52 | } 53 | 54 | try { 55 | return handlebars.compile(fs.readFileSync(tplPath, 'utf-8')); 56 | } 57 | catch (e) { 58 | this.emit('error', e.message); 59 | } 60 | }; 61 | 62 | UMD.prototype.generate = function generate() { 63 | var options = this.options, 64 | code = this.code, 65 | ctx = objectMerge({}, options); 66 | 67 | var depsOptions = objectMerge( 68 | getDependencyDefaults(this.options.globalAlias), 69 | convertDependencyArrays(options.deps) || {} 70 | ); 71 | 72 | var defaultDeps = depsOptions['default'].items; 73 | var deps = defaultDeps ? defaultDeps || defaultDeps.items || [] : []; 74 | var dependency, dependencyType, items, prefix, separator, suffix; 75 | 76 | for (dependencyType in depsOptions) { 77 | dependency = depsOptions[dependencyType]; 78 | items = dependency.items || defaultDeps || []; 79 | prefix = dependency.prefix || ''; 80 | separator = dependency.separator || ', '; 81 | suffix = dependency.suffix || ''; 82 | ctx[dependencyType + 'Dependencies'] = { 83 | normal: items, 84 | params: convertToAlphabet(items), 85 | wrapped: items.map(wrap(prefix, suffix)).join(separator), 86 | }; 87 | } 88 | 89 | ctx.dependencies = deps.join(', '); 90 | 91 | ctx.code = code; 92 | 93 | return this.template(ctx); 94 | }; 95 | 96 | function convertToAlphabet(items) { 97 | return items.map(function(_, i) { 98 | return alphabet[i] + i; 99 | }); 100 | } 101 | 102 | function wrap(pre, post) { 103 | pre = pre || ''; 104 | post = post || ''; 105 | 106 | return function (v) { 107 | return pre + v + post; 108 | }; 109 | } 110 | 111 | function convertDependencyArrays(deps) { 112 | if(!deps) { 113 | return; 114 | } 115 | 116 | return zip.toObject(zip(deps).map(function(pair) { 117 | if(is.array(pair[1])) { 118 | return [pair[0], { 119 | items: pair[1] 120 | }]; 121 | } 122 | 123 | return pair; 124 | })); 125 | } 126 | 127 | function getDependencyDefaults(globalAlias) { 128 | return { 129 | 'default': { 130 | items: null, 131 | }, 132 | amd: { 133 | items: null, 134 | prefix: '\"', 135 | separator: ',', 136 | suffix: '\"', 137 | }, 138 | cjs: { 139 | items: null, 140 | prefix: 'require(\"', 141 | separator: ',', 142 | suffix: '\")', 143 | }, 144 | global: { 145 | items: null, 146 | prefix: globalAlias? globalAlias + '.': '\"', 147 | separator: ',', 148 | suffix: '\"', 149 | } 150 | }; 151 | } 152 | 153 | module.exports = function(code, options) { 154 | var u = new UMD(code, options); 155 | 156 | return u.generate(); 157 | }; 158 | --------------------------------------------------------------------------------