source/Package.js
import { meta } from './utility';
import { configOf, patternOf } from '@tech_query/node-toolkit';
import { dirname, basename } from 'path';
import Module from './Module';
import {generate} from './UMD';
const Array_iterator = [ ][Symbol.iterator], { unshift } = Array.prototype;
var config = configOf( meta.name ) || '';
if ( config.moduleMap ) config.moduleMap = patternOf( config.moduleMap );
/**
* Package to be bundled
*/
export default class Package {
/**
* @param {string} path - The entry file path of this package
* (relative to `process.cwd()`)
* @param {boolean} [includeAll=false] - Include NPM modules in the final bundle
* @param {?NameMap} moduleMap - Map to replace some dependencies to others
* @param {boolean} [noLog=false] - Disable log output
*/
constructor(path, includeAll = false, moduleMap, noLog = false) {
/**
* The entry file path of this package
*
* @type {string}
*/
this.path = path;
/**
* The root path of this package (relative to `process.cwd()`)
*
* @type {string}
*/
this.base = dirname( path );
/**
* Whether include NPM modules in the final bundle
*
* @type {boolean}
*/
this.includeAll = includeAll;
/**
* Module count of this package
*
* @type {number}
*/
this.length = 0;
/**
* @type {NameMap}
*/
this.moduleMap = moduleMap || config.moduleMap;
/**
* Whether show logs during the bundle process
*
* @type {boolean}
*/
this.showLog = (! noLog);
}
[Symbol.iterator]() { return Array_iterator.call( this ); }
/**
* @param {Module|string} module - Instance or name of a module
*
* @return {number}
*/
indexOf(module) {
for (let i = 0; this[i]; i++)
if (
(module instanceof Module) ?
(module === this[i]) : (module === this[i].name)
)
return i;
return -1;
}
/**
* @protected
*
* @param {string} modName - Path of a module
*
* @return {?Module} New module
*/
register(modName) {
if (this.indexOf( modName ) > -1) return;
unshift.call(
this,
new Module(modName, this.base, this.includeAll, this.moduleMap)
);
return this[0];
}
/**
* Entry module of this package
*
* @type {Module}
*/
get entry() { return this[this.length - 1]; }
/**
* @protected
*
* @param {string} modName - Path of a module
*/
parse(modName) {
const module = this.register( modName );
if (! module) return;
if ( this.showLog )
module.on('replace', (oldMod, newMod) =>
console.info(
`→ Module "${oldMod}" will be replaced by "${newMod}"`
)
);
module.parse();
if ( this.showLog )
console.info(`√ Module "${modName}" has been bundled`);
module.dependencyPath.forEach( this.parse.bind( this ) );
}
/**
* Outside dependencies of this package
*
* @type {DependencyMap}
*/
get outDependency() {
return this.includeAll ? [ ] : Object.assign.apply(
Object, Array.from(this, module => module.dependency.outside)
);
}
/**
* @param {string} [name] - Module name of bundled package
* (Default: The entry module's name)
* @return {string} Source code of this package
*/
bundle(name) {
const entry = basename( this.path );
this.parse(`./${entry}`);
return generate(
this, name || entry, this.entry.name, this.outDependency
);
}
}