Home Reference Source Test

source/Package.js

  1. import { meta } from './utility';
  2.  
  3. import { configOf, patternOf } from '@tech_query/node-toolkit';
  4.  
  5. import { dirname, basename } from 'path';
  6.  
  7. import Module from './Module';
  8.  
  9. import {generate} from './UMD';
  10.  
  11. const Array_iterator = [ ][Symbol.iterator], { unshift } = Array.prototype;
  12.  
  13.  
  14. var config = configOf( meta.name ) || '';
  15.  
  16. if ( config.moduleMap ) config.moduleMap = patternOf( config.moduleMap );
  17.  
  18.  
  19. /**
  20. * Package to be bundled
  21. */
  22. export default class Package {
  23. /**
  24. * @param {string} path - The entry file path of this package
  25. * (relative to `process.cwd()`)
  26. * @param {boolean} [includeAll=false] - Include NPM modules in the final bundle
  27. * @param {?NameMap} moduleMap - Map to replace some dependencies to others
  28. * @param {boolean} [noLog=false] - Disable log output
  29. */
  30. constructor(path, includeAll = false, moduleMap, noLog = false) {
  31. /**
  32. * The entry file path of this package
  33. *
  34. * @type {string}
  35. */
  36. this.path = path;
  37.  
  38. /**
  39. * The root path of this package (relative to `process.cwd()`)
  40. *
  41. * @type {string}
  42. */
  43. this.base = dirname( path );
  44.  
  45. /**
  46. * Whether include NPM modules in the final bundle
  47. *
  48. * @type {boolean}
  49. */
  50. this.includeAll = includeAll;
  51.  
  52. /**
  53. * Module count of this package
  54. *
  55. * @type {number}
  56. */
  57. this.length = 0;
  58.  
  59. /**
  60. * @type {NameMap}
  61. */
  62. this.moduleMap = moduleMap || config.moduleMap;
  63.  
  64. /**
  65. * Whether show logs during the bundle process
  66. *
  67. * @type {boolean}
  68. */
  69. this.showLog = (! noLog);
  70. }
  71.  
  72. [Symbol.iterator]() { return Array_iterator.call( this ); }
  73.  
  74. /**
  75. * @param {Module|string} module - Instance or name of a module
  76. *
  77. * @return {number}
  78. */
  79. indexOf(module) {
  80.  
  81. for (let i = 0; this[i]; i++)
  82. if (
  83. (module instanceof Module) ?
  84. (module === this[i]) : (module === this[i].name)
  85. )
  86. return i;
  87.  
  88. return -1;
  89. }
  90.  
  91. /**
  92. * @protected
  93. *
  94. * @param {string} modName - Path of a module
  95. *
  96. * @return {?Module} New module
  97. */
  98. register(modName) {
  99.  
  100. if (this.indexOf( modName ) > -1) return;
  101.  
  102. unshift.call(
  103. this,
  104. new Module(modName, this.base, this.includeAll, this.moduleMap)
  105. );
  106.  
  107. return this[0];
  108. }
  109.  
  110. /**
  111. * Entry module of this package
  112. *
  113. * @type {Module}
  114. */
  115. get entry() { return this[this.length - 1]; }
  116.  
  117. /**
  118. * @protected
  119. *
  120. * @param {string} modName - Path of a module
  121. */
  122. parse(modName) {
  123.  
  124. const module = this.register( modName );
  125.  
  126. if (! module) return;
  127.  
  128. if ( this.showLog )
  129. module.on('replace', (oldMod, newMod) =>
  130. console.info(
  131. `→ Module "${oldMod}" will be replaced by "${newMod}"`
  132. )
  133. );
  134.  
  135. module.parse();
  136.  
  137. if ( this.showLog )
  138. console.info(`√ Module "${modName}" has been bundled`);
  139.  
  140. module.dependencyPath.forEach( this.parse.bind( this ) );
  141. }
  142.  
  143. /**
  144. * Outside dependencies of this package
  145. *
  146. * @type {DependencyMap}
  147. */
  148. get outDependency() {
  149.  
  150. return this.includeAll ? [ ] : Object.assign.apply(
  151. Object, Array.from(this, module => module.dependency.outside)
  152. );
  153. }
  154.  
  155. /**
  156. * @param {string} [name] - Module name of bundled package
  157. * (Default: The entry module's name)
  158. * @return {string} Source code of this package
  159. */
  160. bundle(name) {
  161.  
  162. const entry = basename( this.path );
  163.  
  164. this.parse(`./${entry}`);
  165.  
  166. return generate(
  167. this, name || entry, this.entry.name, this.outDependency
  168. );
  169. }
  170. }