Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9804cfb

Browse files
committedAug 4, 2016
doc: update README
and fix review
1 parent 52c9c70 commit 9804cfb

File tree

13 files changed

+259
-61
lines changed

13 files changed

+259
-61
lines changed
 

‎README.md

+191-36
Original file line numberDiff line numberDiff line change
@@ -20,53 +20,208 @@
2020
[download-image]: https://img.shields.io/npm/dm/egg-loader.svg?style=flat-square
2121
[download-url]: https://npmjs.org/package/egg-loader
2222

23-
egg 文件加载器
23+
A core Plugable framework based on koa
2424

25-
## 使用说明
25+
**Don't use it directly, see [egg]**
26+
27+
## Usage
28+
29+
Directory structure
30+
31+
```
32+
├── package.json
33+
├── app.js (optional)
34+
├── agent.js (optional)
35+
├── app
36+
| ├── router.js
37+
│ ├── controller
38+
│ │ └── home.js
39+
| ├── extend (optional)
40+
│ | ├── helper.js (optional)
41+
│ | ├── filter.js (optional)
42+
│ | ├── request.js (optional)
43+
│ | ├── response.js (optional)
44+
│ | ├── context.js (optional)
45+
│ | ├── application.js (optional)
46+
│ | └── agent.js (optional)
47+
│ ├── service (optional)
48+
│ ├── middleware (optional)
49+
│ │ └── response_time.js
50+
│ └── view (optional)
51+
| ├── layout.html
52+
│ └── home.html
53+
├── config
54+
| ├── config.default.js
55+
│ ├── config.prod.js
56+
| ├── config.test.js (optional)
57+
| ├── config.local.js (optional)
58+
| ├── config.unittest.js (optional)
59+
│ └── plugin.js
60+
```
61+
62+
Than you can start with code below
2663

2764
```js
28-
const app = koa();
29-
const Loader = require('egg-loader');
30-
const loader = new Loader({
31-
baseDir: '/path/to/app',
32-
eggPath: '/path/to/framework',
33-
app: app,
65+
const Application = require('egg-core').Application;
66+
const app = new Application({
67+
baseDir: '/path/to/app'
3468
});
35-
loader.loadPlugin();
36-
loader.loadConfig();
69+
app.ready(() => {
70+
app.listen(3000);
71+
});
72+
```
73+
74+
## EggLoader
75+
76+
EggLoader will load file or directory easily, you can also custom your loader with low level API.
77+
78+
### constructor
79+
80+
- {String} baseDir - current directory of application
81+
- {Object} app - instance of egg application
82+
- {Object} plugins - merge plugins for test
83+
- {Logger} logger - logger instance,default is console
84+
85+
### High Level API
86+
87+
#### loadPlugin
88+
89+
Load config/plugin.js
90+
91+
#### loadConfig
92+
93+
Load config/config.js and config/{serverEnv}.js
94+
95+
#### loadController
96+
97+
Load app/controller
98+
99+
#### loadMiddleware
100+
101+
Load app/middleware
102+
103+
#### loadApplicationExtend
104+
105+
Load app/extend/application.js
106+
107+
#### loadContextExtend
108+
109+
Load app/extend/context.js
110+
111+
#### loadRequestExtend
112+
113+
Load app/extend/request.js
114+
115+
#### loadResponseExtend
116+
117+
Load app/extend/response.js
118+
119+
#### loadHelperExtend
120+
121+
Load app/extend/helper.js
122+
123+
#### loadCustomApp
124+
125+
Load app.js
126+
127+
#### loadCustomAgent
128+
129+
Load agent.js
130+
131+
#### loadService
132+
133+
Load app/service
134+
135+
### Low Level API
136+
137+
#### getServerEnv()
138+
139+
Get serverEnv for application, available serverEnv
140+
141+
serverEnv | description
142+
--- | ---
143+
default | default environment
144+
test | system integration testing environment
145+
prod | production environment
146+
local | local environment on your own computer
147+
unittest | unit test environment
148+
149+
You can use this.serverEnv directly after instantiation.
150+
151+
#### getEggPaths()
152+
153+
Get the directory of the frameworks, a new framework born by extending egg, then you can use this function to get all frameworks.
154+
155+
#### getLoadUnits()
156+
157+
A loadUnit is a directory that can be loaded by EggLoader, it has the same structure.
158+
159+
This function will get add loadUnits follow the order:
160+
161+
1. plugin
162+
2. framework
163+
3. app
164+
165+
loadUnit has a path and a type(app, framework, plugin).
166+
167+
```js
168+
{
169+
path: 'path/to/application',
170+
type: 'app',
171+
}
37172
```
38173

