chanjs 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD ADDED
@@ -0,0 +1,52 @@
1
+ # <center>Chan.js mvc框架</center>
2
+
3
+ Chan.js 基于express 纯js研发的轻量级mvc框架。基于函数式编程思想,性能优越,代码清晰,流程易读,可持续维护高。
4
+
5
+ ## 特性
6
+
7
+ - 基于express
8
+ - 支持es6语法
9
+ - 模块化
10
+ - 支持多模块路由
11
+ - 支持多模块视图
12
+ - 支持多模块控制器
13
+ - 支持多模块服务
14
+ - 插件化
15
+ - 轻量级(核心代码300行内)
16
+ - 长期维护
17
+
18
+ ## 规范 遵循约定优于配置
19
+
20
+ ```code
21
+ |- app
22
+ |- config 配置
23
+ |- module 模块1
24
+ |- module1 模块1
25
+ |- controller 控制器
26
+ |- service 服务模型
27
+ |- view 视图模板
28
+ |- router.js 路由
29
+ |- module2 模块2
30
+ |- controller 控制器
31
+ |- service 服务模型
32
+ |- view 视图模板
33
+ |- router.js路由
34
+ |- extend 扩展
35
+ |- middleware 中间件
36
+ |- plugin 插件
37
+ |- public 静态文件
38
+ |- index.js
39
+ ```
40
+
41
+ ### 初始化流程
42
+
43
+ - 初始化
44
+ - 加载配置
45
+ - 加载模块
46
+ - 加载service
47
+ - 加载controller
48
+ - 加载router
49
+ - 加载extend
50
+ - 加载plugin
51
+ - beforeStart() 挂在从数据库获取的配置合并到配置文件中
52
+ - run() 启动服务
package/chan.js ADDED
@@ -0,0 +1,162 @@
1
+ const express = require("express");
2
+ const config = require("./lib/config/config.js");
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+
6
+ /**
7
+ * @description chanjs
8
+ */
9
+ class Chan {
10
+ constructor(options={}) {
11
+
12
+ //加载全局对象
13
+ this.config = Object.assign(config, options);
14
+ //配置
15
+ Chan.config = this.config;
16
+ //模块
17
+ Chan.modules = this.modules = {};
18
+ //帮助文档
19
+ Chan.helper = this.helper = {};
20
+
21
+ this.app = express();
22
+ this.router = express.Router();
23
+
24
+ this.loadConfig();
25
+ this.beforeStart();
26
+ this.init();
27
+ }
28
+
29
+ // 加载配置
30
+ loadConfig() {
31
+ const configPath = path.join(config.APP_PATH, "config/index.js");
32
+ if (fs.existsSync(configPath)) {
33
+ const config = require(configPath);
34
+ Object.assign(this.config, config);
35
+ }
36
+
37
+ console.log("config——>配置文件加载完成");
38
+ }
39
+
40
+ //启动加载
41
+ beforeStart(cb) {
42
+ // 初始化一些配置
43
+ console.log("beforeStart--->初始化一些配置");
44
+ cb && cb();
45
+ }
46
+
47
+ init() {
48
+ this.loadModules();
49
+ this.loadExtends();
50
+ this.loadPlusins();
51
+
52
+ }
53
+
54
+ loadModules() {
55
+ const configPath = path.join(config.APP_PATH, "module");
56
+ if (fs.existsSync(configPath)) {
57
+ const dirs = fs
58
+ .readdirSync(configPath, { withFileTypes: true })
59
+ .filter((dirent) => dirent.isDirectory())
60
+ .map((dirent) => dirent.name)
61
+ .forEach((item, index) => {
62
+ this.modules[item] = {
63
+ controller: {},
64
+ service: {},
65
+ };
66
+ this.loadModule(item);
67
+ });
68
+ //执行路由
69
+ this.app.use(this.router);
70
+ }
71
+ }
72
+
73
+ // 加载插件
74
+ loadPlugins() {
75
+ const configPath = path.join(config.APP_PATH, "plugin");
76
+ if (fs.existsSync(configPath)) {
77
+ const dirs = fs
78
+ .readdirSync(configPath, { withFileTypes: true })
79
+ .filter((dirent) => dirent.isDirectory())
80
+ .map((dirent) => dirent.name);
81
+ this.plugins = dirs;
82
+ } else {
83
+ this.plugins = [];
84
+ }
85
+ }
86
+
87
+ loadModule(moduleName) {
88
+ const moduleDir = path.join(config.APP_PATH, "module", moduleName);
89
+ this.loadServices(moduleDir,moduleName);
90
+ this.loadControllers(moduleDir,moduleName);
91
+ this.loadRoutes(moduleDir,moduleName);
92
+ }
93
+
94
+ // 加载服务
95
+ loadServices(moduleDir,moduleName) {
96
+ const servicesDir = path.join(moduleDir, "service");
97
+ if (fs.existsSync(servicesDir)) {
98
+ let services = fs
99
+ .readdirSync(servicesDir)
100
+ .filter((file) => file.endsWith(".js"));
101
+ for (let i = 0, file = services[i]; i < services.length; i++) {
102
+ const Service = require(path.join(servicesDir, file));
103
+ const serviceName = file.replace(".js", "");
104
+ this.modules[moduleName].service[serviceName] = {};
105
+ this.modules[moduleName].service[serviceName] = Service;
106
+ }
107
+ }
108
+ }
109
+
110
+ // 加载控制器
111
+ loadControllers(moduleDir,moduleName) {
112
+ const controllersDir = path.join(moduleDir, "controller");
113
+ if (fs.existsSync(controllersDir)) {
114
+ let controllers = fs
115
+ .readdirSync(controllersDir)
116
+ .filter((file) => file.endsWith(".js"));
117
+ for (let i = 0, file = controllers[i]; i < controllers.length; i++) {
118
+ const controller = require(path.join(controllersDir, file));
119
+ const controllerName = file.replace(".js", "");
120
+ this.modules[moduleName].controller[controllerName] = {};
121
+ this.modules[moduleName].controller[controllerName] = controller;
122
+ }
123
+ }
124
+ }
125
+
126
+ // 加载路由
127
+ loadRoutes(moduleDir,moduleName) {
128
+ const routersDir = path.join(moduleDir, "router.js");
129
+ if (fs.existsSync(routersDir)) {
130
+ const routes = require(routersDir);
131
+ routes({router:this.router,controller:this.modules[moduleName].controller});
132
+ }
133
+ }
134
+
135
+ // 加载扩展
136
+ loadExtends() {
137
+ const extendPath = path.join(config.APP_PATH, "extend");
138
+ if (fs.existsSync(extendPath)) {
139
+ let controllers = fs
140
+ .readdirSync(extendPath)
141
+ .filter((file) => file.endsWith(".js"));
142
+ for (let i = 0, file = controllers[i]; i < controllers.length; i++) {
143
+ const helper = require(path.join(extendPath, file));
144
+ const fileName = file.replace(".js", "");
145
+ this.helper[fileName] = helper;
146
+ }
147
+ }
148
+ }
149
+
150
+ loadPlusins() {
151
+ // 加载插件
152
+ }
153
+
154
+ run(port) {
155
+ this.app.listen(port, () => {
156
+ console.log(`Server is running on port ${port}`);
157
+ });
158
+ }
159
+ }
160
+
161
+
162
+ module.exports = Chan;
package/lib/base.js ADDED
@@ -0,0 +1,8 @@
1
+ class Base{
2
+ constructor(config){
3
+ this.config = config;
4
+ }
5
+ log(...args){
6
+ console.log(...args);
7
+ }
8
+ }
@@ -0,0 +1,18 @@
1
+ const path = require('path');
2
+
3
+ /**
4
+ * @description 根目录
5
+ */
6
+ const ROOT_PATH = process.cwd();
7
+
8
+ /**
9
+ * @description 程序目录
10
+ */
11
+ const APP_PATH = path.join(ROOT_PATH, 'app');
12
+
13
+ module.exports = {
14
+ ROOT_PATH,
15
+ APP_PATH,
16
+ }
17
+
18
+
@@ -0,0 +1,9 @@
1
+ class Base{
2
+ constructor(config){
3
+ this.config = config;
4
+ }
5
+
6
+ log(...args){
7
+ console.log(...args);
8
+ }
9
+ }
@@ -0,0 +1,217 @@
1
+
2
+ /**
3
+ * extend controller
4
+ */
5
+ module.exports = {
6
+ /**
7
+ * body getter
8
+ */
9
+ get body() {
10
+
11
+ },
12
+ /**
13
+ * body setter
14
+ */
15
+ set body(value) {
16
+
17
+ },
18
+ /**
19
+ * get client ip
20
+ */
21
+ get ip() {
22
+
23
+ },
24
+ /**
25
+ * get client ips
26
+ */
27
+ get ips() {
28
+
29
+ },
30
+ /**
31
+ * get status code
32
+ */
33
+ get status() {
34
+
35
+ },
36
+ /**
37
+ * set status code
38
+ */
39
+ set status(status) {
40
+
41
+ },
42
+ /**
43
+ * get content type
44
+ */
45
+ get type() {
46
+
47
+ },
48
+ /**
49
+ * set content type
50
+ */
51
+ set type(contentType) {
52
+
53
+ },
54
+ /**
55
+ * get userAgent header
56
+ */
57
+ get userAgent() {
58
+
59
+ },
60
+ /**
61
+ * get request method
62
+ */
63
+ get method() {
64
+
65
+ },
66
+ /**
67
+ * is get method
68
+ */
69
+ get isGet() {
70
+
71
+ },
72
+ /**
73
+ * is post method
74
+ */
75
+ get isPost() {
76
+
77
+ },
78
+ /**
79
+ * is command line invoke
80
+ */
81
+ get isCli() {
82
+
83
+ },
84
+ /**
85
+ * get or set config
86
+ * @param {String} name
87
+ * @param {Mix} value
88
+ * @param {String} m
89
+ */
90
+ config(name, value, m ) {
91
+
92
+ },
93
+ /**
94
+ * is method
95
+ * @param {String} method
96
+ */
97
+ isMethod(method) {
98
+
99
+ },
100
+ /**
101
+ * check if is ajax request
102
+ * @param {String} method
103
+ */
104
+ isAjax(method) {
105
+
106
+ },
107
+ /**
108
+ * is jsonp request
109
+ * @param {String} callback
110
+ */
111
+ isJsonp(callbackField) {
112
+
113
+ },
114
+ /**
115
+ * send jsonp data
116
+ */
117
+ jsonp(data, callbackField) {
118
+
119
+ },
120
+ /**
121
+ * send json data
122
+ */
123
+ json(data) {
124
+
125
+ },
126
+ /**
127
+ * send success data
128
+ */
129
+ success(data, message) {
130
+
131
+ },
132
+ /**
133
+ * send fail data
134
+ */
135
+ fail(errno, errmsg, data) {
136
+
137
+ },
138
+ /**
139
+ * set expires header
140
+ * @param {Number} time
141
+ */
142
+ expires(time) {
143
+
144
+ },
145
+ /**
146
+ * get query data
147
+ * @param {String} name
148
+ * @param {Mixed} value
149
+ */
150
+ get(name, value) {
151
+
152
+ },
153
+ /**
154
+ * get query data
155
+ * @param {String} name
156
+ * @param {Mixed} value
157
+ */
158
+ query(name, value) {
159
+
160
+ },
161
+ /**
162
+ * get or set post data
163
+ * @param {String} name
164
+ * @param {Mixed} value
165
+ */
166
+ post(name, value) {
167
+
168
+ },
169
+ /**
170
+ * get or set file data
171
+ * @param {String} name
172
+ * @param {Mixed} value
173
+ */
174
+ file(name, value) {
175
+
176
+ },
177
+ /**
178
+ * get or set cookies
179
+ * @param {String} name
180
+ * @param {String} value
181
+ * @param {Object} options
182
+ */
183
+ cookie(name, value, options) {
184
+
185
+ },
186
+
187
+ /**
188
+ * get referer header
189
+ */
190
+ referrer(onlyHost) {
191
+
192
+ },
193
+ /**
194
+ * get referer header
195
+ */
196
+ referer(onlyHost) {
197
+
198
+ },
199
+ /**
200
+ * Perform a 302 redirect to `url`.
201
+ * @param {String} url
202
+ * @param {String} alt
203
+ */
204
+ redirect(url, alt) {
205
+
206
+ },
207
+
208
+
209
+ /**
210
+ * download
211
+ * @param {String} filepath
212
+ * @param {String} filename
213
+ */
214
+ download(filepath, filename) {
215
+
216
+ }
217
+ };
@@ -0,0 +1,135 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ /**
5
+ * @description 是否存在
6
+ * @param {*} dir 目录
7
+ * @returns {Boolean} 返回true false
8
+ */
9
+ function isExist(dir) {
10
+ let formatDir = path.normalize(dir);
11
+ try {
12
+ fs.accessSync(formatDir, fs.R_OK);
13
+ return true;
14
+ } catch (e) {
15
+ return false;
16
+ }
17
+ }
18
+
19
+ exports.isExist = isExist;
20
+
21
+ /**
22
+ * @description 是否是文件
23
+ * @param {*} filePath
24
+ * @returns {Boolean} true 是文件 false 不是文件
25
+ */
26
+ function isFile(filePath) {
27
+ if (!isExist(filePath)) return false;
28
+ try {
29
+ const stat = fs.statSync(filePath);
30
+ return stat.isFile();
31
+ } catch (e) {
32
+ return false;
33
+ }
34
+ }
35
+ exports.isFile = isFile;
36
+
37
+ /**
38
+ * @description 是否是目录
39
+ * @param {*} filePath
40
+ * @returns {Boolean} 返回true false
41
+ */
42
+ function isDirectory(filePath) {
43
+ if (!isExist(filePath)) return false;
44
+ try {
45
+ const stat = fs.statSync(filePath);
46
+ return stat.isDirectory();
47
+ } catch (e) {
48
+ return false;
49
+ }
50
+ }
51
+ exports.isDirectory = isDirectory;
52
+
53
+ /**
54
+ * @description 修改指定路径 `p` 的权限模式为给定的 `mode`。这是一个同步版本的文件权限更改方法
55
+ * 如果成功修改权限,则返回 `true`,否则在发生错误时捕获异常并返回 `false`。
56
+ * @param {String} p - 要更改权限的文件或目录的绝对路径。
57
+ * @param {String|Number} mode - 指定的新权限模式,可以是八进制数字表示(如0o755)或字符串形式(如"755")
58
+ * @return {Boolean} - 根据操作是否成功,返回 `true` 表示成功,`false` 表示失败。
59
+ */
60
+ function chmod(p, mode) {
61
+ try {
62
+ fs.chmodSync(p, mode);
63
+ return true;
64
+ } catch (e) {
65
+ return false;
66
+ }
67
+ }
68
+ exports.chmod = chmod;
69
+
70
+ /**
71
+ * @function mkdir
72
+ * @description 递归创建目录
73
+ * @param {string} dir - 要创建的目录路径。
74
+ * @param {string|number} - 默认为 0o777。可以是八进制数字表示或字符串形式。
75
+ * @returns {boolean} - 返回 `true` 表示成功,`false` 表示失败。
76
+ */
77
+ function mkdir(dir, mode) {
78
+ if (isExist(dir)) {
79
+ if (mode) return chmod(dir, mode);
80
+ return true;
81
+ }
82
+ const pp = path.dirname(dir);
83
+ if (isExist(pp)) {
84
+ try {
85
+ fs.mkdirSync(dir, mode);
86
+ return true;
87
+ } catch (e) {
88
+ return false;
89
+ }
90
+ }
91
+ if (mkdir(pp, mode)) return mkdir(dir, mode);
92
+ return false;
93
+ }
94
+ exports.mkdir = mkdir;
95
+
96
+ function getdirFiles(dir, prefix = "") {
97
+ dir = path.normalize(dir);
98
+ if (!fs.existsSync(dir)) return [];
99
+ const files = fs.readdirSync(dir);
100
+ let result = [];
101
+ files.forEach((item) => {
102
+ const currentDir = path.join(dir, item);
103
+ const stat = fs.statSync(currentDir);
104
+ if (stat.isFile()) {
105
+ result.push(path.join(prefix, item));
106
+ } else if (stat.isDirectory()) {
107
+ const cFiles = getdirFiles(currentDir, path.join(prefix, item));
108
+ result = result.concat(cFiles);
109
+ }
110
+ });
111
+ return result;
112
+ }
113
+
114
+ exports.getdirFiles = getdirFiles;
115
+
116
+ /**
117
+ * remove dir aync
118
+ * @param {String} p [path]
119
+ * @param {Boolean} reserve []
120
+ * @return {Promise} []
121
+ */
122
+ function rmdir(p, reserve) {
123
+ if (!isDirectory(p)) return Promise.resolve();
124
+ return fsReaddir(p).then((files) => {
125
+ const promises = files.map((item) => {
126
+ const filepath = path.join(p, item);
127
+ if (isDirectory(filepath)) return rmdir(filepath, false);
128
+ return fsUnlink(filepath);
129
+ });
130
+ return Promise.all(promises).then(() => {
131
+ if (!reserve) return fsRmdir(p);
132
+ });
133
+ });
134
+ }
135
+ exports.rmdir = rmdir;
@@ -0,0 +1,17 @@
1
+
2
+
3
+ module.exports = {
4
+ /**
5
+ * @description 给路由加前缀
6
+ * @returns viod 0
7
+ */
8
+ addRoutePrefix:()=>{
9
+ return function (req, res, next) {
10
+ req.baseUrl = `${prefix}${req.baseUrl || ''}`;
11
+ // 如果有 query 参数,则保留原有参数
12
+ req.url = `${req.baseUrl}${req.url.includes('?') ? req.url.split('?')[1] : ''}`;
13
+ next();
14
+ };
15
+ }
16
+ }
17
+
package/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "chanjs",
3
+ "version": "0.0.1",
4
+ "description": "Chan.js 基于express 纯js研发的轻量级mvc框架。基于函数式编程思想,性能优越,代码清晰,流程易读,可持续维护高。",
5
+ "main": "chan.js",
6
+ "directories": {
7
+ "lib": "lib"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "author": "明空",
13
+ "license": "ISC"
14
+ }