build-module.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. var fs = require('fs');
  2. var uglify = require('uglify-js');
  3. var pack = require('./../package.json');
  4. var version = 'v' + pack.version;
  5. var license = pack.license + '-License';
  6. var libPath = __dirname;
  7. var { getModuleNames, error } = require('./helpers');
  8. module.exports = (options) => {
  9. // Arguments Sanity Check:
  10. if (options.only && options.ignore) {
  11. error('Error: You cannot specify both --only and --ignore.');
  12. }
  13. // Bootstrap build version and type
  14. var bs_version = options.bs_version; // if not specified BS3 will be used
  15. var build_type = options.minify ? 'minified' : 'unminified';
  16. if (options.only) options.only = getModuleNames(options.only);
  17. if (options.ignore) options.ignore = getModuleNames(options.ignore);
  18. // Get a list of all modules:
  19. var allModules = fs.readdirSync(`${libPath}/V${bs_version}/`).filter(item => /-native\.js$/.test(item));
  20. // Get a list of modules to include:
  21. var modules = [];
  22. if (options.only) { // If --only, use that for modules
  23. modules = options.only.filter(function (item) {
  24. // Validate module names:
  25. var valid = getModuleNames(allModules).some(name => name === item);
  26. if (!valid) {
  27. console.warn(`Warning: ${item} is not a valid module name, continuing`);
  28. }
  29. return valid;
  30. });
  31. } else if (options.ignore) { // If --ignore, filter allModules
  32. // Filter allModules:
  33. modules = getModuleNames(allModules).filter(function (item) {
  34. // If not in ignore list, return true:
  35. return options.ignore.every(ignoreItem => ignoreItem !== item);
  36. });
  37. } else { // If neither --ignore or --only, use allModules
  38. modules = getModuleNames(allModules);
  39. }
  40. // If modules is an empty array, abort
  41. // This could happen if you passed non-module values to --only
  42. if (modules.length === 0) {
  43. error(`Error: No valid module names, aborting`);
  44. }
  45. // Use console.warn to avoid writing to stdout
  46. console.warn(`Building ${build_type} package for Native JavaScript for Bootstrap ${bs_version} ${version} ..`);
  47. console.warn(`Included modules: ${modules.join(', ')}`);
  48. console.warn(`Build complete!\n`);
  49. // Load modules:
  50. // Use Promises to avoid race conditions
  51. var promises = [];
  52. modules.forEach(function (name, i) {
  53. promises[i] = new Promise(function (resolve, reject) {
  54. fs.readFile(`${libPath}/V${bs_version}/${name.toLowerCase()}-native.js`, 'utf8', function (err, contents) {
  55. if (err) reject(err);
  56. resolve(contents);
  57. });
  58. });
  59. });
  60. // When all modules are loaded, make bundle:
  61. var result = Promise.all(promises)
  62. .then(function (modules) {
  63. var header = '// Native Javascript for Bootstrap ' + bs_version + ' ' + version + ' | © dnp_theme | ' + license + '\n';
  64. var bundle = wrap(modules.join(''));
  65. if (options.minify) {
  66. bundle = uglify.minify(bundle, {fromString: true}).code;
  67. }
  68. var output = header + bundle + '\n';
  69. process.stdout.on('error', function (err) {
  70. throw err; // Will be caught below
  71. });
  72. if (options.cli) {
  73. process.stdout.write(output, 'utf8');
  74. }
  75. return output;
  76. })
  77. .catch(error);
  78. function wrap(main) {
  79. var utils = fs.readFileSync(`${libPath}/V${bs_version}/utils.js`, 'utf8').split('\n').join('\n ');
  80. var init = options.autoInitDataAPI === false ? '' : fs.readFileSync(`${libPath}/utils-init.js`, 'utf8').split('\n').join('\n ');
  81. main = main.split('\n').join('\n ');
  82. // Initialize arrays:
  83. // Arrays will be used in the template literal below
  84. var rootAttachments = [];
  85. var returns = [];
  86. // Populate arrays:
  87. modules.forEach(function (name) {
  88. rootAttachments.push(`root.${name} = bsn.${name};`);
  89. returns.push(`${name}: ${name}`);
  90. });
  91. // Custom UMD Template:
  92. return `(function (root, factory) {
  93. if (typeof define === 'function' && define.amd) {
  94. // AMD support:
  95. define([], factory);
  96. } else if (typeof module === 'object' && module.exports) {
  97. // CommonJS-like:
  98. module.exports = factory();
  99. } else {
  100. // Browser globals (root is window)
  101. var bsn = factory();
  102. ${rootAttachments.join('\n ')/* add indentation */}
  103. }
  104. }(this, function () {
  105. ${utils}
  106. BSN.version = '${pack.version}';
  107. ${main}
  108. ${init}
  109. return {
  110. ${returns.join(',\n ')/* add indentation and comma */}
  111. };
  112. }));`;
  113. // End of Template
  114. }
  115. return result;
  116. }