39-
## API
174+
#### getAppname()
175+
176+
Get appname from package.json
177+
178+
#### loadFile(filepath)
179+
180+
Load single file, will invork when export is function.
181+
182+
#### loadToApp(directory, property, LoaderOptions)
183+
184+
Load the files in directory to app.
40185

41-
### options
186+
Invoke `this.loadToApp('$baseDir/app/controller', 'controller')`, then you can use it by `app.controller`.
42187

43-
- baseDir: 应用根目录
44-
- eggPath: egg 本身的路径
45-
- plugins: 自定义插件配置
46-
- app: 任何基于 koa 实例化
188+
#### loadToContext(directory, property, LoaderOptions)
47189

48-
### methods
190+
Load the files in directory to context, it will bind the context.
49191

50-
基础方式
192+
```
193+
// define service in app/service/query.js
194+
module.exports = class Query {
195+
constructor(ctx) {
196+
// get the ctx
197+
}
198+
199+
get() {}
200+
};
201+
202+
// use the service in app/controller/home.js
203+
module.exports = function*() {
204+
this.body = this.service.query.get();
205+
};
206+
```
51207

52-
- loadFile: 加载单文件,
53-
- loadDirs: 获取需要加载的所有目录,按照 egg > 插件 > 框架 > 应用的顺序加载。
208+
#### loadExtend(name, target)
209+
210+
Loader app/extend/xx.js to target, example
211+
212+
```js
213+
this.loadExtend('application', app);
214+
```
54215

55-
业务方法
216+
### LoaderOptions
56217

57-
- getAppname: 获取应用名
58-
- loadServerEnv: 加载环境变量
59-
- loadConfig: 加载: config
60-
- loadPlugin: 加载插件
61-
- loadApplication: 加载 extend/application.js 到 app
62-
- loadRequest: 加载 extend/request.js 到 app.request
63-
- loadResponse: 加载 extend/response.js 到 app.response
64-
- loadContext: 加载 extend/context.js 到 app.context
65-
- loadHelper: 加载 extend/helper.js,到 app.Helper.prototype,需要定义 app.Helper 才会加载
66-
- loadService: 加载 app/service 到 app.service
67-
- loadProxy: 加载 app/proxy 到 app.proxy
68-
- loadMiddleware: 加载中间件
69-
- loadController: 加载 app/controller 到 app.controller
70-
- loadAgent: 加载 agent.js 进行自定义
71-
- loadApp: 加载 app.js 进行自定义
218+
- {String|Array} directory - directories to load
219+
- {Object} target: attach object from loaded files,
220+
- {String} ignore - ignore the files when load
221+
- {Function} initializer - custom file exports
222+
- {Boolean} lowercaseFirst - determine whether the fist letter is lowercase
223+
- {Boolean} override: determine whether override the property when get the same name
224+
- {Boolean} call - determine whether invoke when exports is function
225+
- {Object} inject - an object that be the argument when invoke the function
72226

227+
[egg]: https://github.com/eggjs/egg

