diff --git a/lib/egg.js b/lib/egg.js index 373c0822..beaba50b 100644 --- a/lib/egg.js +++ b/lib/egg.js @@ -11,17 +11,17 @@ class EggCore extends KoaApplication { /** * @constructor - * @param {Object} options - 创建应用配置 - * - {String} [process.cwd()] baseDir - app root dir, default is `process.cwd()` - * - {String} [application|agent] type - * - {Object} plugins - 自定义插件配置,一般只用于单元测试 + * @param {Object} options - options + * @param {String} [options.baseDir=process.cwd()] - the directory of application + * @param {String} [options.type=application|agent] - wheter it's running in app worker or agent worker + * @param {Object} [options.plugins] - custom plugins + * @since 1.0.0 */ constructor(options) { options = options || {}; options.baseDir = options.baseDir || process.cwd(); options.type = options.type || 'application'; - // 确保 baseDir 存在,是字符串,并且所在目录存在 assert(typeof options.baseDir === 'string', 'options.baseDir required, and must be a string'); assert(fs.existsSync(options.baseDir), `Directory ${options.baseDir} not exists`); assert(fs.statSync(options.baseDir).isDirectory(), `Directory ${options.baseDir} is not a directory`); @@ -30,20 +30,21 @@ class EggCore extends KoaApplication { super(); /** - * {@link EggCore} 初始化传入的参数 * @member {Object} EggCore#options + * @since 1.0.0 */ this._options = options; /** - * console 的替代品,但可由 egg 进行控制 + * logging for EggCore, avoid using console directly * @member {Logger} EggCore#console + * @since 1.0.0 */ this.console = new EggConsoleLogger(); /** - * 获取 app 的 Loader - * @member {AppWorkerLoader} EggCore#loader + * @member {EggLoader} EggCore#loader + * @since 1.0.0 */ const Loader = this[Symbol.for('egg#loader')]; assert(Loader, 'Symbol.for(\'egg#loader\') is required'); @@ -57,12 +58,17 @@ class EggCore extends KoaApplication { this._initReady(); } + /** + * alias to options.type + * @member {String} + * @since 1.0.0 + */ get type() { return this._options.type; } /** - * 应用所在的代码根目录 + * alias to options.baseDir * @member {String} * @since 1.0.0 */ @@ -71,21 +77,20 @@ class EggCore extends KoaApplication { } /** - * 统一的 depd API * @member {Function} * @see https://npmjs.com/package/depd * @since 1.0.0 */ get deprecate() { if (!this[DEPRECATE]) { - // 延迟加载,这样允许单元测试通过 process.env.NO_DEPRECATION = '*' 设置不输出 + // require depd when get, `process.env.NO_DEPRECATION = '*'` should be use when run test everytime this[DEPRECATE] = require('depd')('egg'); } return this[DEPRECATE]; } /** - * 当前应用名, 读取自 `package.json` 的 name 字段。 + * name in package.json * @member {String} * @since 1.0.0 */ @@ -94,7 +99,7 @@ class EggCore extends KoaApplication { } /** - * 获取配置,从 `config/config.${env}.js` 读取 + * alias to {EggCore#loader} * @member {Object} * @since 1.0.0 */ @@ -103,7 +108,7 @@ class EggCore extends KoaApplication { } /** - * 获取配置,从 `config/config.${env}.js` 读取 + * alias to {EggCore#loader} * @member {Config} * @since 1.0.0 */ @@ -113,6 +118,8 @@ class EggCore extends KoaApplication { /** * close all listeners + * @member {Function} + * @since 1.0.0 */ close() { this.emit('close'); @@ -120,29 +127,29 @@ class EggCore extends KoaApplication { } /** - * 初始化 ready + * @member {Function} * @private */ _initReady() { /** - * 注册 ready 方法,当启动完成后触发此方法 + * register an callback function that will be invoked when application is ready. * @member {Function} EggCore#ready * @since 1.0.0 */ /** - * 异步启动接口,查看 https://github.com/koajs/koa-ready - * 当所有注册的任务完成后才会触发 app.ready,启动才正式完成 + * If a client starts asynchronously, you can register `readyCallback`, + * then the application will wait for the callback to ready * + * It will log when the callback is not invoked after 10s * @member {Function} EggCore#readyCallback * @since 1.0.0 * @example * ```js - * const done = app.readyCallback('configclient'); - * configclient.ready(done); + * const done = app.readyCallback('mysql'); + * mysql.ready(done); * ``` */ - // 默认 10s 没有 ready 就输出日志提示 require('ready-callback')({ timeout: 10000 }).mixin(this); this.on('ready_stat', data => { diff --git a/lib/loader/egg_loader.js b/lib/loader/egg_loader.js index bcc3bb80..9fda0b71 100644 --- a/lib/loader/egg_loader.js +++ b/lib/loader/egg_loader.js @@ -15,11 +15,12 @@ class EggLoader { /** * @constructor - * @param {Object} options - * - {String} baseDir - 应用根目录 - * - {Object} app - app 实例,如果是 Agent Worker 则传入 agent 实例,可为空 - * - {Logger} logger - logger 实例,默认是 console - * - {Object} plugins - 自定义插件配置,测试用 + * @param {Object} options - options + * @param {String} options.baseDir - the directory of application + * @param {Object} options.app - Application instance + * @param {Logger} options.logger - logger + * @param {Object} [options.plugins] - custom plugins + * @since 1.0.0 */ constructor(options) { this.options = options; @@ -30,13 +31,14 @@ class EggLoader { this.app = this.options.app; /** - * 读取 package.json * @member {Object} EggLoader#pkg + * @since 1.0.0 */ this.pkg = require(path.join(this.options.baseDir, 'package.json')); /** * @member {Array} EggLoader#eggPaths + * @since 1.0.0 * @see EggLoader#getEggPaths */ this.eggPaths = this.getEggPaths(); @@ -44,6 +46,7 @@ class EggLoader { /** * @member {String} EggLoader#serverEnv + * @since 1.0.0 * @see EggLoader#getServerEnv */ this.serverEnv = this.getServerEnv(); @@ -74,6 +77,7 @@ class EggLoader { * unittest | unit test * * @return {String} serverEnv + * @since 1.0.0 */ getServerEnv() { let serverEnv; @@ -104,7 +108,7 @@ class EggLoader { * Get appname from pkg.name * * @return {String} appname - * @private + * @since 1.0.0 */ getAppname() { if (this.pkg.name) { @@ -138,6 +142,7 @@ class EggLoader { * ``` * * @return {Array} framework directories + * @since 1.0.0 */ getEggPaths() { const eggPaths = []; @@ -177,6 +182,7 @@ class EggLoader { * ```js * app.loader.loadFile(path.join(app.options.baseDir, 'config/router.js')); * ``` + * @since 1.0.0 */ loadFile(filepath) { if (!fs.existsSync(filepath)) { @@ -203,6 +209,7 @@ class EggLoader { * 3. app * * @return {Array} loadUnits + * @since 1.0.0 */ getLoadUnits() { if (this.dirs) { @@ -211,7 +218,6 @@ class EggLoader { const dirs = this.dirs = []; - // 插件目录,master 没有 plugin if (this.orderPlugins) { for (const plugin of this.orderPlugins) { dirs.push({ @@ -221,7 +227,7 @@ class EggLoader { } } - // egg 框架路径 + // framework or egg path for (const eggPath of this.eggPaths) { dirs.push({ path: eggPath, @@ -261,7 +267,7 @@ class EggLoader { } /** - * Mixin loader 方法到 BaseLoader,class 不支持多类继承 + * Mixin methods to EggLoader * // ES6 Multiple Inheritance * https://medium.com/@leocavalcante/es6-multiple-inheritance-73a3c66d2b6b */ diff --git a/lib/loader/mixin/config.js b/lib/loader/mixin/config.js index fe0f8481..09cfa790 100644 --- a/lib/loader/mixin/config.js +++ b/lib/loader/mixin/config.js @@ -15,6 +15,7 @@ module.exports = { * Will merge config.default.js 和 config.${env}.js * * @method EggLoader#loadConfig + * @since 1.0.0 */ loadConfig() { const target = {}; diff --git a/lib/loader/mixin/controller.js b/lib/loader/mixin/controller.js index 3c4e494c..0bc1b6ac 100644 --- a/lib/loader/mixin/controller.js +++ b/lib/loader/mixin/controller.js @@ -5,9 +5,9 @@ const path = require('path'); module.exports = { /** - * load app/controller - * - * @param {Object} opt LoaderOptions + * Load app/controller + * @param {Object} opt - LoaderOptions + * @since 1.0.0 */ loadController(opt) { opt = Object.assign({ lowercaseFirst: true }, opt); diff --git a/lib/loader/mixin/custom.js b/lib/loader/mixin/custom.js index de8968fe..e4d70b1a 100644 --- a/lib/loader/mixin/custom.js +++ b/lib/loader/mixin/custom.js @@ -18,6 +18,7 @@ module.exports = { * doAsync(done); * } * ``` + * @since 1.0.0 */ loadCustomApp() { this.getLoadUnits() diff --git a/lib/loader/mixin/extend.js b/lib/loader/mixin/extend.js index a36f70df..1c526713 100644 --- a/lib/loader/mixin/extend.js +++ b/lib/loader/mixin/extend.js @@ -9,60 +9,54 @@ const utils = require('../../utils'); module.exports = { /** - * 扩展 Agent.prototype 的属性 - * - * 可加载路径查看 {@link EggLoader#getLoadUnits} + * mixin Agent.prototype * @method EggLoader#loadAgentExtend + * @since 1.0.0 */ loadAgentExtend() { this.loadExtend('agent', this.app); }, /** - * 扩展 Application.prototype 的属性 - * - * 可加载路径查看 {@link EggLoader#getLoadUnits} + * mixin Application.prototype * @method EggLoader#loadApplicationExtend + * @since 1.0.0 */ loadApplicationExtend() { this.loadExtend('application', this.app); }, /** - * 扩展 Request.prototype 的属性 - * - * 可加载路径查看 {@link EggLoader#getLoadUnits} + * mixin Request.prototype * @method EggLoader#loadRequestExtend + * @since 1.0.0 */ loadRequestExtend() { this.loadExtend('request', this.app.request); }, /** - * 扩展 Response.prototype 的属性 - * - * 可加载路径查看 {@link EggLoader#getLoadUnits} + * mixin Response.prototype * @method EggLoader#loadResponseExtend + * @since 1.0.0 */ loadResponseExtend() { this.loadExtend('response', this.app.response); }, /** - * 扩展 Context.prototype 的属性 - * - * 可加载路径查看 {@link EggLoader#getLoadUnits} + * mixin Context.prototype * @method EggLoader#loadContextExtend + * @since 1.0.0 */ loadContextExtend() { this.loadExtend('context', this.app.context); }, /** - * 扩展 app.Helper.prototype 的属性 - * - * 可加载路径查看 {@link EggLoader#getLoadUnits} + * mixin app.Helper.prototype * @method EggLoader#loadHelperExtend + * @since 1.0.0 */ loadHelperExtend() { if (this.app && this.app.Helper) { @@ -71,12 +65,11 @@ module.exports = { }, /** - * 加载 extend 基类 - * + * Loader app/extend/xx.js to `prototype`, * @method loadExtend - * @param {String} name - 加载的文件名,如 app/extend/{name}.js - * @param {Object} proto - 最终将属性合并到 proto 上 - * @private + * @param {String} name - filename which may be `app/extend/{name}.js` + * @param {Object} proto - prototype that mixed + * @since 1.0.0 */ loadExtend(name, proto) { // 获取需要加载的文件 diff --git a/lib/loader/mixin/middleware.js b/lib/loader/mixin/middleware.js index b1cd42ef..bb56c285 100644 --- a/lib/loader/mixin/middleware.js +++ b/lib/loader/mixin/middleware.js @@ -8,12 +8,12 @@ const inspect = require('util').inspect; module.exports = { /** - * Load middleware + * Load app/middleware * * app.config.xx is the options of the middleware xx that has same name as config * * @method EggLoader#loadMiddleware - * @param {Object} opt LoaderOptions + * @param {Object} opt - LoaderOptions * @example * ```js * // app/middleware/status.js @@ -24,6 +24,7 @@ module.exports = { * } * } * ``` + * @since 1.0.0 */ loadMiddleware(opt) { const app = this.app; diff --git a/lib/loader/mixin/plugin.js b/lib/loader/mixin/plugin.js index 214b054a..35f1a148 100644 --- a/lib/loader/mixin/plugin.js +++ b/lib/loader/mixin/plugin.js @@ -9,14 +9,7 @@ const loadFile = require('../../utils').loadFile; module.exports = { /** - * Load plugin.js - * - * - * 插件配置来自三个地方 - * - * 1. 应用 config/plugin.js,优先级最高 - * 2. egg/config/plugin.js,优先级次之。 - * 3. 插件本身的 package.json => eggPlugin 配置,优先级最低 + * Load confog/plugin.js from {EggLoader#loadUnits} * * plugin.js is written below * @@ -28,7 +21,7 @@ module.exports = { * dep: [], * env: [], * }, - * // 简写 + * // short hand * 'rds': false, * 'depd': { * enable: true, @@ -37,38 +30,41 @@ module.exports = { * } * ``` * - * 根据配置从三个目录去加载插件,优先级依次降低 + * If the plugin has path, Loader will find the module from it. + * + * Otherwise Loader will lookup follow the order by packageName * - * 1. $APP_BASE/node_modules/${package or name} - * 2. $EGG_BASE/node_modules/${package or name} + * 1. $APP_BASE/node_modules/${package} + * 2. $EGG_BASE/node_modules/${package} * - * 加载后可通过 `loader.plugins` 访问已开启的插件 + * You can call `loader.plugins` that retrieve enabled plugins. * * ```js * loader.plugins['xxx-client'] = { - * name: 'xxx-client', // 模块名,模块依赖配置使用这个名字 - * package: 'xxx-client', // 包名,加载插件时会尝试使用包名加载 - * enable: true, // 是否开启 - * path: 'path/to/xxx-client', // 插件路径 - * dep: [], // 依赖的模块 - * env: [ 'local', 'unittest' ], // 只在这两个环境下开启才有效 + * name: 'xxx-client', // the plugin name, it can be used in `dep` + * package: 'xxx-client', // the package name of plugin + * enable: true, // whether enabled + * path: 'path/to/xxx-client', // the directory of the plugin package + * dep: [], // the dependent plugins, you can use the plugin name + * env: [ 'local', 'unittest' ], // specify the serverEnv that only enable the plugin in it * } * ``` * - * 如需要访问所有插件可调用 `loader.allPlugins` + * `loader.allPlugins` can be used when retrieve all plugins. * @method EggLoader#loadPlugin + * @since 1.0.0 */ loadPlugin() { - // 读取 appPlugins,为应用配置 + // loader plugins from application const appPlugins = this.readPluginConfigs(path.join(this.options.baseDir, 'config/plugin.js')); debug('Loaded app plugins: %j', Object.keys(appPlugins)); - // 读取 eggPlugins,为框架和 egg 配置 + // loader plugins from framework const eggPluginConfigPaths = this.eggPaths.map(eggPath => path.join(eggPath, 'config/plugin.js')); const eggPlugins = this.readPluginConfigs(eggPluginConfigPaths); debug('Loaded egg plugins: %j', Object.keys(eggPlugins)); - // 自定义插件配置,一般用于单元测试 + // loader plugins from process.env.EGG_PLUGINS let customPlugins; if (process.env.EGG_PLUGINS) { try { @@ -78,6 +74,7 @@ module.exports = { } } + // loader plugins from options.plugins if (this.options.plugins) { customPlugins = Object.assign({}, customPlugins, this.options.plugins); } @@ -89,33 +86,31 @@ module.exports = { debug('Loaded custom plugins: %j', Object.keys(customPlugins)); } - // 合并所有插件 this.allPlugins = {}; extendPlugins(this.allPlugins, eggPlugins); extendPlugins(this.allPlugins, appPlugins); extendPlugins(this.allPlugins, customPlugins); - // 过滤出环境不符的插件、以及被应用显示关闭的插件 - const enabledPluginNames = []; // 入口开启的插件列表,不包括被依赖的 + const enabledPluginNames = []; // enabled plugins that configured explicitly const plugins = {}; const env = this.serverEnv; for (const name in this.allPlugins) { const plugin = this.allPlugins[name]; - // 根据 path/package 获取真正的插件路径,两者互斥 + // resolve the real plugin.path based on plugin or package plugin.path = this.getPluginPath(plugin, this.options.baseDir); - // 从 eggPlugin 更新插件信息 + // read plugin infomation from ${plugin.path}/package.json this.mergePluginConfig(plugin); - // 只允许符合服务器环境 env 条件的插件开启 + // disable the plugin that not match the serverEnv if (env && plugin.env.length && plugin.env.indexOf(env) === -1) { debug('Disabled %j as env is %j, but got %j', name, plugin.env, env); plugin.enable = false; continue; } - // app 的配置优先级最高,切不允许隐式的规则推翻 app 配置 + // Can't enable the plugin implicitly when it's disabled by application if (appPlugins[name] && !appPlugins[name].enable) { debug('Disabled %j as disabled by app', name); continue; @@ -128,10 +123,9 @@ module.exports = { } } - // 获取开启的插件,并排序 + // retrieve the ordered plugins this.orderPlugins = this.getOrderPlugins(plugins, enabledPluginNames); - // 将数组转换成对象 const enablePlugins = {}; for (const plugin of this.orderPlugins) { enablePlugins[plugin.name] = plugin; @@ -139,17 +133,15 @@ module.exports = { debug('Loaded plugins: %j', Object.keys(enablePlugins)); /** - * 获取 plugin 配置 - * @alias app.loader.plugins - * @see Plugin - * @member {Object} App#plugins + * Retrieve enabled plugins + * @member {Object} EggLoader#plugins * @since 1.0.0 */ this.plugins = enablePlugins; }, /* - * 读取 plugin.js 配置 + * Read plugin.js from multiple directory */ readPluginConfigs(configPaths) { if (!Array.isArray(configPaths)) { @@ -168,20 +160,15 @@ module.exports = { this.normalizePluginConfig(config, name); } - // 拷贝一个新对象,不修改原来的对象 extendPlugins(plugins, config); } return plugins; }, - /* - * 标准化每个插件的配置项 - */ normalizePluginConfig(plugins, name) { const plugin = plugins[name]; - // 布尔型为简写,将其标准化 // plugin_name: false if (typeof plugin === 'boolean') { plugins[ name ] = { @@ -193,26 +180,25 @@ module.exports = { return; } - // 否则标准化每个配置 if (!('enable' in plugin)) { - plugin.enable = true; // 如果没有配则默认开启 + plugin.enable = true; } plugin.name = name; plugin.dep = plugin.dep || []; plugin.env = plugin.env || []; - // path, package 不需要处理 }, - // 读取插件本身的配置信息,插件只支持以下字段 + // Read plugin infomation from package.json and merge // { - // "name": "", 插件本身定义的名字,必须和配置名(应用或框架定义的 config/plugin.js)一致 - // "dep": [], 插件申明的依赖 - // "env": "", 插件适用的环境 + // eggPlugin: { + // "name": "", plugin name, must be same as name in config/plugin.js + // "dep": [], dependent plugins + // "env": "" env + // } // } mergePluginConfig(plugin) { let pkg; let config; - // 从 pkg.eggPlugin 获取配置 const pluginPackage = path.join(plugin.path, 'package.json'); if (fs.existsSync(pluginPackage)) { pkg = require(pluginPackage); @@ -229,8 +215,8 @@ module.exports = { } if (config.name && config.name !== plugin.name) { - // pluginName 为 config/plugin.js 配置的插件名 - // pluginConfigName 为 pkg.eggPath.name + // pluginName is configured in config/plugin.js + // pluginConfigName is pkg.eggPath.name logger.warn(`[egg:loader] pluginName(${plugin.name}) is different from pluginConfigName(${config.name})`); } @@ -241,15 +227,8 @@ module.exports = { } }, - /** - * 获取所有已开启并排序后的插件列表 - * @param {Object} allPlugins 所有的插件 - * @param {Array} enabledPluginNames 插件列表 - * @return {Array} 插件列表 - * @private - */ getOrderPlugins(allPlugins, enabledPluginNames) { - // 表示所有插件都未开启 + // no plugins enabled if (!enabledPluginNames.length) { return []; } @@ -257,10 +236,10 @@ module.exports = { const result = sequencify(allPlugins, enabledPluginNames); debug('Got plugins %j after sequencify', result); - // 如果 result.sequence 是空数组可能处理有问题 + // catch error when result.sequence is empty if (!result.sequence.length) { const err = new Error(`sequencify plugins has problem, missing: [${result.missingTasks}], recursive: [${result.recursiveDependencies}]`); - // 找出缺少的 plugins 被谁依赖了 + // find plugins which is required by the missing plugin for (const missName of result.missingTasks) { const requires = []; for (const name in allPlugins) { @@ -275,11 +254,10 @@ module.exports = { throw err; } - // 打印被自动开启的插件 + // log the plugins that be enabled implicitly const implicitEnabledPlugins = []; const requireMap = {}; result.sequence.forEach(name => { - // 统计插件被那些插件依赖,用于提示隐式开启的插件引用关系 for (const depName of allPlugins[name].dep) { if (!requireMap[depName]) { requireMap[depName] = []; @@ -288,7 +266,6 @@ module.exports = { } if (!allPlugins[name].enable) { - // 如果计算结果未开启说明需要自动开启 implicitEnabledPlugins.push(name); allPlugins[name].enable = true; } @@ -304,20 +281,18 @@ module.exports = { return result.sequence.map(name => allPlugins[name]); }, - // 获取插件真正的路径 + // Get the real plugin path getPluginPath(plugin) { - // 如果指定了 path 则直接使用 if (plugin.path) { return plugin.path; } - // 根据 package/name 配置 const name = plugin.package || plugin.name; const lookupDirs = []; // 尝试在以下目录找到匹配的插件 - // -> {appname}/node_modules - // -> {framework}/node_modules + // -> {APP_PATH}/node_modules + // -> {EGG_PATH}/node_modules // -> $CWD/node_modules lookupDirs.push(path.join(this.options.baseDir, 'node_modules')); @@ -327,7 +302,7 @@ module.exports = { lookupDirs.push(path.join(eggPath, 'node_modules')); } - // npm@3, 插件测试用例,还需要通过 $cwd/node_modules 目录获取 + // should find the $cwd/node_modules when test the plugins under npm3 lookupDirs.push(path.join(process.cwd(), 'node_modules')); for (let dir of lookupDirs) { @@ -342,8 +317,6 @@ module.exports = { }; -// 将 plugin 合并到 target 中 -// 如果合并过程中,插件指定了 path/package,则将已存在的 path/package 删除。 function extendPlugins(target, plugins) { if (!plugins) { return; diff --git a/lib/loader/mixin/router.js b/lib/loader/mixin/router.js index 2badce9b..2458f357 100644 --- a/lib/loader/mixin/router.js +++ b/lib/loader/mixin/router.js @@ -6,13 +6,10 @@ const Router = require('../../utils/router'); module.exports = { /** - * 加载 app/proxy 目录下的文件 - * - * 1. 加载应用 app/proxy - * 2. 加载插件 app/proxy - * - * @method EggLoader#loadProxy - * @param {Object} opt - loading 参数 + * Load app/router.js + * @method EggLoader#loadRouter + * @param {Object} opt - LoaderOptions + * @since 1.0.0 */ loadRouter() { const app = this.app; diff --git a/lib/loader/mixin/service.js b/lib/loader/mixin/service.js index 2bf14b93..8cfe9a14 100644 --- a/lib/loader/mixin/service.js +++ b/lib/loader/mixin/service.js @@ -5,13 +5,10 @@ const path = require('path'); module.exports = { /** - * 加载 app/service 目录下的文件 - * - * 1. 加载应用 app/service - * 2. 加载插件 app/service - * + * Load app/service * @method EggLoader#loadService - * @param {Object} opt - loading 参数 + * @param {Object} opt - LoaderOptions + * @since 1.0.0 */ loadService(opt) { const servicePaths = this.getLoadUnits().map(unit => { diff --git a/lib/utils/index.js b/lib/utils/index.js index 41230387..923664cd 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -4,11 +4,6 @@ const interopRequire = require('interop-require'); module.exports = exports = { - /** - * require a file - * @param {String} filepath fullpath - * @return {Object} exports - */ loadFile(filepath) { let exports; try { @@ -20,26 +15,15 @@ module.exports = exports = { return exports; }, - /** - * 判断模块是否存在 - * @method Util#existsModule - * @param {String} path - 模块路径 - * @return {boolean} 如果模块存在则返回 `true`,否则返回 `false`。 - */ - existsModule(path) { + existsModule(filepath) { try { - require.resolve(path); + require.resolve(filepath); return true; } catch (e) { return false; } }, - /** - * 获得 Home 目录,将会从环境变量 `HOME` 里面获取,如果没有,会返回 "/home/admin" - * @function getHomedir - * @return {String} 用户目录 - */ getHomedir() { return process.env.HOME || '/home/admin'; }, diff --git a/lib/utils/router.js b/lib/utils/router.js index cd028cce..7dace84e 100644 --- a/lib/utils/router.js +++ b/lib/utils/router.js @@ -1,9 +1,3 @@ -/** - * 基于 koa-router 实现 egg 的路由扩展 - * 比如: - * - app.resources() ... - */ - 'use strict'; const KoaRouter = require('koa-router'); @@ -53,21 +47,18 @@ const REST_MAP = { const slice = Array.prototype.slice; -/** - * 路由类 - */ class Router extends KoaRouter { /** * @constructor - * @param {Object} opts Router options. - * @param {Application} app Application object. + * @param {Object} opts - Router options. + * @param {Application} app - Application object. */ constructor(opts, app) { super(opts); this.app = app; - // patch app, koa-router 5.x 去除了 app patch 功能 + // patch koa-router@5.x const router = this; app.url = this.url.bind(this); app.router = this; @@ -82,10 +73,10 @@ class Router extends KoaRouter { } /** - * 实现 RESTFul 风格的一组路由 + * restful router api * @param {String} name - Router name - * @param {String} prefix - URL 路径前缀 - * @param {Function} middleware - Controller 或 Role 或 字符串的 Controller.Action 具体看 Example + * @param {String} prefix - url prefix + * @param {Function} middleware - middleware or controller * @example * ```js * app.resources('/posts', 'posts') @@ -93,13 +84,13 @@ class Router extends KoaRouter { * app.resources('posts', '/posts', app.role.can('user'), app.controller.posts) * ``` * - * 例如: + * Examples: * * ```js * app.resources('/posts', 'posts') * ``` * - * 将会直接对应成: + * yield router mapping * * Method | Path | Route Name | Controller.Action * -------|-----------------|----------------|----------------------------- @@ -111,7 +102,7 @@ class Router extends KoaRouter { * PUT | /posts/:id | post | app.controller.posts.update * DELETE | /posts/:id | post | app.controller.posts.destroy * - * app.router.url 生成 URL 路径参考: + * app.router.url can generate url based on arguments * ```js * app.router.url('posts') * => /posts @@ -146,7 +137,6 @@ class Router extends KoaRouter { } const opts = REST_MAP[key]; - // 处理 Route name 单数复数,以及前缀的事情 let formatedName; if (opts.member) { formatedName = inflection.singularize(name); @@ -165,9 +155,8 @@ class Router extends KoaRouter { } /** - * 覆盖 router.url 以实现 queryString 的参数, 之前只能生成出 /posts/:id 路由声明里面已知的参数 * @param {String} name - Router name - * @param {Object} params - 更多的参数,具体见 example + * @param {Object} params - more parameters * @example * ```js * router.url('edit_post', { id: 1, name: 'foo', page: 2 }) @@ -232,7 +221,7 @@ class Router extends KoaRouter { } /** - * 覆盖原始的 register 函数,实现让最后个 action 的 function 可以是字符串,以便能实现下面的效果 + * override koa-router, controller can be string * @param {String} path Path string or regular expression. * @param {Array.} methods Array of HTTP verbs. * @param {Function} middleware Multiple middleware also accepted. @@ -250,7 +239,6 @@ class Router extends KoaRouter { * app.resources('posts', '/posts', 'posts'); * app.get('/', '/posts', 'home.index'); * - * 同时,两种方式也支持。 */ register(path, methods, middleware, opts) { middleware = Array.isArray(middleware) ? middleware : [ middleware ]; diff --git a/package.json b/package.json index de3da13b..8888e13d 100644 --- a/package.json +++ b/package.json @@ -55,4 +55,4 @@ "ready-callback": "^1.0.0", "utility": "^1.8.0" } -} \ No newline at end of file +} diff --git a/test/egg.test.js b/test/egg.test.js index 3bbda98a..f17a24da 100644 --- a/test/egg.test.js +++ b/test/egg.test.js @@ -26,12 +26,12 @@ describe('test/egg.test.js', () => { it('should use cwd when no options', () => { app = new Application(); - app._options.baseDir.should.eql(process.cwd()); + app._options.baseDir.should.equal(process.cwd()); }); it('should set default application when no type', () => { app = new Application(); - app.type.should.eql('application'); + app.type.should.equal('application'); }); it('should not set value expect for application and agent', () => { @@ -73,19 +73,20 @@ describe('test/egg.test.js', () => { app = utils.createApp('app-getter'); app.loader.loadPlugin(); app.loader.loadConfig(); + return app.ready(); }); after(() => app.close()); it('should has get type', () => { - app.type.should.eql('application'); + app.type.should.equal('application'); }); it('should has baseDir', () => { - app.baseDir.should.eql(utils.getFilepath('app-getter')); + app.baseDir.should.equal(utils.getFilepath('app-getter')); }); it('should has name', () => { - app.name.should.eql('app-getter'); + app.name.should.equal('app-getter'); }); it('should has plugins', () => { @@ -119,8 +120,8 @@ describe('test/egg.test.js', () => { app = utils.createApp('notready'); app.loader.loadAll(); mm(app.console, 'warn', (message, a) => { - message.should.eql('[egg:core:ready_timeout] 10 seconds later %s was still unable to finish.'); - a.should.eql('a'); + message.should.equal('[egg:core:ready_timeout] 10 seconds later %s was still unable to finish.'); + a.should.equal('a'); done(); }); app.ready(() => { diff --git a/test/loader/get_appname.test.js b/test/loader/get_appname.test.js index a1d17f3d..f901c9e5 100644 --- a/test/loader/get_appname.test.js +++ b/test/loader/get_appname.test.js @@ -12,7 +12,7 @@ describe('test/loader/get_appname.test.js', function() { it('should get appname', function() { app = utils.createApp('appname'); - app.loader.getAppname().should.eql('appname'); + app.loader.getAppname().should.equal('appname'); }); it('should throw when appname is not found', function() {