var fs = require('fs'); var cluster = require('cluster'); //自动加载进行识别的路径 var autoloadPaths = {}; /** * [exports description] * @type {Object} */ module.exports = { /** * [run description] * @return {[type]} [description] */ run: function(){ 'use strict'; this.init(); //加载文件 this.loadFiles(); //合并自动加载的路径 this.mergeAutoloadPath(); //thinkRequire的autoload registerAutoload(this.autoload); //debug模式 if (APP_DEBUG) { this.debug(); }else{ this.processEvent(); //记录日志 this.log(); } //记录进程的id this.logPid(); }, /** * 定义一些目录,加载框架的基础文件 * @return {[type]} [description] */ init: function(){ 'use strict'; //系统路径设置 global.THINK_LIB_PATH = THINK_PATH + '/Lib'; global.THINK_EXTEND_PATH = THINK_LIB_PATH + '/Extend'; //应用路径设置 var config = { COMMON_PATH: APP_PATH + '/Common', LIB_PATH: APP_PATH + '/Lib', CONF_PATH: APP_PATH + '/Conf', LANG_PATH: APP_PATH + '/Lang', VIEW_PATH: APP_PATH + '/View', //HTML_PATH: RUNTIME_PATH + '/Html', LOG_PATH: RUNTIME_PATH + '/Log', TEMP_PATH: RUNTIME_PATH + '/Temp', DATA_PATH: RUNTIME_PATH + '/Data', CACHE_PATH: RUNTIME_PATH + '/Cache' }; for (var name in config) { if (global[name] === undefined) { global[name] = config[name]; } } require(THINK_PATH + '/Common/extend.js'); require(THINK_PATH + '/Common/common.js'); require(THINK_PATH + '/Common/function.js'); //别名导入 aliasImport(require(THINK_PATH + '/Conf/alias.js')); }, /** * 记录日志 * @return {[type]} [description] */ log: function(){ 'use strict'; if (C('log_console')) { thinkRequire('Log')(C('log_console_path')).console(); } if (C('log_memory')) { thinkRequire('Log')(C('log_memory_path')).memory(); } }, /** * 安全方式加载文件 * @param {[type]} file [description] * @return {[type]} [description] */ safeRequire: function(file){ 'use strict'; try{ return require(file); }catch(e){ if (APP_DEBUG) { console.error(e.stack); } } return {}; }, /** * 注册异常处理 * @return {[type]} [description] */ processEvent: function(){ 'use strict'; process.on('uncaughtException', function(err) { console.error(isError(err) ? err.stack : err); }); }, /** * 加载项目下对应的文件 * @return {[type]} [description] */ loadFiles: function(){ 'use strict'; C(null); //移除之前的所有配置 //加载系统默认配置 C(require(THINK_PATH + '/Conf/config.js')); //加载用户配置 var file = CONF_PATH + '/config.js'; if (isFile(file)) { C(this.safeRequire(file)); } //加载模式的配置文件 if (APP_MODE) { var modeFiles = [ THINK_PATH + '/Conf/mode.js', CONF_PATH + '/mode.js' ]; var self = this; modeFiles.forEach(function(file){ if (!isFile(file)) { return; } var conf = self.safeRequire(file); if (conf[APP_MODE]) { C(conf[APP_MODE]); } }); } //自定义路由 if (C('url_route_on') && isFile(CONF_PATH + '/route.js')) { C('url_route_rules', this.safeRequire(CONF_PATH + '/route.js')); } //别名文件 if (isFile(CONF_PATH + '/alias.js')) { aliasImport(this.safeRequire(CONF_PATH + '/alias.js')); } //common文件 if (isFile(COMMON_PATH + '/common.js')) { require(COMMON_PATH + '/common.js'); } this.loadTag(); this.loadExtConfig(); this.loadExtFiles(); this.parseGroupList(); }, /** * 解析分组列表 * @return {[type]} [description] */ parseGroupList: function(){ 'use strict'; var filePath = LIB_PATH + '/Controller'; if (!isDir(filePath)) { var groupList = C('app_group_list').map(function(item){ return item.toLowerCase(); }) C('app_group_list', groupList); return; } var dirs = fs.readdirSync(filePath); //禁止分组列表 var denyDirs = C('deny_group_list'); if (!isEmpty(denyDirs)) { var length = denyDirs.length; var result = []; dirs.forEach(function(dir){ for(var i = 0; i < length; i++){ if (dir.toLowerCase() === denyDirs[i].toLowerCase()) { return; } } result.push(dir.toLowerCase()); }) dirs = result; }else{ dirs = dirs.map(function(item){ return item.toLowerCase(); }) } C('app_group_list', dirs); }, //加载标签行为 loadTag: function(){ 'use strict'; //系统标签 var tag = require(THINK_PATH + '/Conf/tag.js'); //用户行为标签 var tagFile = CONF_PATH + '/tag.js'; if (!C('app_tag_on') || !isFile(tagFile)) { C('tag', tag); return; } var mixTag = extend({}, tag); var userTag = extend({}, this.safeRequire(tagFile)); for(var key in userTag){ var value = userTag[key]; if (!value.length) { continue; } mixTag[key] = mixTag[key] || []; if (isBoolean(value[0])) { var flag = value.shift(); if (flag) { //true为替换系统标签 mixTag[key] = value; }else{ //false为将自定义标签置为系统标签前面 mixTag[key] = value.concat(mixTag[key]); } }else{// 默认将用户标签置为系统标签后面 mixTag[key] = mixTag[key].concat(value); } } //行为标签 C('tag', mixTag); }, //加载自定义外部文件 loadExtFiles: function(){ 'use strict'; var files = C('load_ext_file'); if (!isEmpty(files)) { if (isString(files)) { files = files.split(','); } var self = this; files.forEach(function(file){ file = COMMON_PATH + '/' + file + '.js'; self.safeRequire(file); }); } }, //加载额外的配置 loadExtConfig: function(){ 'use strict'; var files = C('load_ext_config'); if (!isEmpty(files)) { if (isString(files)) { files = files.split(','); } var self = this; files.forEach(function(file){ file = CONF_PATH + '/' + file + '.js'; C(self.safeRequire(file)); }); } }, //加载debug模式配置文件 loadDebugFiles: function(){ 'use strict'; //加载debug模式下的配置 C(require(THINK_PATH + '/Conf/debug.js')); var debugFile = CONF_PATH + '/debug.js'; if (isFile(debugFile)) { C(this.safeRequire(debugFile)); } if (APP_MODE) { var modeFiles = [ THINK_PATH + '/Conf/mode.js', CONF_PATH + '/mode.js' ]; var self = this; modeFiles.forEach(function(file){ if (!isFile(file)) { return; } var conf = self.safeRequire(file); var key = APP_MODE + '_debug'; if (conf[key]) { C(conf[key]); } }); } }, /** * debug模式下一些特殊处理 * @return {[type]} [description] */ debug: function(){ 'use strict'; this.loadDebugFiles(); //清除require的缓存 if (C('clear_require_cache')) { //这些文件不清除缓存 var self = this; setInterval(function(){ var retainFiles = C('debug_retain_files'); var fn = function(item){ //windows目录定界符为\ if (process.platform === 'win32') { item = item.replace(/\//g, '\\'); } if (file.indexOf(item) > -1) { return true; } }; for(var file in require.cache){ var flag = retainFiles.some(fn); if (!flag) { require.cache[file] = null; } } self.loadFiles(); self.loadDebugFiles(); }, 500); } }, /** * 记录当前进程的id * 记录在Runtime/Data/app.pid文件里 * @return {[type]} [description] */ logPid: function(){ 'use strict'; if (C('log_process_pid') && cluster.isMaster) { mkdir(DATA_PATH); var pidFile = DATA_PATH + '/app.pid'; fs.writeFileSync(pidFile, process.pid); chmod(pidFile); //进程退出时删除该文件 process.on('SIGTERM', function () { if (fs.existsSync(pidFile)) { fs.unlinkSync(pidFile); } process.exit(0); }); } }, /** * 合并autoload的path * @return {[type]} [description] */ mergeAutoloadPath: function(){ 'use strict'; var file = '__CLASS__.js'; var sysAutoloadPath = { 'Behavior': [ LIB_PATH + '/Behavior/' + file, THINK_LIB_PATH + '/Behavior/' + file ], 'Model': [ LIB_PATH + '/Model/' + file, THINK_EXTEND_PATH + '/Model/' + file ], 'Logic': [ LIB_PATH + '/Logic/' + file ], 'Service': [ LIB_PATH + '/Service/' + file ], 'Controller': [ LIB_PATH + '/Controller/' + file, THINK_EXTEND_PATH + '/Controller/' + file ], 'Cache': [ LIB_PATH + '/Driver/Cache/' + file, THINK_LIB_PATH + '/Driver/Cache/' + file ], 'Db': [ LIB_PATH + '/Driver/Db/' + file, THINK_LIB_PATH + '/Driver/Db/' + file ], 'Template': [ LIB_PATH + '/Driver/Template/' + file, THINK_LIB_PATH + '/Driver/Template/' + file ], 'Socket': [ LIB_PATH + '/Driver/Socket/' + file, THINK_LIB_PATH + '/Driver/Socket/' + file ], 'Session': [ LIB_PATH + '/Driver/Session/' + file, THINK_LIB_PATH + '/Driver/Session/' + file ] }; var autoloadPath = C('autoload_path'); for(var type in autoloadPath){ var paths = autoloadPath[type]; var override = false; if (!isArray(paths)) { paths = [paths]; }else if (isBoolean(paths[0])) { override = paths.shift(); } if (override) { sysAutoloadPath[type] = paths; }else{ paths.push.apply(paths, sysAutoloadPath[type]); sysAutoloadPath[type] = paths; } } autoloadPaths = sysAutoloadPath; }, /** * 自动加载机制,给thinkRequire使用 * @param {[type]} cls [description] * @return {[type]} [description] */ autoload: function(cls){ 'use strict'; for(var name in autoloadPaths){ if (cls.substr(0 - name.length) === name) { var list = autoloadPaths[name]; for(var i = 0, len = list.length, item; i < len; i++){ item = list[i].replace('__CLASS__', cls); if (isFile(item)) { return item; } } } } } };