merge_develop
Showing
16 changed files
with
460 additions
and
165 deletions
.editorconfig
0 → 100644
1 | - | ||
2 | -# Created by https://www.gitignore.io/api/node,webstorm,netbeans,sublimetext,vim | ||
3 | - | ||
4 | -### Node ### | ||
5 | -# Logs | ||
6 | -logs | ||
7 | -*.log | ||
8 | -npm-debug.log* | ||
9 | - | ||
10 | -# Runtime data | ||
11 | -pids | ||
12 | -*.pid | ||
13 | -*.seed | ||
14 | - | ||
15 | -# Directory for instrumented libs generated by jscoverage/JSCover | ||
16 | -lib-cov | ||
17 | - | ||
18 | -# Coverage directory used by tools like istanbul | ||
19 | -coverage | ||
20 | - | ||
21 | -# nyc test coverage | ||
22 | -.nyc_output | ||
23 | - | ||
24 | -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
25 | -.grunt | ||
26 | - | ||
27 | -# node-waf configuration | ||
28 | -.lock-wscript | ||
29 | - | ||
30 | -# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
31 | -build/Release | ||
32 | - | ||
33 | -# Dependency directories | ||
34 | -node_modules | ||
35 | -jspm_packages | ||
36 | - | ||
37 | -# Optional npm cache directory | ||
38 | -.npm | ||
39 | - | ||
40 | -# Optional REPL history | ||
41 | -.node_repl_history | ||
42 | - | ||
43 | - | ||
44 | -### WebStorm ### | ||
45 | -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm | ||
46 | -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
47 | - | ||
48 | -# User-specific stuff: | ||
49 | -.idea/workspace.xml | ||
50 | -.idea/tasks.xml | ||
51 | -.idea/dictionaries | ||
52 | -.idea/vcs.xml | ||
53 | -.idea/jsLibraryMappings.xml | ||
54 | - | ||
55 | -# Sensitive or high-churn files: | ||
56 | -.idea/dataSources.ids | ||
57 | -.idea/dataSources.xml | ||
58 | -.idea/dataSources.local.xml | ||
59 | -.idea/sqlDataSources.xml | ||
60 | -.idea/dynamic.xml | ||
61 | -.idea/uiDesigner.xml | ||
62 | - | ||
63 | -# Gradle: | ||
64 | -.idea/gradle.xml | ||
65 | -.idea/libraries | ||
66 | - | ||
67 | -# Mongo Explorer plugin: | ||
68 | -.idea/mongoSettings.xml | ||
69 | - | ||
70 | -## File-based project format: | ||
71 | -*.iws | ||
72 | - | ||
73 | -## Plugin-specific files: | ||
74 | - | ||
75 | -# IntelliJ | ||
76 | -/out/ | ||
77 | - | ||
78 | -# mpeltonen/sbt-idea plugin | ||
79 | -.idea_modules/ | ||
80 | - | ||
81 | -# JIRA plugin | ||
82 | -atlassian-ide-plugin.xml | ||
83 | - | ||
84 | -# Crashlytics plugin (for Android Studio and IntelliJ) | ||
85 | -com_crashlytics_export_strings.xml | ||
86 | -crashlytics.properties | ||
87 | -crashlytics-build.properties | ||
88 | -fabric.properties | ||
89 | - | ||
90 | -### WebStorm Patch ### | ||
91 | -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 | ||
92 | - | ||
93 | -# *.iml | ||
94 | -# modules.xml | ||
95 | - | ||
96 | - | ||
97 | -### NetBeans ### | ||
98 | -nbproject/private/ | ||
99 | -build/ | ||
100 | -nbbuild/ | ||
101 | -dist/ | ||
102 | -nbdist/ | ||
103 | -nbactions.xml | ||
104 | -.nb-gradle/ | ||
105 | - | ||
106 | - | ||
107 | -### SublimeText ### | ||
108 | -# cache files for sublime text | ||
109 | -*.tmlanguage.cache | ||
110 | -*.tmPreferences.cache | ||
111 | -*.stTheme.cache | ||
112 | - | ||
113 | -# workspace files are user-specific | ||
114 | -*.sublime-workspace | ||
115 | - | ||
116 | -# project files should be checked into the repository, unless a significant | ||
117 | -# proportion of contributors will probably not be using SublimeText | ||
118 | -# *.sublime-project | ||
119 | - | ||
120 | -# sftp configuration file | ||
121 | -sftp-config.json | ||
122 | - | ||
123 | - | ||
124 | -### Vim ### | ||
125 | -# swap | ||
126 | -[._]*.s[a-w][a-z] | ||
127 | -[._]s[a-w][a-z] | ||
128 | -# session | ||
129 | -Session.vim | ||
130 | -# temporary | ||
131 | -.netrwhist | ||
132 | -*~ | ||
133 | -# auto-generated tag files | ||
134 | -tags | ||
135 | - | ||
136 | -### YOHO ### | ||
137 | -dist | 1 | + |
2 | +# Created by https://www.gitignore.io/api/node,webstorm,netbeans,sublimetext,vim | ||
3 | + | ||
4 | +### Node ### | ||
5 | +# Logs | ||
6 | +logs | ||
7 | +*.log | ||
8 | +npm-debug.log* | ||
9 | + | ||
10 | +# Runtime data | ||
11 | +pids | ||
12 | +*.pid | ||
13 | +*.seed | ||
14 | + | ||
15 | +# Directory for instrumented libs generated by jscoverage/JSCover | ||
16 | +lib-cov | ||
17 | + | ||
18 | +# Coverage directory used by tools like istanbul | ||
19 | +coverage | ||
20 | + | ||
21 | +# nyc test coverage | ||
22 | +.nyc_output | ||
23 | + | ||
24 | +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
25 | +.grunt | ||
26 | + | ||
27 | +# node-waf configuration | ||
28 | +.lock-wscript | ||
29 | + | ||
30 | +# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
31 | +build/Release | ||
32 | + | ||
33 | +# Dependency directories | ||
34 | +node_modules | ||
35 | +jspm_packages | ||
36 | + | ||
37 | +# Optional npm cache directory | ||
38 | +.npm | ||
39 | + | ||
40 | +# Optional REPL history | ||
41 | +.node_repl_history | ||
42 | + | ||
43 | + | ||
44 | +### WebStorm ### | ||
45 | +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm | ||
46 | +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
47 | +.idea/ | ||
48 | +# User-specific stuff: | ||
49 | +.idea/workspace.xml | ||
50 | +.idea/tasks.xml | ||
51 | +.idea/dictionaries | ||
52 | +.idea/vcs.xml | ||
53 | +.idea/jsLibraryMappings.xml | ||
54 | + | ||
55 | +# Sensitive or high-churn files: | ||
56 | +.idea/dataSources.ids | ||
57 | +.idea/dataSources.xml | ||
58 | +.idea/dataSources.local.xml | ||
59 | +.idea/sqlDataSources.xml | ||
60 | +.idea/dynamic.xml | ||
61 | +.idea/uiDesigner.xml | ||
62 | + | ||
63 | +# Gradle: | ||
64 | +.idea/gradle.xml | ||
65 | +.idea/libraries | ||
66 | + | ||
67 | +# Mongo Explorer plugin: | ||
68 | +.idea/mongoSettings.xml | ||
69 | + | ||
70 | +## File-based project format: | ||
71 | +*.iws | ||
72 | + | ||
73 | +## Plugin-specific files: | ||
74 | + | ||
75 | +# IntelliJ | ||
76 | +/out/ | ||
77 | + | ||
78 | +# mpeltonen/sbt-idea plugin | ||
79 | +.idea_modules/ | ||
80 | + | ||
81 | +# JIRA plugin | ||
82 | +atlassian-ide-plugin.xml | ||
83 | + | ||
84 | +# Crashlytics plugin (for Android Studio and IntelliJ) | ||
85 | +com_crashlytics_export_strings.xml | ||
86 | +crashlytics.properties | ||
87 | +crashlytics-build.properties | ||
88 | +fabric.properties | ||
89 | + | ||
90 | +### WebStorm Patch ### | ||
91 | +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 | ||
92 | + | ||
93 | +# *.iml | ||
94 | +# modules.xml | ||
95 | + | ||
96 | + | ||
97 | +### NetBeans ### | ||
98 | +nbproject/private/ | ||
99 | +build/ | ||
100 | +nbbuild/ | ||
101 | +dist/ | ||
102 | +nbdist/ | ||
103 | +nbactions.xml | ||
104 | +.nb-gradle/ | ||
105 | + | ||
106 | + | ||
107 | +### SublimeText ### | ||
108 | +# cache files for sublime text | ||
109 | +*.tmlanguage.cache | ||
110 | +*.tmPreferences.cache | ||
111 | +*.stTheme.cache | ||
112 | + | ||
113 | +# workspace files are user-specific | ||
114 | +*.sublime-workspace | ||
115 | + | ||
116 | +# project files should be checked into the repository, unless a significant | ||
117 | +# proportion of contributors will probably not be using SublimeText | ||
118 | +# *.sublime-project | ||
119 | + | ||
120 | +# sftp configuration file | ||
121 | +sftp-config.json | ||
122 | + | ||
123 | + | ||
124 | +### Vim ### | ||
125 | +# swap | ||
126 | +[._]*.s[a-w][a-z] | ||
127 | +[._]s[a-w][a-z] | ||
128 | +# session | ||
129 | +Session.vim | ||
130 | +# temporary | ||
131 | +.netrwhist | ||
132 | +*~ | ||
133 | +# auto-generated tag files | ||
134 | +tags | ||
135 | + | ||
136 | +### YOHO ### | ||
137 | +dist | ||
138 | public/css/* | 138 | public/css/* |
139 | -public/bundle/* | ||
140 | -.eslintcache | 139 | +public/bundle/* |
140 | +.eslintcache | ||
141 | +*.log.* |
@@ -3,21 +3,26 @@ | @@ -3,21 +3,26 @@ | ||
3 | * @author: xuqi<qi.xu@yoho.cn> | 3 | * @author: xuqi<qi.xu@yoho.cn> |
4 | * @date: 2016/4/25 | 4 | * @date: 2016/4/25 |
5 | */ | 5 | */ |
6 | +'use strict'; | ||
6 | 7 | ||
7 | -var express = require('express'), | 8 | +let express = require('express'), |
8 | path = require('path'), | 9 | path = require('path'), |
9 | bodyParser = require('body-parser'), | 10 | bodyParser = require('body-parser'), |
10 | - favicon = require('serve-favicon'), | ||
11 | - cookieParser = require('cookie-parser'); | 11 | + cookieParser = require('cookie-parser'), |
12 | + favicon = require('serve-favicon'); | ||
12 | 13 | ||
13 | -var app = express(); | 14 | +require('express-handlebars'); |
15 | + | ||
16 | + | ||
17 | +let app = express(); | ||
14 | 18 | ||
15 | app.set('view engine', '.hbs'); | 19 | app.set('view engine', '.hbs'); |
16 | 20 | ||
21 | +app.use(favicon(path.join(__dirname, '/public/favicon.ico'))); | ||
22 | +app.use(express.static(path.join(__dirname, 'public'))); | ||
17 | app.use(bodyParser.json()); | 23 | app.use(bodyParser.json()); |
18 | app.use(bodyParser.urlencoded({extended: false})); | 24 | app.use(bodyParser.urlencoded({extended: false})); |
19 | app.use(cookieParser()); | 25 | app.use(cookieParser()); |
20 | -app.use(express.static(path.join(__dirname, 'public'))); | ||
21 | 26 | ||
22 | // dispatcher | 27 | // dispatcher |
23 | require('./dispatch')(app); | 28 | require('./dispatch')(app); |
apps/guang/index.js
0 → 100644
1 | +/** | ||
2 | + * sub app guang | ||
3 | + * @author: hbomb<qiqi.zhou@yoho.cn> | ||
4 | + * @date: 2016/05/06 | ||
5 | + */ | ||
6 | + | ||
7 | +var express = require('express'), | ||
8 | + path = require('path'), | ||
9 | + hbs = require('express-handlebars'); | ||
10 | + | ||
11 | +var app = express(); | ||
12 | + | ||
13 | +// set view engin | ||
14 | +var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root | ||
15 | + | ||
16 | +app.set('views', path.join(__dirname, 'views/action')); | ||
17 | +app.engine('.hbs', hbs({ | ||
18 | + extname: '.hbs', | ||
19 | + defaultLayout: 'layout', | ||
20 | + layoutsDir: doraemon, | ||
21 | + partialsDir: ['./views/partial', `${doraemon}/partial`], | ||
22 | + helpers: 'helpers' | ||
23 | +})); | ||
24 | + | ||
25 | +// router | ||
26 | +require('./router')(app); | ||
27 | + | ||
28 | +module.exports = app; |
apps/guang/router.js
0 → 100644
1 | +/** | ||
2 | + * router of sub app guang | ||
3 | + * @author: hbomb<qiqi.zhou@yoho.cn> | ||
4 | + * @date: 2016/05/06 | ||
5 | + */ | ||
6 | + | ||
7 | +'use strict'; | ||
8 | + | ||
9 | + | ||
10 | +let API = require('../../library/api'); | ||
11 | + | ||
12 | +// Your controller here | ||
13 | +let router = function(app) { | ||
14 | + app.get('/', function(req, res) { | ||
15 | + let api = new API(); | ||
16 | + let name = '/productColor/queryProductColors'; | ||
17 | + | ||
18 | + api.get(name, {}).then(function(body) { | ||
19 | + res.send(body); | ||
20 | + }).catch(function() { | ||
21 | + res.send('something wrong'); | ||
22 | + }); | ||
23 | + }); | ||
24 | +}; | ||
25 | + | ||
26 | + | ||
27 | + | ||
28 | + | ||
29 | +module.exports = router; |
config/common.js
0 → 100644
1 | +/** | ||
2 | + * 系统配置 | ||
3 | + * | ||
4 | + * @author hbomb qiqi.zhou@yoho.cn | ||
5 | + * @date 2016/05/06 | ||
6 | + */ | ||
7 | + | ||
8 | +module.exports = { | ||
9 | + domains: { | ||
10 | + api: 'http://192.168.102.202:8088/platform' | ||
11 | + }, | ||
12 | + loggers: { | ||
13 | + infoFile: { | ||
14 | + name: 'info', | ||
15 | + level: 'info', | ||
16 | + filename: 'info.log' | ||
17 | + }, | ||
18 | + errorFile: { | ||
19 | + name: 'error', | ||
20 | + level: 'error', | ||
21 | + filename: 'error.log', | ||
22 | + handleExceptions: true | ||
23 | + }, | ||
24 | + udp: { // send by udp | ||
25 | + level: 'debug', // logger level | ||
26 | + host: '192.168.102.162', // influxdb host | ||
27 | + port: '4444'// influxdb port | ||
28 | + }, | ||
29 | + console: { | ||
30 | + level: 'debug', | ||
31 | + colorize: 'all', | ||
32 | + prettyPrint: true | ||
33 | + } | ||
34 | + } | ||
35 | +}; |
@@ -8,21 +8,64 @@ | @@ -8,21 +8,64 @@ | ||
8 | 8 | ||
9 | const rp = require('request-promise'); | 9 | const rp = require('request-promise'); |
10 | const _ = require('lodash'); | 10 | const _ = require('lodash'); |
11 | +const log = require('./logger'); | ||
12 | +const api = require('../config/common').domains.api; | ||
13 | +const Timer = require('./timer'); | ||
11 | 14 | ||
12 | -const ApiUrl = 'http://testapi.yoho.cn:28078/'; | 15 | +/** |
16 | + * 日志打印 | ||
17 | + * @param {Object} requestPromise 请求的promise对象 | ||
18 | + */ | ||
19 | +function logPrint(options, requestPromise) { | ||
20 | + | ||
21 | + // 接口统计 | ||
22 | + let timer = new Timer(); | ||
23 | + | ||
24 | + timer.put('getApi');// 统计时间开始 | ||
25 | + | ||
26 | + let method = options.method ? options.method : 'get'; | ||
27 | + | ||
28 | + log.info('API Begin %s call: %s, parms: %j', | ||
29 | + method, options.url, options.qs, {}); | ||
30 | + requestPromise.then((body) => { | ||
31 | + let duration = timer.put('getApi');// 接口返回 | ||
32 | + | ||
33 | + log.info('API %s res: %s, parms: %j , durationMs: %d ms , body: %s', | ||
34 | + method, options.url, options.qs, duration, body); | ||
35 | + }).catch((error) => { | ||
36 | + let duration = timer.put('getApi');// 接口返回 | ||
37 | + | ||
38 | + log.error('API %s res: %s, parms: %j , durationMs: %d ms error: %s , statusCode: %d', | ||
39 | + method, options.url, options.qs, duration, error.message, error.statusCode); | ||
40 | + }); | ||
41 | +} | ||
42 | + | ||
43 | + | ||
44 | +let ApiUrl; | ||
13 | 45 | ||
14 | class API { | 46 | class API { |
15 | 47 | ||
48 | + constructor(url) { | ||
49 | + ApiUrl = url || api; | ||
50 | + } | ||
51 | + | ||
16 | /** | 52 | /** |
17 | * get | 53 | * get |
18 | * @param url String | 54 | * @param url String |
19 | * @param data Obejct | 55 | * @param data Obejct |
20 | */ | 56 | */ |
21 | get(url, data) { | 57 | get(url, data) { |
22 | - return rp({ | 58 | + |
59 | + let options = { | ||
23 | url: `${ApiUrl}${url}`, | 60 | url: `${ApiUrl}${url}`, |
24 | qs: data | 61 | qs: data |
25 | - }); | 62 | + }; |
63 | + | ||
64 | + let requestPromise = rp(options); | ||
65 | + | ||
66 | + logPrint(options, requestPromise);// 日志打印 | ||
67 | + | ||
68 | + return requestPromise; | ||
26 | } | 69 | } |
27 | 70 | ||
28 | /** | 71 | /** |
@@ -30,13 +73,19 @@ class API { | @@ -30,13 +73,19 @@ class API { | ||
30 | * @params: urls => Array[Object[url[string], data[object]]] | 73 | * @params: urls => Array[Object[url[string], data[object]]] |
31 | */ | 74 | */ |
32 | multiGet(urls) { | 75 | multiGet(urls) { |
33 | - var rps = []; | 76 | + let rps = []; |
34 | 77 | ||
35 | _.forEach(urls, function(el) { | 78 | _.forEach(urls, function(el) { |
36 | - rps.push(rp({ | 79 | + let options = { |
37 | url: `${ApiUrl}${el.url}`, | 80 | url: `${ApiUrl}${el.url}`, |
38 | qs: el.data | 81 | qs: el.data |
39 | - })); | 82 | + }; |
83 | + | ||
84 | + let requestPromise = rp(options); | ||
85 | + | ||
86 | + logPrint(options, requestPromise);// 打印日志 | ||
87 | + | ||
88 | + rps.push(requestPromise); | ||
40 | }); | 89 | }); |
41 | 90 | ||
42 | return Promise.all(rps).then((d) => { | 91 | return Promise.all(rps).then((d) => { |
@@ -50,11 +99,17 @@ class API { | @@ -50,11 +99,17 @@ class API { | ||
50 | * @param data Obejct | 99 | * @param data Obejct |
51 | */ | 100 | */ |
52 | post(url, data) { | 101 | post(url, data) { |
53 | - return rp({ | 102 | + let options = { |
54 | url: `${ApiUrl}${url}`, | 103 | url: `${ApiUrl}${url}`, |
55 | method: 'post', | 104 | method: 'post', |
56 | form: data | 105 | form: data |
57 | - }); | 106 | + }; |
107 | + | ||
108 | + let requestPromise = rp(options); | ||
109 | + | ||
110 | + logPrint(options, requestPromise);// 打印日志 | ||
111 | + | ||
112 | + return requestPromise; | ||
58 | } | 113 | } |
59 | } | 114 | } |
60 | 115 |
library/logger.js
0 → 100644
1 | + | ||
2 | +/** | ||
3 | + * 日志工具类 | ||
4 | + * @author: hbomb<qiqi.zhou@yoho.cn> | ||
5 | + * @date: 2016/05/06 | ||
6 | + */ | ||
7 | + 'use strict'; | ||
8 | + | ||
9 | + let winston = require('winston'), | ||
10 | + config = require('../config/common'), | ||
11 | + FileTransport = require('winston-daily-rotate-file'); | ||
12 | + | ||
13 | + require('influxdb-winston'); | ||
14 | + | ||
15 | + let logger = new (winston.Logger)({ | ||
16 | + transports: [ | ||
17 | + new (FileTransport)(config.loggers.infoFile), | ||
18 | + new (FileTransport)(config.loggers.errorFile), | ||
19 | + new (winston.transports.UdpTransport)(config.loggers.udp), | ||
20 | + new (winston.transports.Console)(config.loggers.console) | ||
21 | + ] | ||
22 | + }); | ||
23 | + | ||
24 | + module.exports = logger; |
@@ -31,7 +31,7 @@ const packageSort = argument => { | @@ -31,7 +31,7 @@ const packageSort = argument => { | ||
31 | } | 31 | } |
32 | 32 | ||
33 | return newObj; | 33 | return newObj; |
34 | -} | 34 | +}; |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * 生成签名 | 37 | * 生成签名 |
@@ -46,7 +46,7 @@ const makeSign = argument => { | @@ -46,7 +46,7 @@ const makeSign = argument => { | ||
46 | }); | 46 | }); |
47 | 47 | ||
48 | return md5(qs.join('&')).toLowerCase(); | 48 | return md5(qs.join('&')).toLowerCase(); |
49 | -} | 49 | +}; |
50 | 50 | ||
51 | // 生成API签名,调用后端接口的时候有私钥校验 | 51 | // 生成API签名,调用后端接口的时候有私钥校验 |
52 | exports.apiSign = (params) => { | 52 | exports.apiSign = (params) => { |
@@ -91,4 +91,4 @@ exports.webSign = (params) => { | @@ -91,4 +91,4 @@ exports.webSign = (params) => { | ||
91 | var webPrivateKey = 'yohobuyapp'; | 91 | var webPrivateKey = 'yohobuyapp'; |
92 | 92 | ||
93 | return params.key === md5(md5(webPrivateKey) + params.uid); | 93 | return params.key === md5(md5(webPrivateKey) + params.uid); |
94 | -}; | ||
94 | +}; |
library/timer.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +/** | ||
4 | + * 计时类 | ||
5 | + * @example | ||
6 | + * let timer = new Timer(); | ||
7 | + * timer.put('profile'); | ||
8 | + * timer.put('proflie'); // console output: 12.14 | ||
9 | + * | ||
10 | + * @author: hbomb<qiqi.zhou@yoho.cn> | ||
11 | + * @date: 2016/05/07 | ||
12 | + */ | ||
13 | + | ||
14 | +class Timer { | ||
15 | + constructor() { | ||
16 | + this.timers = {}; | ||
17 | + } | ||
18 | + | ||
19 | + /** | ||
20 | + * 打点计时 | ||
21 | + */ | ||
22 | + put(label) { | ||
23 | + let labelTime = this.timers[label]; | ||
24 | + | ||
25 | + if (labelTime) { | ||
26 | + let duration = process.hrtime(labelTime); | ||
27 | + | ||
28 | + return this._round(duration[1]); | ||
29 | + } else { | ||
30 | + this.timers[label] = process.hrtime(); | ||
31 | + } | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * 格式化成毫秒 | ||
36 | + * @param {Number} value 纳秒 | ||
37 | + */ | ||
38 | + _round(value) { | ||
39 | + return Math.round(value / 10000) / 100; | ||
40 | + } | ||
41 | + | ||
42 | +} | ||
43 | + | ||
44 | +module.exports = Timer; |
lint.js
0 → 100644
1 | +const shelljs = require('shelljs'); | ||
2 | +const path = require('path'); | ||
3 | + | ||
4 | +const changeFiles = { | ||
5 | + js: shelljs.exec('git diff --cached --name-only --diff-filter=ACM | grep .js$', {silent: true}).stdout, | ||
6 | + css: shelljs.exec('git diff --cached --name-only --diff-filter=ACM | grep .css$', {silent: true}).stdout | ||
7 | +}; | ||
8 | +const lintPath = { | ||
9 | + js: path.resolve('./node_modules/.bin/eslint'), | ||
10 | + css: path.resolve('./node_modules/.bin/stylelint') | ||
11 | +}; | ||
12 | +const lintResult = { | ||
13 | + js: {}, | ||
14 | + css: {} | ||
15 | +}; | ||
16 | + | ||
17 | +const ext = process.platform === 'win32' ? '.cmd' : ''; // Windows 平台需要加后缀 | ||
18 | + | ||
19 | +// 在执行检查脚本的时候,不显示 NPM 错误日志 | ||
20 | +if (!shelljs.grep('npm run -s', path.resolve('./.git/hooks/pre-commit')).stdout.trim()) { | ||
21 | + shelljs.sed('-i', 'npm run', 'npm run -s', path.resolve('./.git/hooks/pre-commit')); | ||
22 | +} | ||
23 | + | ||
24 | +if (changeFiles.js) { | ||
25 | + changeFiles.js = changeFiles.js.replace(/\n/g, ' '); | ||
26 | + lintResult.js = shelljs.exec(`${lintPath.js}${ext} -c .eslintrc --cache --fix ${changeFiles.js}`); | ||
27 | +} | ||
28 | + | ||
29 | +if (changeFiles.css) { | ||
30 | + changeFiles.css = changeFiles.css.replace(/\n/g, ' '); | ||
31 | + lintResult.css = shelljs.exec(`${lintPath.css}${ext} --config .stylelintrc ${changeFiles.css}`); | ||
32 | +} | ||
33 | + | ||
34 | +if (lintResult.js.code || lintResult.css.code) { | ||
35 | + process.exit(lintResult.js.code || lintResult.css.code); // eslint-disable-line | ||
36 | +} |
@@ -12,9 +12,9 @@ | @@ -12,9 +12,9 @@ | ||
12 | "dev": "node_modules/.bin/nodemon -e js,hbs -i public/ app.js", | 12 | "dev": "node_modules/.bin/nodemon -e js,hbs -i public/ app.js", |
13 | "online": "NODE_ENV=\"production\" node app.js", | 13 | "online": "NODE_ENV=\"production\" node app.js", |
14 | "debug": "DEBUG=\"express:*\" node app.js", | 14 | "debug": "DEBUG=\"express:*\" node app.js", |
15 | - "lint-js": "node_modules/.bin/eslint -c .eslintrc --cache --fix `git diff --cached --name-only --diff-filter=ACM | grep .js$` app.js", | ||
16 | - "lint-css": "node_modules/.bin/stylelint --config .stylelintrc `git diff --cached --name-only --diff-filter=ACM | grep .css$`", | ||
17 | - "precommit": "npm run lint-js && npm run lint-css" | 15 | + "lint-js": "./node_modules/.bin/eslint -c .eslintrc --cache --fix .", |
16 | + "lint-css": "./node_modules/.bin/stylelint --config .stylelintrc public/**/*.css", | ||
17 | + "precommit": "node lint.js" | ||
18 | }, | 18 | }, |
19 | "license": "MIT", | 19 | "license": "MIT", |
20 | "dependencies": { | 20 | "dependencies": { |
@@ -22,11 +22,14 @@ | @@ -22,11 +22,14 @@ | ||
22 | "cookie-parser": "^1.4.1", | 22 | "cookie-parser": "^1.4.1", |
23 | "express": "^4.13.1", | 23 | "express": "^4.13.1", |
24 | "express-handlebars": "^3.0.0", | 24 | "express-handlebars": "^3.0.0", |
25 | - "lodash": "^4.8.2", | 25 | + "influxdb-winston": "^1.0.1", |
26 | + "lodash": "^4.12.0", | ||
26 | "md5": "^2.1.0", | 27 | "md5": "^2.1.0", |
27 | "morgan": "^1.7.0", | 28 | "morgan": "^1.7.0", |
28 | - "request-promise": "^2.0.1", | ||
29 | - "serve-favicon": "^2.3.0" | 29 | + "request-promise": "^3.0.0", |
30 | + "serve-favicon": "^2.3.0", | ||
31 | + "winston": "^2.2.0", | ||
32 | + "winston-daily-rotate-file": "^1.0.1" | ||
30 | }, | 33 | }, |
31 | "devDependencies": { | 34 | "devDependencies": { |
32 | "autoprefixer": "^6.3.6", | 35 | "autoprefixer": "^6.3.6", |
@@ -39,6 +42,8 @@ | @@ -39,6 +42,8 @@ | ||
39 | "gulp-sourcemaps": "^2.0.0-alpha", | 42 | "gulp-sourcemaps": "^2.0.0-alpha", |
40 | "gulp-util": "^3.0.7", | 43 | "gulp-util": "^3.0.7", |
41 | "husky": "^0.11.4", | 44 | "husky": "^0.11.4", |
45 | + "mocha": "^2.4.5", | ||
46 | + "nodemon": "1.9.2", | ||
42 | "postcss-assets": "^4.0.1", | 47 | "postcss-assets": "^4.0.1", |
43 | "postcss-cachebuster": "^0.1.2", | 48 | "postcss-cachebuster": "^0.1.2", |
44 | "postcss-calc": "^5.2.1", | 49 | "postcss-calc": "^5.2.1", |
@@ -51,11 +56,12 @@ | @@ -51,11 +56,12 @@ | ||
51 | "postcss-sprites": "^3.1.2", | 56 | "postcss-sprites": "^3.1.2", |
52 | "postcss-use": "^2.0.2", | 57 | "postcss-use": "^2.0.2", |
53 | "precss": "^1.4.0", | 58 | "precss": "^1.4.0", |
54 | - "stylelint": "^6.2.2", | ||
55 | - "stylelint-config-yoho": "^1.2.0", | 59 | + "rewire": "^2.5.1", |
60 | + "shelljs": "^0.7.0", | ||
61 | + "stylelint": "^6.3.3", | ||
62 | + "stylelint-config-yoho": "^1.2.2", | ||
56 | "webpack": "^1.13.0", | 63 | "webpack": "^1.13.0", |
57 | "webpack-dev-server": "^1.14.1", | 64 | "webpack-dev-server": "^1.14.1", |
58 | - "webpack-stream": "^3.1.0", | ||
59 | - "shelljs": "^0.7.0" | 65 | + "webpack-stream": "^3.1.0" |
60 | } | 66 | } |
61 | } | 67 | } |
test/library/timer.test.js
0 → 100644
1 | +let expect = require('expect.js'); | ||
2 | +let Timer = require('../../library/timer'); | ||
3 | + | ||
4 | + | ||
5 | +describe('/library/timer', function() { | ||
6 | + it('延迟100ms,期望大于或等于100ms', function(done) { | ||
7 | + let t = new Timer(); | ||
8 | + t.put('aa'); | ||
9 | + setTimeout(function() { | ||
10 | + let time = t.put('aa'); | ||
11 | + expect(Math.round(time) >= 100).to.be.ok(); | ||
12 | + done(); | ||
13 | + }, 100); | ||
14 | + }); | ||
15 | +}); |
test/run.js
0 → 100644
1 | +require('./library/timer.test'); |
-
Please register or login to post a comment