UNPKG

fis3

Version:
318 lines (285 loc) 7.95 kB
'use strict'; var last = Date.now(); /* * Object.derive,产生一个Class的工厂方法 * @param {Function} constructor 构造函数 * @param {Object} proto 对象共有变量 * @return {Function} 构造方法 * @example * var class1 = Object.derive(function(){ console.log(this.name) }, {name: 'class1'}); * var class2 = Object.derive({ * constructor: function() { * console.log(this.name) * } * }, {name: 'class2'}) */ Function.prototype.derive = function(constructor, proto) { if (typeof constructor === 'object') { proto = constructor; constructor = proto.constructor || function() {}; delete proto.constructor; } var parent = this; var fn = function() { parent.apply(this, arguments); constructor.apply(this, arguments); }; var tmp = function() {}; tmp.prototype = parent.prototype; var fp = new tmp(), cp = constructor.prototype, key; for (key in cp) { if (cp.hasOwnProperty(key)) { fp[key] = cp[key]; } } proto = proto || {}; for (key in proto) { if (proto.hasOwnProperty(key)) { fp[key] = proto[key]; } } fp.constructor = constructor.prototype.constructor; fn.prototype = fp; return fn; }; //factory Function.prototype.factory = function() { var clazz = this; function F(args) { clazz.apply(this, args); } F.prototype = clazz.prototype; return function() { return new F(arguments); }; }; /** * fis 名字空间,fis 中所有工具和方法都是通过此变量暴露给外部使用。 * @namespace fis */ var fis = module.exports = {}; // register global variable Object.defineProperty(global, 'fis', { enumerable: true, writable: false, value: fis }); /** * 事件监听器, fis 中所有的事件都通过它来监听和触发。 * @name emitter * @type {EventEmitter} * @namespace fis.emitter * @see {@link https://nodejs.org/api/events.html#events_class_events_eventemitter} */ fis.emitter = new(require('events').EventEmitter); ['on', 'once', 'removeListener', 'removeAllListeners', 'emit'].forEach(function(key) { fis[key] = function() { if (arguments[0].match(/^proccess\:/)) { arguments[0] = 'process:' + arguments[0].slice(9) fis.log.warning('Did you mean ' + arguments[0] + ' event?') } var emitter = fis.emitter; return emitter[key].apply(emitter, arguments); }; }); /** * 用来监听 fis 中的事件。每次添加都不会有额外的检测工作,也就是说重复添加有可能被调用多次。 * * 注意:以下示例中 type 为 `project:lookup`, 但是它没有多余的意思,就是一段字符串,跟 namespace 没有一点关系。 * * 代理 fis.emitter.on. * * @example * fis.on('project:lookup', function(uri, file) { * // looking for uri from file. * console.log('Looking for %s from $s', uri, file.subpath); * }); * @see {@link https://nodejs.org/api/events.html} * @param {Sring} type 事件类型 * @param {Function} handler 响应函数 * @function on * @memberOf fis */ /** * 跟 fis.on 差不多,但是只会触发一次。 * * 代理 fis.emitter.once. * * @example * fis.once('compile:start', function(file) { * console.log('The file %s is gona compile.', file.subpath); * }); * @see fis.on * @see {@link https://nodejs.org/api/events.html} * @param {Sring} type 事件类型 * @param {Function} handler 响应函数 * @function once * @memberOf fis */ /** * 取消监听某事件。注意,如果同一个事件类型和同一响应函数被监听了多次,此函数一次只会移除一次。 * * 代理 fis.emitter.removeListener. * * @example * fis.on('project:lookup', function onLookup(uri, file) { * // looking for uri from file. * console.log('Looking for %s from $s', uri, file.subpath); * }); * * fis.removeListener('project:lookup', onLookup); * @see {@link https://nodejs.org/api/events.html} * @function removeListener * @param {String} type 事件类型 * @param {Function} handler 响应函数 * @memberOf fis */ /** * 取消监听所有事件监听,如果指定了事件类型,那么只会取消掉指定的事件类型的所有监听。 * * 代理 fis.emitter.removeAllListeners. * * @see {@link https://nodejs.org/api/events.html} * @function removeAllListeners * @param {String} [type] 事件类型 * @memberOf fis */ /** * 发送事件,将所有监听此事件名的响应函数挨个执行一次,并把消息体参数 args.. 带过去。 * * 代理 fis.emitter.emit. * * @example * fis.emit('donthing', { * foo: 1 * }); * @see {@link https://nodejs.org/api/events.html} * @param {Sring} type 事件类型 * @param {Mixed} args... 消息体数据,任意多个,所有参数都可以在 `handler` 中获取到。 * @function emit * @return {Boolean} 如果有事件响应了,则返回 `true` 否则返回 `false`. * @memberOf fis */ /** * 输出时间消耗,单位为 ms. * @example * fis.time('Comiple cost'); * // => compile cost 56ms * @param {String} title 描述内容 * @return {Undefined} * @function time * @memberOf fis */ fis.time = function(title) { console.log(title + ' : ' + (Date.now() - last) + 'ms'); last = Date.now(); }; fis.log = require('./log.js'); // utils var _ = fis.util = require('./util.js'); // config fis.config = require('./config.js'); // resource location fis.uri = require('./uri.js'); // project fis.project = require('./project.js'); // file fis.file = require('./file.js'); // cache fis.cache = require('./cache.js'); // compile kernel fis.compile = require('./compile.js'); // release api fis.release = require('./release.js'); ['get', 'set', 'env', 'media', 'match', 'hook', 'unhook'].forEach(function(key) { fis[key] = function() { var config = fis.config; return config[key].apply(config, arguments); }; }); /** * 仅限于 fis-conf.js 中使用,用来包装 fis 插件配置。 * * 需要在对应的插件扩展点中配置才有效,否则直接执行 fis.plugin 没有任何意义。 * * 单文件扩展点: * - lint * - parser * - preprocess * - standard * - postprocess * - optimizer * * 打包阶段扩展点: * - prepacakger * - sprite * - packager * - postpackager * * @example * fis.match('*.scss', { * parser: fis.plugin('sass', { * include_paths: [ * './static/scss/libaray' * ] * }) * }); * * fis.match('::packager', { * postpackager: fis.plugin('loader', { * allInOne: true * }); * }) * @memberOf fis * @param {String} pluginName 插件名字。 * * 说明:pluginName 不是对应的 npm 包名,而是对应 npm 包名去掉 fis 前缀,去掉插件扩展点前缀。 * * 如:fis-parser-sass 包,在这里面配置就是: * * ```js * fis.match('*.scss', { * parser: fis.plugin('sass') * }); * ``` * @param {Object} options 插件配置项,具体请参看插件说明。 * @param {String} [position] 可选:'prepend' | 'append'。默认为空,当给某类文件配置插件时,都是覆盖式的。而通过设置此插件可以做到,往前追加和往后追加。 * * 如: * * ```js * fis.match('*.xxx', { * parser: fis.plugin('a') * }); * * // 保留 plugin a 同时,之后再执行 plugin b * fis.match('*.xxx', { * parser: fis.plugin('b', null, 'append') * }); * ``` */ fis.plugin = function(key, options, position) { if (arguments.length === 2 && !_.isPlainObject(options)) { position = options; options = null; } options = options || {}; options.__name = options.__plugin = key; options.__pos = position; options.__isPlugin = true; return options; }; /** * fis 的 npm 包信息。 * @memberOf fis */ fis.info = fis.util.readJSON(__dirname + '/../package.json'); /** * fis 版本号 * @memberOf fis */ fis.version = fis.info.version; fis.require = require('./require.js'); fis.cli = require('./cli.js');