mirror of
https://github.com/thinkjs/thinkjs.git
synced 2026-01-25 14:42:47 +00:00
420 lines
11 KiB
JavaScript
420 lines
11 KiB
JavaScript
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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|