index.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. 'use strict';
  2. var templateSTR = "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}defineNamespace()}})(function(){source()});\n";
  3. function template(moduleName, options) {
  4. if (typeof options === 'boolean') {
  5. options = {commonJS: options};
  6. } else if (!options) {
  7. options = {};
  8. }
  9. var str = templateSTR.replace(/defineNamespace\(\)/g, compileNamespace(moduleName))
  10. .split('source()')
  11. str[0] = str[0].trim();
  12. //make sure these are undefined so as to not get confused if modules have inner UMD systems
  13. str[0] += 'var define,module,exports;';
  14. if (options.commonJS) str[0] += 'module={exports:(exports={})};';
  15. str[0] += '\n';
  16. if (options.commonJS) str[1] = 'return module.exports;' + str[1];
  17. str[1] = '\n' + str[1];
  18. return str;
  19. }
  20. exports = module.exports = function (name, src, options) {
  21. if (typeof options === 'string' && typeof src === 'object') {
  22. var tmp = options;
  23. options = src;
  24. src = tmp;
  25. }
  26. return exports.prelude(name, options) + src + exports.postlude(name, options);
  27. };
  28. exports.prelude = function (moduleName, options) {
  29. return template(moduleName, options)[0];
  30. };
  31. exports.postlude = function (moduleName, options) {
  32. return template(moduleName, options)[1];
  33. };
  34. function camelCase(name) {
  35. name = name.replace(/\-([a-z])/g, function (_, char) { return char.toUpperCase(); });
  36. if (!/^[a-zA-Z_$]$/.test(name[0])) {
  37. name = name.substr(1);
  38. }
  39. var result = name.replace(/[^\w$]+/g, '')
  40. if (!result) {
  41. throw new Error('Invalid JavaScript identifier resulted from camel-casing');
  42. }
  43. return result
  44. }
  45. function compileNamespace(name) {
  46. var names = name.split('.')
  47. // No namespaces, yield the best case 'global.NAME = VALUE'
  48. if (names.length === 1) {
  49. return 'g.' + camelCase(name) + ' = f()';
  50. // Acceptable case, with reasonable compilation
  51. } else if (names.length === 2) {
  52. names = names.map(camelCase);
  53. return '(g.' + names[0] + ' || (g.' + names[0] + ' = {})).' + names[1] + ' = f()';
  54. // Worst case, too many namespaces to care about
  55. } else {
  56. var valueContainer = names.pop()
  57. return names.map(compileNamespaceStep)
  58. .concat(['g.' + camelCase(valueContainer) + ' = f()'])
  59. .join(';');
  60. }
  61. }
  62. function compileNamespaceStep(name) {
  63. name = camelCase(name);
  64. return 'g=(g.' + name + '||(g.' + name + ' = {}))';
  65. }