Merge branch 'es6' of github.com:75team/thinkjs into es6

This commit is contained in:
maxzhang 2015-08-25 21:42:16 +08:00
commit dbe4c72ea8
30 changed files with 520 additions and 229 deletions

View File

@ -7,14 +7,13 @@ var program = require('commander');
var cwd = process.cwd();
var templatePath = path.dirname(__dirname) + '/template';
var modeType = 'module';
var modeTypeList = ['mini', 'normal', 'module'];
var projectRootPath = './'; //project root path
var modeList = ['mini', 'normal', 'module'];
require('../lib/core/think.js');
think.mode = think.mode_module;
/**
* get date time
* @return {} []
@ -27,24 +26,76 @@ var getDateTime = function(){
var date = d.getFullYear() + '-' + fn(d.getMonth() + 1) + '-' + fn(d.getDate());
var time = fn(d.getHours()) + ':' + fn(d.getMinutes()) + ':' + fn(d.getSeconds());
return date + ' ' + time;
}
};
var log = function(fn){
think.log(function(colors){
return ' ' + fn(colors);
}, '', null);
};
/**
* mkdir
* @param {String} dir []
* @return {} []
*/
var mkdir = function(dir){
if(think.isDir(dir)){
return;
}
think.mkdir(dir);
log(function(colors){
return colors.cyan('create') + ' : ' + path.normalize(dir);
});
};
/**
* get version
* @return {String} []
*/
var getVersion = function(){
var filepath = path.normalize(__dirname + '/../package.json');
var filepath = path.resolve(__dirname, '../package.json');
var version = JSON.parse(fs.readFileSync(filepath)).version;
return version;
};
/**
* get app root path
* @return {} []
*/
var getProjectAppPath = function(){
var path = projectRootPath;
path += program.es6 ? 'src' : 'app';
return path;
};
/**
* copy file
* @param {String} source []
* @param {String} target []
* @return {} []
*/
var copyFile = function(source, target, replace){
var copyFile = function(source, target, replace, showWarning){
if(showWarning === undefined){
showWarning = true;
}
if(think.isBoolean(replace)){
showWarning = replace;
replace = '';
}
//if target file is exist, ignore it
if(think.isFile(target)){
if(showWarning){
log(function(colors){
return colors.yellow('exist') + ' : ' + path.normalize(target);
});
}
return;
}
mkdir(path.dirname(target));
if(program.es6){
@ -57,7 +108,7 @@ var copyFile = function(source, target, replace){
}
var content = fs.readFileSync(templatePath + '/' + source, 'utf8');
//replace content
if(replace){
for(var key in replace){
content = content.replace(key, replace[key]);
@ -65,203 +116,391 @@ var copyFile = function(source, target, replace){
}
fs.writeFileSync(target, content);
think.log(function(colors){
return colors.green('create') + ' : ' + target;
log(function(colors){
return colors.cyan('create') + ' : ' + path.normalize(target);
});
}
};
/**
* mkdir
* @param {String} dir []
* @return {} []
* check is thinkjs app
* @param {String} projectRootPath []
* @return {Boolean} []
*/
var mkdir = function(dir){
if(think.isDir(dir)){
return;
}
think.mkdir(dir);
think.log(function(colors){
return colors.green('create') + ' : ' + dir;
});
}
/**
* create project
* @param {String} projectPath []
* @return {} []
*/
var createProject = function(projectPath){
//check path
if(think.isDir(projectPath)){
var filepath = projectPath + '/.thinkjsrc';
var isThinkApp = function(projectRootPath){
if(think.isDir(projectRootPath)){
var filepath = projectRootPath + '.thinkjsrc';
if(think.isFile(filepath)){
console.log();
think.log(function(colors){
return colors.red('path `' + projectPath + '` is already a thinkjs project.\n');
});
return;
return true;
}
}
console.log();
copyCommonFiles(projectPath);
switch(modeType){
case 'module':
createModuleApp(projectPath);
break;
case 'normal':
createNormalApp(projectPath);
break;
case 'mini':
createMiniApp(projectPath);
break;
}
console.log();
return false;
};
/**
* get app root path
* @return {} []
* is module exist
* @param {String} module []
* @return {Boolean} []
*/
var getAppRootPath = function(projectPath){
var path = projectPath;
path += program.es6 ? 'src' : 'app';
return path;
}
var isModuleExist = function(module){
var modelPath = think.getPath(module, 'model');
if(think.mode === think.mode_normal){
modelPath = think.getPath(module, 'controller');
}
return think.isDir(modelPath);
};
/**
* parse app config
* @param {} projectRootPath []
* @return {} []
*/
var parseAppConfig = function(){
var filepath = projectRootPath + '.thinkjsrc';
var content = fs.readFileSync(filepath, 'utf8');
var data = JSON.parse(content);
program.es6 = data.es6;
think.mode = think['mode_' + data.mode];
think.APP_PATH = getProjectAppPath();
};
/**
* get view root path;
* @param {String} projectPath []
* @return {String} []
*/
var getViewRootPath = function(projectPath, module){
var path = projectPath;
var getProjectViewPath = function(module){
if(program.es6){
path += 'view/' + module;
var APP_PATH = think.APP_PATH;
think.APP_PATH = projectRootPath + 'view';
var viewPath = think.getPath(module, '');
if(think.mode === think.mode_normal){
viewPath += '/' + module + '/';
}
think.APP_PATH = APP_PATH;
return path.normalize(viewPath).slice(0, -1);
}else{
path += 'app/' + module + '/view';
return think.getPath(module, 'view');
}
return path;
}
};
/**
* check env
* @return {} []
*/
var _checkEnv = function(){
if(!isThinkApp('./')){
console.log();
log(function(colors){
return colors.red('current path is not thinkjs project.\n');
});
process.exit();
}
parseAppConfig();
console.log();
};
/**
* copy common files
* @param {String} projectPath []
* @param {String} projectRootPath []
* @return {} []
*/
var copyCommonFiles = function(projectPath){
mkdir(projectPath);
var _copyWwwFiles = function(){
mkdir(projectRootPath);
copyFile('package.json', projectPath + 'package.json');
copyFile('.thinkjsrc', projectPath + '.thinkjsrc', {
"<createAt>": getDateTime(),
"<mode>": modeType,
copyFile('package.json', projectRootPath + 'package.json');
var mode = 'mini';
if(think.mode === think.mode_normal){
mode = 'normal';
}else if(think.mode === think.mode_module){
mode = 'module';
}
copyFile('.thinkjsrc', projectRootPath + '.thinkjsrc', {
'<createAt>': getDateTime(),
'<mode>': mode,
'"<es6>"': !!program.es6
});
copyFile('nginx.conf', projectPath + 'nginx.conf', {
ROOT_PATH: cwd + '/' + projectPath + 'www'
copyFile('nginx.conf', projectRootPath + 'nginx.conf', {
ROOT_PATH: cwd + '/' + projectRootPath + 'www'
});
copyFile('.gitignore', projectRootPath + '.gitignore');
mkdir(projectPath + 'www/');
copyFile('entrance/index.js', projectPath + 'www/index.js');
copyFile('entrance/production.js', projectPath + 'www/production.js');
copyFile('entrance/testing.js', projectPath + 'www/testing.js');
copyFile('entrance/README.md', projectPath + 'www/README.md');
mkdir(projectPath + 'www/static/');
mkdir(projectPath + 'www/static/js');
mkdir(projectPath + 'www/static/css');
mkdir(projectPath + 'www/static/img');
}
mkdir(projectRootPath + 'www/');
copyFile('www/index.js', projectRootPath + 'www/index.js');
copyFile('www/production.js', projectRootPath + 'www/production.js');
copyFile('www/testing.js', projectRootPath + 'www/testing.js');
copyFile('www/README.md', projectRootPath + 'www/README.md');
mkdir(projectRootPath + 'www/static/');
mkdir(projectRootPath + 'www/static/js');
mkdir(projectRootPath + 'www/static/css');
mkdir(projectRootPath + 'www/static/img');
};
/**
* module app
* @param {} projectPath []
* copy error template files
* @param {String} projectRootPath []
* @return {} []
*/
var createModuleApp = function(projectPath){
var rootPath = getAppRootPath(projectPath);
var _copyErrorTemplateFiles = function(){
mkdir(rootPath);
mkdir(rootPath + '/common');
mkdir(rootPath + '/common/runtime');
var module = 'common';
if(think.mode === think.mode_normal){
module = 'home';
}
mkdir(rootPath + '/common/bootstrap');
copyFile('bootstrap/hook.js', rootPath + '/common/bootstrap/hook.js');
copyFile('bootstrap/start.js', rootPath + '/common/bootstrap/start.js');
var controllerPath = think.getPath(module, 'controller');
mkdir(controllerPath);
copyFile('controller/error.js', controllerPath + '/error.js');
mkdir(rootPath + '/common/config');
copyFile('config/config.js', rootPath + '/common/config/config.js');
copyFile('config/tpl.js', rootPath + '/common/config/tpl.js');
copyFile('config/db.js', rootPath + '/common/config/db.js');
var commonViewPath = getProjectViewPath(module);
mkdir(rootPath + '/common/controller');
copyFile('controller/error.js', rootPath + '/common/controller/error.js');
var commonViewPath = getViewRootPath(projectPath, 'common');
mkdir(commonViewPath);
copyFile('view/error_403.html', commonViewPath + '/error_403.html');
copyFile('view/error_404.html', commonViewPath + '/error_404.html');
copyFile('view/error_500.html', commonViewPath + '/error_500.html');
copyFile('view/error_503.html', commonViewPath + '/error_503.html');
mkdir(rootPath + '/home/');
mkdir(rootPath + '/home/config');
copyFile('config/config.js', rootPath + '/home/config/config.js');
mkdir(rootPath + '/home/controller');
copyFile('controller/base.js', rootPath + '/home/controller/base.js');
copyFile('controller/index.js', rootPath + '/home/controller/index.js');
mkdir(rootPath + '/home/logic');
copyFile('logic/index.js', rootPath + '/home/logic/index.js');
mkdir(rootPath + '/home/model');
copyFile('model/index.js', rootPath + '/home/model/index.js');
var commonViewPath = getViewRootPath(projectPath, 'home');
mkdir(commonViewPath);
copyFile('view/index_index.html', commonViewPath + '/index_index.html');
}
};
/**
* create mini app
* @param {} projectPath []
* copy common config files
* @return {} []
*/
var createMiniApp = function(projectPath){
var _copyCommonConfigFiles = function(){
var rootPath = think.getPath('common', 'config');
mkdir(rootPath);
copyFile('config/config.js', rootPath + '/config.js', false);
copyFile('config/tpl.js', rootPath + '/tpl.js');
copyFile('config/db.js', rootPath + '/db.js');
mkdir(rootPath + '/env');
copyFile('config/env/development.js', rootPath + '/env/development.js');
copyFile('config/env/testing.js', rootPath + '/env/testing.js');
copyFile('config/env/production.js', rootPath + '/env/production.js');
mkdir(rootPath + '/locale');
copyFile('config/locale/en.js', rootPath + '/locale/en.js');
};
/**
* copy bootstrap files
* @return {} []
*/
var _copyCommonBootstrapFiles = function(){
var rootPath = think.getPath('common', 'bootstrap');
mkdir(rootPath);
copyFile('bootstrap/hook.js', rootPath + '/hook.js');
copyFile('bootstrap/start.js', rootPath + '/start.js');
};
/**
* create module
* @param {String} module []
* @return {} []
*/
var _createModule = function(module){
if(isModuleExist(module)){
log(function(colors){
return colors.red('module `' + module + '` is exist.\n');
});
process.exit();
}
}
//config files
var configPath = think.getPath(module, 'config');
mkdir(configPath);
copyFile('config/config.js', configPath + '/config.js', false);
//controller files
var controllerPath = think.getPath(module, 'controller');
mkdir(controllerPath);
copyFile('controller/base.js', controllerPath + '/base.js');
copyFile('controller/index.js', controllerPath + '/index.js');
//logic files
var logicPath = think.getPath(module, 'logic');
mkdir(logicPath);
copyFile('logic/index.js', logicPath + '/index.js');
//model files
var modelPath = think.getPath(module, 'model');
mkdir(modelPath);
copyFile('model/index.js', modelPath + '/index.js', false);
//view files
var viewPath = getProjectViewPath(module);
mkdir(viewPath);
copyFile('view/index_index.html', viewPath + '/index_index.html');
};
/**
* create module
* @param {} module []
* @return {} []
*/
var createModule = function(module){
_checkEnv();
_createModule(module);
};
/**
* create controller
* @param {} controller []
* @return {} []
*/
var createController = function(controller){
_checkEnv();
controller = controller.split('/');
var module = 'home';
if(controller.length === 2){
module = controller[0];
controller = controller[1];
}else{
controller = controller[0];
}
if(!isModuleExist(module)){
_createModule(module);
}
var controllerPath = think.getPath(module, 'controller');
var file = 'index.js';
if(program.rest){
file = 'rest.js';
}
copyFile('controller/' + file, controllerPath + '/' + controller + '.js');
var logicPath = think.getPath(module, 'logic');
copyFile('logic/index.js', logicPath + '/' + controller + '.js');
console.log();
};
/**
* create model file
* @param {String} model []
* @return {} []
*/
var createModel = function(model){
_checkEnv();
model = model.split('/');
var module = 'home';
if(model.length === 2){
module = model[0];
model = model[1];
}else{
model = model[0];
}
if(!isModuleExist(module)){
_createModule(module);
}
var file = 'index.js';
if(program.relation){
file = 'relation.js';
}else if(program.mongo){
file = 'mongo.js';
}
var controllerPath = think.getPath(module, 'model');
copyFile('model/' + file, controllerPath + '/' + model + '.js');
console.log();
};
/**
* module app
* @param {} projectRootPath []
* @return {} []
*/
var _createProject = function(){
_copyWwwFiles();
mkdir(think.APP_PATH);
var runtimePath = think.getPath('common', 'runtime');
mkdir(runtimePath);
_copyCommonBootstrapFiles();
_copyCommonConfigFiles();
_copyErrorTemplateFiles();
_createModule('home');
};
/**
* create project
* @param {String} projectRootPath []
* @return {} []
*/
var createProject = function(){
if(isThinkApp(projectRootPath)){
console.log();
log(function(colors){
return colors.red('path `' + projectRootPath + '` is already a thinkjs project.\n');
});
return;
}
console.log();
think.APP_PATH = getProjectAppPath();
_createProject();
console.log();
console.log(' enter path:');
console.log(' $ cd ' + projectRootPath);
console.log();
console.log(' install dependencies:');
console.log(' $ npm install');
console.log();
if(program.es6){
console.log(' watch compile:');
console.log(' $ npm run watch-compile');
console.log();
}
console.log(' run the app:');
console.log(' $ npm start');
console.log();
};
program.version(getVersion()).usage('[command] <options ...>');
program.option('-e, --es6', 'use es6 for project, used in `new` command');
program.option('-r, --rest', 'create rest controller, used in `controller` command');
program.option('-M, --mongo', 'create rest model, used in `model` command');
program.option('-M, --mongo', 'create mongo model, used in `model` command');
program.option('-R, --relation', 'create relation model, used in `model` command');
program.option('-m, --mode <mode>', 'project mode type, used in `new` command', function(mode){
if(modeTypeList.indexOf(mode) === -1){
throw new Error('mode value must one of mini,normal,module');
if(modeList.indexOf(mode) === -1){
throw new Error('mode value must one of ' + modeList.join(', '));
}
modeType = mode;
think.mode = think['mode_' + mode];
});
//create project
program.command('new <projectPath>').description('create project').action(function(projectPath){
projectPath = path.normalize(projectPath + '/');
createProject(projectPath);
projectRootPath = path.normalize(projectPath + '/');
createProject();
});
//create module
program.command('module <moduleName>').description('add module').action(function(module){
createModule(module.toLowerCase());
});
//create controlelr
program.command('controller <controllerName>').description('add controller').action(function(controller){
createController(controller.toLowerCase());
});
//create model
program.command('model <modelName>').description('add model').action(function(model){
createModel(model.toLowerCase());
});
program.parse(process.argv);
program.parse(process.argv);

View File

@ -31,14 +31,14 @@
"babel-runtime": "5.6.17",
"co": "4.6.0",
"colors": "1.1.0",
"validator": "4.0.2"
"validator": "4.0.2",
"commander": "2.8.1"
},
"devDependencies": {
"mocha": "1.20.1",
"muk": "0.3.1",
"istanbul": "*",
"babel": "*",
"commander": ""
"babel": "*"
},
"keywords": [
"thinkjs",

View File

@ -14,7 +14,7 @@ export default {
service_on: true, //Service available
timeout: 10, //10 seconds
timeout: 30, //30 seconds
resource_on: true,
resource_reg: /^(static\/|[^\/]+\.(?!js|html)\w+$)/,

View File

@ -167,9 +167,11 @@ export default class extends think.base {
}
think.log('Server running at http://' + (host || '127.0.0.1') + ':' + port + '/', 'THINK');
think.log(colors => `ThinkJS Version: ${think.version}`, 'THINK');
think.log(() => `ThinkJS Version: ${think.version}`, 'THINK');
think.log(colors => `WebSocket Status: ${colors.magenta(status)}`, 'THINK');
think.log(colors => `App Enviroment: ${colors.magenta(think.env)}`, 'THINK');
think.log(colors => `File Auto Reload: ${colors.magenta(think.config('auto_reload'))}`, 'THINK');
think.log(colors => `App Enviroment: ${colors.magenta(think.env)}\n`, 'THINK');
}
/**
* cli mode

View File

@ -253,7 +253,6 @@ think.getPath = (module, type = think.dirname.controller, prefix = '') => {
let filepath = `${think.APP_PATH}${prefix}/${type}`;
switch(type){
case think.dirname.controller:
case think.dirname.model:
case think.dirname.logic:
case think.dirname.service:
case think.dirname.view:
@ -344,16 +343,16 @@ think.isPrevent = err => {
* @TODO
* @return {} []
*/
think.log = (msg, type, startTime) => {
think.log = (msg, type, showTime) => {
//when type or startTime is boolean
//when type or showTime is boolean
//only show log when value is true
if(type === false || startTime === false){
if(type === false || showTime === false){
return;
}else if(type === true){
type = '';
}else if(startTime === true){
startTime = '';
}else if(showTime === true){
showTime = '';
}
let fn = d => {
@ -363,7 +362,11 @@ think.log = (msg, type, startTime) => {
let d = new Date();
let date = `${d.getFullYear()}-${fn(d.getMonth() + 1)}-${fn(d.getDate())}`;
let time = `${fn(d.getHours())}:${fn(d.getMinutes())}:${fn(d.getSeconds())}`;
let dateTime = colors.gray(`[${date} ${time}] `);
if(showTime === null){
dateTime = '';
}
let preError = thinkCache(thinkCache.COLLECTION, 'prev_error');
if (think.isError(msg)) {
@ -381,8 +384,8 @@ think.log = (msg, type, startTime) => {
// if(msg.length > 300){
// msg = msg.substr(0, 300) + '...';
// }
if(startTime){
let time = Date.now() - startTime;
if(think.isNumber(showTime)){
let time = Date.now() - showTime;
msg += ' ' + colors.green(`${time}ms`);
}
if(type){
@ -1412,7 +1415,7 @@ think.statusAction = (status = 500, http, log) => {
think.log(http.error);
}
let name = `${http.module}/${think.dirname.controller}/error`;
let name = `${think.config('default_module')}/${think.dirname.controller}/error`;
if(think.mode === think.mode_module){
name = `${think.dirname.common}/${think.dirname.controller}/error`;
}

31
template/.gitignore vendored Normal file
View File

@ -0,0 +1,31 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage/
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules/
# IDE config
.idea
# output
output/
output.tar.gz

View File

@ -1,5 +1,5 @@
{
createAt: "<createAt>",
mode: "<mode>",
es6: "<es6>"
"createAt": "<createAt>",
"mode": "<mode>",
"es6": "<es6>"
}

5
template/config/env/development.js vendored Normal file
View File

@ -0,0 +1,5 @@
'use strict';
module.exports = {
};

View File

@ -0,0 +1,5 @@
'use strict';
export default {
};

5
template/config/env/es6_production.js vendored Normal file
View File

@ -0,0 +1,5 @@
'use strict';
export default {
};

5
template/config/env/es6_testing.js vendored Normal file
View File

@ -0,0 +1,5 @@
'use strict';
export default {
};

5
template/config/env/production.js vendored Normal file
View File

@ -0,0 +1,5 @@
'use strict';
module.exports = {
};

5
template/config/env/testing.js vendored Normal file
View File

@ -0,0 +1,5 @@
'use strict';
module.exports = {
};

View File

@ -0,0 +1,5 @@
'use strict';
module.exports = {
};

View File

@ -0,0 +1,5 @@
'use strict';
export default {
};

View File

@ -9,7 +9,11 @@ module.exports = think.controller({
* @return {Promise} []
*/
displayErrorPage: function(status){
var file = `common/error/${status}.html`;
var module = 'common';
if(think.mode !== think.mode_module){
module = this.config('default_module');
}
var file = module + '/error/' + status + '.html';
var options = this.config('tpl');
options = think.extend({}, options, {type: 'ejs'});
return this.display(file, options);

View File

@ -9,8 +9,12 @@ export default class extends think.controller.base {
* @return {Promise} []
*/
displayErrorPage(status){
var file = `common/error/${status}.html`;
var options = this.config('tpl');
let module = 'common';
if(think.mode !== think.mode_module){
module = this.config('default_module');
}
let file = `${module}/error/${status}.html`;
let options = this.config('tpl');
options = think.extend({}, options, {type: 'ejs'});
return this.display(file, options);
}

View File

@ -8,7 +8,7 @@ export default class extends Base {
* @return {Promise} []
*/
indexAction(){
//auto render template file home/index_index.html
//auto render template file index_index.html
return this.display();
}
}

View File

@ -8,7 +8,7 @@ module.exports = think.controller(Base, {
* @return {Promise} []
*/
indexAction: function(self){
//auto render template file home/index_index.html
//auto render template file index_index.html
return self.display();
}
});

View File

@ -1,61 +0,0 @@
## application
### start server
*development*
```js
node www/index.js
```
*testing*
```js
node www/testing.js
```
*production*
```js
node www/production.js
```
or use pm2 to manage node:
```
pm2 start www/production.js
```
### compile es6 code
```
npm run compile
```
watch file change:
```
npm run wacth-compile
```
### how to link resource
*in template file*
```html
<script src="/static/js/a.js"></script>
<img src="/static/img/a.png" alt="">
<link rel="stylesheet" href="/static/css/a.js">
```
*link image in css*
```css
.a{
background: url(../img/a.png) no-repeat;
}
```

View File

@ -0,0 +1,7 @@
'use strict';
/**
* model
*/
export default class extends think.model.mongo {
}

View File

@ -0,0 +1,7 @@
'use strict';
/**
* model
*/
export default class extends think.model.relation {
}

8
template/model/mongo.js Normal file
View File

@ -0,0 +1,8 @@
'use strict';
/**
* model
* @type {Class}
*/
module.exports = think.model('mongo', {
});

View File

@ -0,0 +1,8 @@
'use strict';
/**
* model
* @type {Class}
*/
module.exports = think.model('relation', {
});

View File

@ -8,7 +8,6 @@
"watch-compile": "npm run compile -- --watch"
},
"dependencies": {
"thinkjs": "2.x.x",
"babel": "5.8.21",
"babel-runtime": "5.6.17"
}

View File

@ -373,14 +373,14 @@ describe('core/think.js', function(){
think.mode = mode;
think.APP_PATH = APP_PATH;
})
it('mode normal with model', function(){
it('mode normal with controller', function(){
var mode = think.mode;
think.mode = think.mode_normal;
var APP_PATH = think.APP_PATH;
think.APP_PATH = '/path/to/project/app';
think.config('default_module', 'home')
var path = think.getPath(undefined, think.dirname.model);
assert.equal(path, '/path/to/project/app/model/home');
var path = think.getPath(undefined, think.dirname.controller);
assert.equal(path, '/path/to/project/app/controller/home');
think.mode = mode;
think.APP_PATH = APP_PATH;
})