‎lib/egg_loader.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class EggLoader {
118118
/**
119119
* Get all framework directories.
120120
*
121-
* You can extend Application of egg, the extrypoint is options.app,
121+
* You can extend Application of egg, the entrypoint is options.app,
122122
*
123123
* loader will find all directories from the prototype of Application,
124124
* you should define `Symbol.for('egg#eggPath')` property.

‎lib/mixin/config.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const debug = require('debug')('egg-loader:config');
44
const fs = require('fs');
55
const path = require('path');
66
const extend = require('extend');
7+
const assert = require('assert');
8+
79

810
module.exports = {
911

@@ -33,7 +35,7 @@ module.exports = {
3335
// framework config.{env}
3436
for (const filename of names) {
3537
for (const unit of this.getLoadUnits()) {
36-
const config = this._loadConfig(unit.path, filename, appConfig);
38+
const config = this._loadConfig(unit.path, filename, appConfig, unit.type);
3739

3840
if (!config) {
3941
continue;
@@ -58,16 +60,15 @@ module.exports = {
5860
];
5961
const target = {};
6062
for (const filename of names) {
61-
const config = this._loadConfig(this.options.baseDir, filename);
63+
const config = this._loadConfig(this.options.baseDir, filename, undefined, 'app');
6264
extend(true, target, config);
6365
}
6466
return target;
6567
},
6668

67-
_loadConfig(dirpath, filename, extraInject) {
68-
const pluginPaths = this.orderPlugins ? this.orderPlugins.map(plugin => plugin.path) : [];
69-
const isPlugin = pluginPaths.indexOf(dirpath) > -1;
70-
const isApp = dirpath === this.options.baseDir;
69+
_loadConfig(dirpath, filename, extraInject, type) {
70+
const isPlugin = type === 'plugin';
71+
const isApp = type === 'app';
7172

7273
let filepath = path.join(dirpath, 'config', filename);
7374
// let config.js compatible
@@ -80,14 +81,12 @@ module.exports = {
8081
return null;
8182
}
8283

83-
// delete coreMiddleware when app and plugin
8484
if (isPlugin || isApp) {
85-
delete config.coreMiddleware;
85+
assert(!config.coreMiddleware, 'Can not define coreMiddleware in app or plugin');
8686
}
87-
// delete middleware and proxy when it's not app
8887
if (!isApp) {
89-
delete config.middleware;
90-
delete config.proxy;
88+
assert(!config.middleware, 'Can not define middleware in framework or plugin');
89+
assert(!config.proxy, 'Can not define proxy in framework or plugin');
9190
}
9291

9392
return config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports.coreMiddleware = [];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "coreMiddleware"
3+
}

‎test/fixtures/plugin/node_modules/d/config/config.js

-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports.middleware = [];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"eggPlugin": {
3+
"name": "middleware"
4+
}
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports.proxy = {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"eggPlugin": {
3+
"name": "proxy"
4+
}
5+
}

‎test/load_config.test.js

+34-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const should = require('should');
4+
const utils = require('./utils');
45
const Loader = require('./utils').Loader;
56

67
describe('test/load_config.test.js', function() {
@@ -48,12 +49,39 @@ describe('test/load_config.test.js', function() {
4849
should.not.exists(loader.config.pluginA);
4950
});
5051

51-
it('should delete config.middleware and config.proxy', function() {
52-
const loader = new Loader('plugin');
53-
loader.loadConfig();
54-
should.not.exists(loader.config.proxy);
55-
loader.config.coreMiddleware.should.not.containEql('d');
56-
loader.config.appMiddleware.should.not.containEql('d');
52+
it('should throw when plugin define middleware', function() {
53+
const loader = new Loader('plugin', {
54+
plugins: {
55+
middleware: {
56+
enable: true,
57+
path: utils.getFilepath('plugin/plugin-middleware'),
58+
},
59+
},
60+
});
61+
(function() {
62+
loader.loadConfig();
63+
}).should.throw('Can not define middleware in framework or plugin');
64+
});
65+
66+
it('should throw when plugin define proxy', function() {
67+
const loader = new Loader('plugin', {
68+
plugins: {
69+
proxy: {
70+
enable: true,
71+
path: utils.getFilepath('plugin/plugin-proxy'),
72+
},
73+
},
74+
});
75+
(function() {
76+
loader.loadConfig();
77+
}).should.throw('Can not define proxy in framework or plugin');
78+
});
79+
80+
it('should throw when app define coreMiddleware', function() {
81+
const loader = new Loader('app-core-middleware');
82+
(function() {
83+
loader.loadConfig();
84+
}).should.throw('Can not define coreMiddleware in app or plugin');
5785
});
5886

5987
it('should read appinfo from the function of config', function() {

‎test/load_extend.test.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ describe('test/load_extend.test.js', function() {
8282
});
8383

8484
it('should throw when syntax error', function() {
85+
const file = utils.getFilepath('load_context_syntax_error/app/extend/context.js');
86+
const reg = new RegExp(`${file} error: Unexpected token`);
8587
(function() {
8688
const app = koa();
8789
app.coreLogger = console;
@@ -90,7 +92,7 @@ describe('test/load_extend.test.js', function() {
9092
});
9193
loader.loadConfig();
9294
loader.load();
93-
}).should.throw(/load_context_syntax_error\/app\/extend\/context\.js error: Unexpected token \)/);
95+
}).should.throw(reg);
9496
});
9597

9698
it('should extend symbol', function() {

‎test/loader.test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const should = require('should');
88
const pedding = require('pedding');
99
const path = require('path');
1010
const Loader = require('../lib/loader');
11+
const utils = require('./utils');
1112
const dirBase = path.join(__dirname, 'fixtures/load_dirs');
1213

1314
describe('test/loader.test.js', () => {
@@ -179,12 +180,14 @@ describe('test/loader.test.js', () => {
179180

180181
it('should contain syntax error filepath', () => {
181182
const app = { model: {} };
183+
const file = utils.getFilepath('load_dirs/syntax_error/error.js');
184+
const reg = new RegExp(`load file: ${file}, error:`);
182185
(function() {
183186
new Loader({
184187
directory: path.join(dirBase, 'syntax_error'),
185188
target: app.model,
186189
}).load();
187-
}).should.throw(/load file: .*?test\/fixtures\/load_dirs\/syntax_error\/error\.js, error:/);
190+
}).should.throw(reg);
188191
});
189192

190193
it('should throw when directory contains dot', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.