From 7c202b26e9bb09e9ffccd3d6f16962e4acd7397d Mon Sep 17 00:00:00 2001 From: wanghx Date: Tue, 20 Mar 2018 17:53:19 +0800 Subject: [PATCH 01/20] feat: loader support custom extension --- .gitignore | 3 ++- lib/loader/egg_loader.js | 10 +++++----- lib/loader/file_loader.js | 12 ++++++++++-- lib/loader/mixin/config.js | 13 +++++++------ lib/loader/mixin/custom.js | 5 +++-- lib/loader/mixin/extend.js | 4 ++-- lib/loader/mixin/plugin.js | 19 +++++++++++-------- lib/loader/mixin/router.js | 3 ++- lib/utils/index.js | 2 +- 9 files changed, 43 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index a6fd35e1..6987c06e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ coverage .logs npm-debug.log .vscode -.DS_Store \ No newline at end of file +.DS_Store +yarn.lock \ No newline at end of file diff --git a/lib/loader/egg_loader.js b/lib/loader/egg_loader.js index 50690180..9a1cbe65 100644 --- a/lib/loader/egg_loader.js +++ b/lib/loader/egg_loader.js @@ -282,7 +282,7 @@ class EggLoader { * @since 1.0.0 */ loadFile(filepath, ...inject) { - if (!fs.existsSync(filepath)) { + if (!filepath || !fs.existsSync(filepath)) { return null; } @@ -391,12 +391,12 @@ class EggLoader { } getTypeFiles(filename) { - const files = [ `${filename}.default.js` ]; - if (this.serverScope) files.push(`${filename}.${this.serverScope}.js`); + const files = [ `${filename}.default` ]; + if (this.serverScope) files.push(`${filename}.${this.serverScope}`); if (this.serverEnv === 'default') return files; - files.push(`${filename}.${this.serverEnv}.js`); - if (this.serverScope) files.push(`${filename}.${this.serverScope}_${this.serverEnv}.js`); + files.push(`${filename}.${this.serverEnv}`); + if (this.serverScope) files.push(`${filename}.${this.serverScope}_${this.serverEnv}`); return files; } } diff --git a/lib/loader/file_loader.js b/lib/loader/file_loader.js index f51b4b06..63e10825 100644 --- a/lib/loader/file_loader.js +++ b/lib/loader/file_loader.js @@ -120,8 +120,16 @@ class FileLoader { * @since 1.0.0 */ parse() { - let files = this.options.match || [ '**/*.js' ]; - files = Array.isArray(files) ? files : [ files ]; + let files = this.options.match; + if (!files) { + const extensions = Object.keys(require.extensions).map(ext => ext.substring(1)); + files = [ '**/*.(' + extensions.join('|') + ')' ]; + if (extensions.includes('ts')) { + files.push('!**/*.d.ts'); + } + } else { + files = Array.isArray(files) ? files : [ files ]; + } let ignore = this.options.ignore; if (ignore) { diff --git a/lib/loader/mixin/config.js b/lib/loader/mixin/config.js index 0d4c25b0..cf1e4a61 100644 --- a/lib/loader/mixin/config.js +++ b/lib/loader/mixin/config.js @@ -1,10 +1,10 @@ 'use strict'; const debug = require('debug')('egg-core:config'); -const fs = require('fs'); const path = require('path'); const extend = require('extend2'); const assert = require('assert'); +const utils = require('../../utils'); const SET_CONFIG_META = Symbol('Loader#setConfigMeta'); @@ -55,8 +55,8 @@ module.exports = { _preloadAppConfig() { const names = [ - 'config.default.js', - `config.${this.serverEnv}.js`, + 'config.default', + `config.${this.serverEnv}`, ]; const target = {}; for (const filename of names) { @@ -70,12 +70,13 @@ module.exports = { const isPlugin = type === 'plugin'; const isApp = type === 'app'; - let filepath = path.join(dirpath, 'config', filename); + let filepath = utils.resolveModule(path.join(dirpath, 'config', filename)); // let config.js compatible - if (filename === 'config.default.js' && !fs.existsSync(filepath)) { - filepath = path.join(dirpath, 'config/config.js'); + if (filename === 'config.default' && !filepath) { + filepath = utils.resolveModule(path.join(dirpath, 'config/config')); } const config = this.loadFile(filepath, this.appInfo, extraInject); + if (!config) return null; if (isPlugin || isApp) { diff --git a/lib/loader/mixin/custom.js b/lib/loader/mixin/custom.js index 4d3fb41c..e5e08888 100644 --- a/lib/loader/mixin/custom.js +++ b/lib/loader/mixin/custom.js @@ -1,6 +1,7 @@ 'use strict'; const path = require('path'); +const utils = require('../../utils'); module.exports = { @@ -22,7 +23,7 @@ module.exports = { */ loadCustomApp() { this.getLoadUnits() - .forEach(unit => this.loadFile(path.join(unit.path, 'app.js'))); + .forEach(unit => this.loadFile(utils.resolveModule(path.join(unit.path, 'app')))); }, /** @@ -30,7 +31,7 @@ module.exports = { */ loadCustomAgent() { this.getLoadUnits() - .forEach(unit => this.loadFile(path.join(unit.path, 'agent.js'))); + .forEach(unit => this.loadFile(utils.resolveModule(path.join(unit.path, 'agent')))); }, }; diff --git a/lib/loader/mixin/extend.js b/lib/loader/mixin/extend.js index 45d527d0..8a9fab4f 100644 --- a/lib/loader/mixin/extend.js +++ b/lib/loader/mixin/extend.js @@ -96,8 +96,8 @@ module.exports = { const isAddUnittest = 'EGG_MOCK_SERVER_ENV' in process.env && this.serverEnv !== 'unittest'; for (let i = 0, l = filepaths.length; i < l; i++) { const filepath = filepaths[i]; - filepaths.push(filepath + `.${this.serverEnv}.js`); - if (isAddUnittest) filepaths.push(filepath + '.unittest.js'); + filepaths.push(filepath + `.${this.serverEnv}`); + if (isAddUnittest) filepaths.push(filepath + '.unittest'); } const mergeRecord = new Map(); diff --git a/lib/loader/mixin/plugin.js b/lib/loader/mixin/plugin.js index 158355a8..f8693d37 100644 --- a/lib/loader/mixin/plugin.js +++ b/lib/loader/mixin/plugin.js @@ -5,6 +5,7 @@ const path = require('path'); const debug = require('debug')('egg-core:plugin'); const sequencify = require('../../utils/sequencify'); const loadFile = require('../../utils').loadFile; +const utils = require('../../utils'); module.exports = { @@ -56,11 +57,11 @@ module.exports = { */ loadPlugin() { // loader plugins from application - const appPlugins = this.readPluginConfigs(path.join(this.options.baseDir, 'config/plugin.default.js')); + const appPlugins = this.readPluginConfigs(path.join(this.options.baseDir, 'config/plugin.default')); debug('Loaded app plugins: %j', Object.keys(appPlugins)); // loader plugins from framework - const eggPluginConfigPaths = this.eggPaths.map(eggPath => path.join(eggPath, 'config/plugin.default.js')); + const eggPluginConfigPaths = this.eggPaths.map(eggPath => path.join(eggPath, 'config/plugin.default')); const eggPlugins = this.readPluginConfigs(eggPluginConfigPaths); debug('Loaded egg plugins: %j', Object.keys(eggPlugins)); @@ -159,20 +160,22 @@ module.exports = { } const plugins = {}; - for (let configPath of newConfigPaths) { + for (const configPath of newConfigPaths) { + let filepath = utils.resolveModule(configPath); + // let plugin.js compatible - if (configPath.endsWith('plugin.default.js') && !fs.existsSync(configPath)) { - configPath = configPath.replace(/plugin\.default\.js$/, 'plugin.js'); + if (configPath.endsWith('plugin.default') && !filepath) { + filepath = utils.resolveModule(configPath.replace(/plugin\.default$/, 'plugin')); } - if (!fs.existsSync(configPath)) { + if (!filepath) { continue; } - const config = loadFile(configPath); + const config = loadFile(filepath); for (const name in config) { - this.normalizePluginConfig(config, name, configPath); + this.normalizePluginConfig(config, name, filepath); } this._extendPlugins(plugins, config); diff --git a/lib/loader/mixin/router.js b/lib/loader/mixin/router.js index af202d2d..3fbe4771 100644 --- a/lib/loader/mixin/router.js +++ b/lib/loader/mixin/router.js @@ -1,6 +1,7 @@ 'use strict'; const path = require('path'); +const utils = require('../../utils'); module.exports = { @@ -12,6 +13,6 @@ module.exports = { */ loadRouter() { // 加载 router.js - this.loadFile(path.join(this.options.baseDir, 'app/router.js')); + this.loadFile(utils.resolveModule(path.join(this.options.baseDir, 'app/router'))); }, }; diff --git a/lib/utils/index.js b/lib/utils/index.js index 87caa7a4..3311ec07 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -12,7 +12,7 @@ module.exports = { try { // if not js module, just return content buffer const extname = path.extname(filepath); - if (![ '.js', '.node', '.json', '' ].includes(extname)) { + if (extname && !require.extensions[extname]) { return fs.readFileSync(filepath); } // require js module From 030e489083410e9d413e010f68d9548bc7607b07 Mon Sep 17 00:00:00 2001 From: wanghx Date: Tue, 20 Mar 2018 18:35:58 +0800 Subject: [PATCH 02/20] feat: remove require.extensions --- lib/loader/file_loader.js | 15 ++++++++++----- lib/utils/index.js | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/loader/file_loader.js b/lib/loader/file_loader.js index 63e10825..e1443928 100644 --- a/lib/loader/file_loader.js +++ b/lib/loader/file_loader.js @@ -23,6 +23,7 @@ const defaults = { override: false, inject: undefined, filter: null, + extensions: [ '.js', '.ts' ], }; /** @@ -37,6 +38,7 @@ class FileLoader { * @param {String|Array} options.directory - directories to be loaded * @param {Object} options.target - attach the target object from loaded files * @param {String} options.match - match the files when load, support glob, default to all js files + * @param {String} options.extensions - match the file extension when load, default to .js and .ts * @param {String} options.ignore - ignore the files when load, support glob * @param {Function} options.initializer - custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path` * @param {Boolean} options.call - determine whether invoke when exports is function @@ -50,6 +52,13 @@ class FileLoader { assert(options.target, 'options.target is required'); this.options = Object.assign({}, defaults, options); + // cache the default match + const extensions = this.options.extensions.map(ext => ext.substring(1)); + this.defaultMatch = [ '**/*.(' + extensions.join('|') + ')' ]; + if (extensions.includes('ts')) { + this.defaultMatch.push('!**/*.d.ts'); + } + // compatible old options _lowercaseFirst_ if (this.options.lowercaseFirst === true) { deprecate('lowercaseFirst is deprecated, use caseStyle instead'); @@ -122,11 +131,7 @@ class FileLoader { parse() { let files = this.options.match; if (!files) { - const extensions = Object.keys(require.extensions).map(ext => ext.substring(1)); - files = [ '**/*.(' + extensions.join('|') + ')' ]; - if (extensions.includes('ts')) { - files.push('!**/*.d.ts'); - } + files = this.defaultMatch; } else { files = Array.isArray(files) ? files : [ files ]; } diff --git a/lib/utils/index.js b/lib/utils/index.js index 3311ec07..14405d7e 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -12,7 +12,7 @@ module.exports = { try { // if not js module, just return content buffer const extname = path.extname(filepath); - if (extname && !require.extensions[extname]) { + if (![ '.js', '.node', '.json', '', '.ts' ].includes(extname)) { return fs.readFileSync(filepath); } // require js module From 49d967e7112c53753f773ee87cdbddfb53f58607 Mon Sep 17 00:00:00 2001 From: wanghx Date: Wed, 21 Mar 2018 16:19:50 +0800 Subject: [PATCH 03/20] refactor: refactor to require.extensions --- lib/loader/file_loader.js | 26 +++++++++++++++++--------- lib/utils/index.js | 2 +- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/loader/file_loader.js b/lib/loader/file_loader.js index e1443928..6d0c54b0 100644 --- a/lib/loader/file_loader.js +++ b/lib/loader/file_loader.js @@ -10,6 +10,7 @@ const deprecate = require('depd')('egg'); const utils = require('../utils'); const FULLPATH = Symbol('EGG_LOADER_ITEM_FULLPATH'); const EXPORTS = Symbol('EGG_LOADER_ITEM_EXPORTS'); +const MATCH = Symbol('EGG_LOADER_ITEM_MATCH'); const defaults = { directory: null, @@ -23,7 +24,6 @@ const defaults = { override: false, inject: undefined, filter: null, - extensions: [ '.js', '.ts' ], }; /** @@ -38,7 +38,6 @@ class FileLoader { * @param {String|Array} options.directory - directories to be loaded * @param {Object} options.target - attach the target object from loaded files * @param {String} options.match - match the files when load, support glob, default to all js files - * @param {String} options.extensions - match the file extension when load, default to .js and .ts * @param {String} options.ignore - ignore the files when load, support glob * @param {Function} options.initializer - custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path` * @param {Boolean} options.call - determine whether invoke when exports is function @@ -52,13 +51,6 @@ class FileLoader { assert(options.target, 'options.target is required'); this.options = Object.assign({}, defaults, options); - // cache the default match - const extensions = this.options.extensions.map(ext => ext.substring(1)); - this.defaultMatch = [ '**/*.(' + extensions.join('|') + ')' ]; - if (extensions.includes('ts')) { - this.defaultMatch.push('!**/*.d.ts'); - } - // compatible old options _lowercaseFirst_ if (this.options.lowercaseFirst === true) { deprecate('lowercaseFirst is deprecated, use caseStyle instead'); @@ -66,6 +58,22 @@ class FileLoader { } } + /** + * default glob used to match files, creating by require.extensions. + * @return {Array} match + */ + get defaultMatch() { + if (!this[MATCH]) { + // cache the default match + const extensions = Object.keys(require.extensions).map(ext => ext.substring(1)); + this[MATCH] = [ '**/*.(' + extensions.join('|') + ')' ]; + if (extensions.includes('ts')) { + this[MATCH].push('!**/*.d.ts'); + } + } + return this[MATCH]; + } + /** * attach items to target object. Mapping the directory to properties. * `app/controller/group/repository.js` => `target.group.repository` diff --git a/lib/utils/index.js b/lib/utils/index.js index 14405d7e..3311ec07 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -12,7 +12,7 @@ module.exports = { try { // if not js module, just return content buffer const extname = path.extname(filepath); - if (![ '.js', '.node', '.json', '', '.ts' ].includes(extname)) { + if (extname && !require.extensions[extname]) { return fs.readFileSync(filepath); } // require js module From e710e8c6056687d8546a84f0e53d780d0df63fdf Mon Sep 17 00:00:00 2001 From: wanghx Date: Wed, 21 Mar 2018 18:30:23 +0800 Subject: [PATCH 04/20] test: add unittest for ts --- package.json | 5 +- test/egg-ts.test.js | 48 +++++++++++++++++++ test/fixtures/egg-ts/app/controller/home.ts | 19 ++++++++ .../fixtures/egg-ts/app/extend/application.ts | 5 ++ test/fixtures/egg-ts/app/extend/context.ts | 5 ++ test/fixtures/egg-ts/app/extend/request.ts | 5 ++ test/fixtures/egg-ts/app/extend/response.ts | 5 ++ test/fixtures/egg-ts/app/middleware/mid.ts | 8 ++++ test/fixtures/egg-ts/app/router.ts | 6 +++ test/fixtures/egg-ts/app/service/Test.ts | 7 +++ test/fixtures/egg-ts/config/config.default.ts | 14 ++++++ test/fixtures/egg-ts/config/plugin.ts | 7 +++ test/fixtures/egg-ts/package.json | 3 ++ .../egg-ts/plugins/a/config/config.default.ts | 13 +++++ test/fixtures/egg-ts/plugins/a/package.json | 3 ++ test/fixtures/egg-ts/tsconfig.json | 25 ++++++++++ .../egg-ts/typings/app/controller/index.d.ts | 10 ++++ .../typings/app/extend/application.d.ts | 9 ++++ .../egg-ts/typings/app/extend/context.d.ts | 9 ++++ .../egg-ts/typings/app/extend/request.d.ts | 9 ++++ .../egg-ts/typings/app/extend/response.d.ts | 9 ++++ .../egg-ts/typings/app/service/index.d.ts | 10 ++++ 22 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 test/egg-ts.test.js create mode 100644 test/fixtures/egg-ts/app/controller/home.ts create mode 100644 test/fixtures/egg-ts/app/extend/application.ts create mode 100644 test/fixtures/egg-ts/app/extend/context.ts create mode 100644 test/fixtures/egg-ts/app/extend/request.ts create mode 100644 test/fixtures/egg-ts/app/extend/response.ts create mode 100644 test/fixtures/egg-ts/app/middleware/mid.ts create mode 100644 test/fixtures/egg-ts/app/router.ts create mode 100644 test/fixtures/egg-ts/app/service/Test.ts create mode 100644 test/fixtures/egg-ts/config/config.default.ts create mode 100644 test/fixtures/egg-ts/config/plugin.ts create mode 100644 test/fixtures/egg-ts/package.json create mode 100644 test/fixtures/egg-ts/plugins/a/config/config.default.ts create mode 100644 test/fixtures/egg-ts/plugins/a/package.json create mode 100644 test/fixtures/egg-ts/tsconfig.json create mode 100644 test/fixtures/egg-ts/typings/app/controller/index.d.ts create mode 100644 test/fixtures/egg-ts/typings/app/extend/application.d.ts create mode 100644 test/fixtures/egg-ts/typings/app/extend/context.d.ts create mode 100644 test/fixtures/egg-ts/typings/app/extend/request.d.ts create mode 100644 test/fixtures/egg-ts/typings/app/extend/response.d.ts create mode 100644 test/fixtures/egg-ts/typings/app/service/index.d.ts diff --git a/package.json b/package.json index bec17e68..b19b2400 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "devDependencies": { "autod": "^3.0.1", "coffee": "^4.1.0", + "egg": "^2.5.0", "egg-bin": "^4.3.7", "egg-ci": "^1.8.0", "eslint": "^4.18.2", @@ -45,7 +46,9 @@ "pedding": "^1.1.0", "rimraf": "^2.6.2", "spy": "^1.0.0", - "supertest": "^3.0.0" + "supertest": "^3.0.0", + "ts-node": "^5.0.1", + "typescript": "^2.7.2" }, "dependencies": { "co": "^4.6.0", diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js new file mode 100644 index 00000000..718e9e64 --- /dev/null +++ b/test/egg-ts.test.js @@ -0,0 +1,48 @@ +'use strict'; + +const request = require('supertest'); +const assert = require('assert'); +const utils = require('./utils'); +const tsNode = require('ts-node'); + +describe('test/egg-ts.test.js', () => { + let app; + + it('should support ts-node', async () => { + tsNode.register({ + typeCheck: true, + compilerOptions: { + target: 'es2017', + module: 'commonjs', + moduleResolution: 'node', + }, + }); + + app = utils.createApp('egg-ts'); + app.loader.loadPlugin(); + app.loader.loadConfig(); + app.loader.loadContextExtend(); + app.loader.loadApplicationExtend(); + app.loader.loadRequestExtend(); + app.loader.loadResponseExtend(); + app.loader.loadService(); + app.loader.loadController(); + app.loader.loadRouter(); + app.loader.loadPlugin(); + app.loader.loadMiddleware(); + + await request(app.callback()) + .get('/') + .expect(res => { + assert(res.text.includes('from extend context')); + assert(res.text.includes('from extend application')); + assert(res.text.includes('from extend request')); + assert(res.text.includes('from extend response')); + assert(res.text.includes('from plugins')); + assert(res.text.includes('from config.default')); + assert(res.text.includes('from middleware')); + assert(res.text.includes('from service')); + }) + .expect(200); + }); +}); diff --git a/test/fixtures/egg-ts/app/controller/home.ts b/test/fixtures/egg-ts/app/controller/home.ts new file mode 100644 index 00000000..403fd831 --- /dev/null +++ b/test/fixtures/egg-ts/app/controller/home.ts @@ -0,0 +1,19 @@ +import { Controller } from 'egg'; + +export default class HomeController extends Controller { + public async index() { + const { ctx, app } = this; + const serviceText = ctx.service.test.getTest(); + + ctx.body = [ + ctx.contextShow(), + ctx.app.applicationShow(), + ctx.request.requestShow(), + ctx.response.responseShow(), + app.config.test, + app.config.testFromA, + ctx.mid, + serviceText + ].join(','); + } +} diff --git a/test/fixtures/egg-ts/app/extend/application.ts b/test/fixtures/egg-ts/app/extend/application.ts new file mode 100644 index 00000000..b72822d8 --- /dev/null +++ b/test/fixtures/egg-ts/app/extend/application.ts @@ -0,0 +1,5 @@ +export default { + applicationShow() { + return 'from extend application'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/extend/context.ts b/test/fixtures/egg-ts/app/extend/context.ts new file mode 100644 index 00000000..7649a2cb --- /dev/null +++ b/test/fixtures/egg-ts/app/extend/context.ts @@ -0,0 +1,5 @@ +export default { + contextShow() { + return 'from extend context'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/extend/request.ts b/test/fixtures/egg-ts/app/extend/request.ts new file mode 100644 index 00000000..f2d92839 --- /dev/null +++ b/test/fixtures/egg-ts/app/extend/request.ts @@ -0,0 +1,5 @@ +export default { + requestShow() { + return 'from extend request'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/extend/response.ts b/test/fixtures/egg-ts/app/extend/response.ts new file mode 100644 index 00000000..f7de36cc --- /dev/null +++ b/test/fixtures/egg-ts/app/extend/response.ts @@ -0,0 +1,5 @@ +export default { + responseShow() { + return 'from extend response'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/middleware/mid.ts b/test/fixtures/egg-ts/app/middleware/mid.ts new file mode 100644 index 00000000..20563fce --- /dev/null +++ b/test/fixtures/egg-ts/app/middleware/mid.ts @@ -0,0 +1,8 @@ +import { Context } from 'egg'; + +export default () => { + return async (ctx: Context, next) => { + ctx.mid = 'from middleware'; + await next(); + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/router.ts b/test/fixtures/egg-ts/app/router.ts new file mode 100644 index 00000000..d16b27c6 --- /dev/null +++ b/test/fixtures/egg-ts/app/router.ts @@ -0,0 +1,6 @@ +import { Application } from 'egg'; + +export default (app: Application) => { + const { router, controller } = app; + router.get('/', controller.home.index); +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/service/Test.ts b/test/fixtures/egg-ts/app/service/Test.ts new file mode 100644 index 00000000..62df3b1f --- /dev/null +++ b/test/fixtures/egg-ts/app/service/Test.ts @@ -0,0 +1,7 @@ +import { Service } from 'egg'; + +export default class TestService extends Service { + getTest() { + return 'from service'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/config/config.default.ts b/test/fixtures/egg-ts/config/config.default.ts new file mode 100644 index 00000000..1cf03e60 --- /dev/null +++ b/test/fixtures/egg-ts/config/config.default.ts @@ -0,0 +1,14 @@ +import { EggAppConfig } from 'egg'; + +export default (appInfo: EggAppConfig) => { + return { + middleware: [ 'mid' ], + test: 'from config.default', + }; +} + +declare module 'egg' { + interface EggAppConfig { + test: string; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/config/plugin.ts b/test/fixtures/egg-ts/config/plugin.ts new file mode 100644 index 00000000..f41e1830 --- /dev/null +++ b/test/fixtures/egg-ts/config/plugin.ts @@ -0,0 +1,7 @@ +import * as path from 'path'; + +export default { + a: { + path: path.resolve(__dirname, '../plugins/a'), + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/package.json b/test/fixtures/egg-ts/package.json new file mode 100644 index 00000000..d71db5a8 --- /dev/null +++ b/test/fixtures/egg-ts/package.json @@ -0,0 +1,3 @@ +{ + "name": "egg-ts" +} diff --git a/test/fixtures/egg-ts/plugins/a/config/config.default.ts b/test/fixtures/egg-ts/plugins/a/config/config.default.ts new file mode 100644 index 00000000..841e3bae --- /dev/null +++ b/test/fixtures/egg-ts/plugins/a/config/config.default.ts @@ -0,0 +1,13 @@ +import { EggAppConfig } from 'egg'; + +export default (appInfo: EggAppConfig) => { + return { + testFromA: 'from plugins', + }; +} + +declare module 'egg' { + interface EggAppConfig { + testFromA: string; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/plugins/a/package.json b/test/fixtures/egg-ts/plugins/a/package.json new file mode 100644 index 00000000..1aeaf2c8 --- /dev/null +++ b/test/fixtures/egg-ts/plugins/a/package.json @@ -0,0 +1,3 @@ +{ + "name": "a" +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/tsconfig.json b/test/fixtures/egg-ts/tsconfig.json new file mode 100644 index 00000000..092038b3 --- /dev/null +++ b/test/fixtures/egg-ts/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "strict": true, + "moduleResolution": "node", + "noImplicitAny": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "charset": "utf8", + "allowJs": false, + "pretty": true, + "noEmitOnError": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "strictPropertyInitialization": false, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "inlineSourceMap": true, + "importHelpers": true + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/controller/index.d.ts b/test/fixtures/egg-ts/typings/app/controller/index.d.ts new file mode 100644 index 00000000..4c562c87 --- /dev/null +++ b/test/fixtures/egg-ts/typings/app/controller/index.d.ts @@ -0,0 +1,10 @@ +// This file was auto generated by ts-helper +// Do not modify this file!!!!!!!!! + +import Home from '../../../app/controller/home'; + +declare module 'egg' { + interface IController { + home: Home; + } +} diff --git a/test/fixtures/egg-ts/typings/app/extend/application.d.ts b/test/fixtures/egg-ts/typings/app/extend/application.d.ts new file mode 100644 index 00000000..727bd8dd --- /dev/null +++ b/test/fixtures/egg-ts/typings/app/extend/application.d.ts @@ -0,0 +1,9 @@ +// This file was auto generated by ts-helper +// Do not modify this file!!!!!!!!! + +import ExtendObject from '../../../app/extend/application'; +declare module 'egg' { + interface Application { + applicationShow: typeof ExtendObject.applicationShow; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/extend/context.d.ts b/test/fixtures/egg-ts/typings/app/extend/context.d.ts new file mode 100644 index 00000000..91c6fb2e --- /dev/null +++ b/test/fixtures/egg-ts/typings/app/extend/context.d.ts @@ -0,0 +1,9 @@ +// This file was auto generated by ts-helper +// Do not modify this file!!!!!!!!! + +import ExtendObject from '../../../app/extend/context'; +declare module 'egg' { + interface Context { + contextShow: typeof ExtendObject.contextShow; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/extend/request.d.ts b/test/fixtures/egg-ts/typings/app/extend/request.d.ts new file mode 100644 index 00000000..0a37fb46 --- /dev/null +++ b/test/fixtures/egg-ts/typings/app/extend/request.d.ts @@ -0,0 +1,9 @@ +// This file was auto generated by ts-helper +// Do not modify this file!!!!!!!!! + +import ExtendObject from '../../../app/extend/request'; +declare module 'egg' { + interface Request { + requestShow: typeof ExtendObject.requestShow; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/extend/response.d.ts b/test/fixtures/egg-ts/typings/app/extend/response.d.ts new file mode 100644 index 00000000..9eb51c7d --- /dev/null +++ b/test/fixtures/egg-ts/typings/app/extend/response.d.ts @@ -0,0 +1,9 @@ +// This file was auto generated by ts-helper +// Do not modify this file!!!!!!!!! + +import ExtendObject from '../../../app/extend/response'; +declare module 'egg' { + interface Response { + responseShow: typeof ExtendObject.responseShow; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/service/index.d.ts b/test/fixtures/egg-ts/typings/app/service/index.d.ts new file mode 100644 index 00000000..e2754cfa --- /dev/null +++ b/test/fixtures/egg-ts/typings/app/service/index.d.ts @@ -0,0 +1,10 @@ +// This file was auto generated by ts-helper +// Do not modify this file!!!!!!!!! + +import Test from '../../../app/service/Test'; + +declare module 'egg' { + interface IService { + test: Test; + } +} From 107304395613a0a669624d4f0cc3e1d40578b0a5 Mon Sep 17 00:00:00 2001 From: wanghx Date: Wed, 21 Mar 2018 18:33:36 +0800 Subject: [PATCH 05/20] chore: remove tsconfig.json --- test/fixtures/egg-ts/tsconfig.json | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 test/fixtures/egg-ts/tsconfig.json diff --git a/test/fixtures/egg-ts/tsconfig.json b/test/fixtures/egg-ts/tsconfig.json deleted file mode 100644 index 092038b3..00000000 --- a/test/fixtures/egg-ts/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "target": "es2017", - "module": "commonjs", - "strict": true, - "moduleResolution": "node", - "noImplicitAny": false, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "charset": "utf8", - "allowJs": false, - "pretty": true, - "noEmitOnError": false, - "noUnusedLocals": true, - "noUnusedParameters": true, - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "strictPropertyInitialization": false, - "noFallthroughCasesInSwitch": true, - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "inlineSourceMap": true, - "importHelpers": true - } -} \ No newline at end of file From b9795ca8fbd66e080474575e88dd8e95243b047f Mon Sep 17 00:00:00 2001 From: wanghx Date: Wed, 21 Mar 2018 18:37:20 +0800 Subject: [PATCH 06/20] test: add d.ts --- test/fixtures/egg-ts/app/controller/index.d.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 test/fixtures/egg-ts/app/controller/index.d.ts diff --git a/test/fixtures/egg-ts/app/controller/index.d.ts b/test/fixtures/egg-ts/app/controller/index.d.ts new file mode 100644 index 00000000..a6c6e24c --- /dev/null +++ b/test/fixtures/egg-ts/app/controller/index.d.ts @@ -0,0 +1,7 @@ +import Home from './home'; + +declare module 'egg' { + interface IController { + home: Home; + } +} From e718758aefd19d3bbb22bbb1b349634bfed484b7 Mon Sep 17 00:00:00 2001 From: wanghx Date: Wed, 21 Mar 2018 18:54:40 +0800 Subject: [PATCH 07/20] test: test loadCustomApp and loadCustomAgent --- test/egg-ts.test.js | 4 ++++ test/fixtures/egg-ts/agent.ts | 11 +++++++++++ test/fixtures/egg-ts/app.ts | 11 +++++++++++ test/fixtures/egg-ts/app/controller/home.ts | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 test/fixtures/egg-ts/agent.ts create mode 100644 test/fixtures/egg-ts/app.ts diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index 718e9e64..ff60d5db 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -30,6 +30,8 @@ describe('test/egg-ts.test.js', () => { app.loader.loadRouter(); app.loader.loadPlugin(); app.loader.loadMiddleware(); + app.loader.loadCustomApp(); + app.loader.loadCustomAgent(); await request(app.callback()) .get('/') @@ -38,6 +40,8 @@ describe('test/egg-ts.test.js', () => { assert(res.text.includes('from extend application')); assert(res.text.includes('from extend request')); assert(res.text.includes('from extend response')); + assert(res.text.includes('from custom app')); + assert(res.text.includes('from custom agent')); assert(res.text.includes('from plugins')); assert(res.text.includes('from config.default')); assert(res.text.includes('from middleware')); diff --git a/test/fixtures/egg-ts/agent.ts b/test/fixtures/egg-ts/agent.ts new file mode 100644 index 00000000..866ebb73 --- /dev/null +++ b/test/fixtures/egg-ts/agent.ts @@ -0,0 +1,11 @@ +import { Application } from 'egg'; + +export default (app: Application) => { + app.fromCustomAgent = 'from custom agent'; +}; + +declare module 'egg' { + interface Application { + fromCustomAgent: string; + } +} diff --git a/test/fixtures/egg-ts/app.ts b/test/fixtures/egg-ts/app.ts new file mode 100644 index 00000000..de4c0553 --- /dev/null +++ b/test/fixtures/egg-ts/app.ts @@ -0,0 +1,11 @@ +import { Application } from 'egg'; + +export default (app: Application) => { + app.fromCustomApp = 'from custom app'; +}; + +declare module 'egg' { + interface Application { + fromCustomApp: string; + } +} diff --git a/test/fixtures/egg-ts/app/controller/home.ts b/test/fixtures/egg-ts/app/controller/home.ts index 403fd831..8cdc2d4d 100644 --- a/test/fixtures/egg-ts/app/controller/home.ts +++ b/test/fixtures/egg-ts/app/controller/home.ts @@ -10,6 +10,8 @@ export default class HomeController extends Controller { ctx.app.applicationShow(), ctx.request.requestShow(), ctx.response.responseShow(), + app.fromCustomApp, + app.fromCustomAgent, app.config.test, app.config.testFromA, ctx.mid, From c85b11461ea8630c255dec8c0eafd53c960f3861 Mon Sep 17 00:00:00 2001 From: wanghx Date: Wed, 21 Mar 2018 19:09:23 +0800 Subject: [PATCH 08/20] test: add more test for custom extend --- test/egg-ts.test.js | 5 +++- test/fixtures/egg-ts/app.ts | 1 + test/fixtures/egg-ts/app/controller/home.ts | 3 ++ test/fixtures/egg-ts/app/extend/agent.ts | 5 ++++ test/fixtures/egg-ts/app/extend/helper.ts | 5 ++++ test/fixtures/egg-ts/app/extend/index.d.ts | 29 +++++++++++++++++++ test/fixtures/egg-ts/app/service/index.d.ts | 7 +++++ .../egg-ts/typings/app/controller/index.d.ts | 10 ------- .../typings/app/extend/application.d.ts | 9 ------ .../egg-ts/typings/app/extend/context.d.ts | 9 ------ .../egg-ts/typings/app/extend/request.d.ts | 9 ------ .../egg-ts/typings/app/extend/response.d.ts | 9 ------ .../egg-ts/typings/app/service/index.d.ts | 10 ------- 13 files changed, 54 insertions(+), 57 deletions(-) create mode 100644 test/fixtures/egg-ts/app/extend/agent.ts create mode 100644 test/fixtures/egg-ts/app/extend/helper.ts create mode 100644 test/fixtures/egg-ts/app/extend/index.d.ts create mode 100644 test/fixtures/egg-ts/app/service/index.d.ts delete mode 100644 test/fixtures/egg-ts/typings/app/controller/index.d.ts delete mode 100644 test/fixtures/egg-ts/typings/app/extend/application.d.ts delete mode 100644 test/fixtures/egg-ts/typings/app/extend/context.d.ts delete mode 100644 test/fixtures/egg-ts/typings/app/extend/request.d.ts delete mode 100644 test/fixtures/egg-ts/typings/app/extend/response.d.ts delete mode 100644 test/fixtures/egg-ts/typings/app/service/index.d.ts diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index ff60d5db..d4c66ffa 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -19,12 +19,15 @@ describe('test/egg-ts.test.js', () => { }); app = utils.createApp('egg-ts'); + app.Helper = class Helper {}; app.loader.loadPlugin(); app.loader.loadConfig(); - app.loader.loadContextExtend(); app.loader.loadApplicationExtend(); + app.loader.loadAgentExtend(); app.loader.loadRequestExtend(); app.loader.loadResponseExtend(); + app.loader.loadContextExtend(); + app.loader.loadHelperExtend(); app.loader.loadService(); app.loader.loadController(); app.loader.loadRouter(); diff --git a/test/fixtures/egg-ts/app.ts b/test/fixtures/egg-ts/app.ts index de4c0553..fa687470 100644 --- a/test/fixtures/egg-ts/app.ts +++ b/test/fixtures/egg-ts/app.ts @@ -6,6 +6,7 @@ export default (app: Application) => { declare module 'egg' { interface Application { + Helper: any; fromCustomApp: string; } } diff --git a/test/fixtures/egg-ts/app/controller/home.ts b/test/fixtures/egg-ts/app/controller/home.ts index 8cdc2d4d..6dc892a3 100644 --- a/test/fixtures/egg-ts/app/controller/home.ts +++ b/test/fixtures/egg-ts/app/controller/home.ts @@ -4,12 +4,15 @@ export default class HomeController extends Controller { public async index() { const { ctx, app } = this; const serviceText = ctx.service.test.getTest(); + const helper = new ctx.app.Helper(); ctx.body = [ ctx.contextShow(), ctx.app.applicationShow(), ctx.request.requestShow(), ctx.response.responseShow(), + ctx.app.agentShow(), + helper.helperShow(), app.fromCustomApp, app.fromCustomAgent, app.config.test, diff --git a/test/fixtures/egg-ts/app/extend/agent.ts b/test/fixtures/egg-ts/app/extend/agent.ts new file mode 100644 index 00000000..aaec7288 --- /dev/null +++ b/test/fixtures/egg-ts/app/extend/agent.ts @@ -0,0 +1,5 @@ +export default { + agentShow() { + return 'from extend agent'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/extend/helper.ts b/test/fixtures/egg-ts/app/extend/helper.ts new file mode 100644 index 00000000..f9e7bff4 --- /dev/null +++ b/test/fixtures/egg-ts/app/extend/helper.ts @@ -0,0 +1,5 @@ +export default { + helperShow() { + return 'from extend show'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/extend/index.d.ts b/test/fixtures/egg-ts/app/extend/index.d.ts new file mode 100644 index 00000000..de225c7d --- /dev/null +++ b/test/fixtures/egg-ts/app/extend/index.d.ts @@ -0,0 +1,29 @@ +import ExtendAgent from './agent'; +import ExtendApplication from './application'; +import ExtendContext from './context'; +import ExtendRequest from './request'; +import ExtendResponse from './response'; +import ExtendHelper from './helper'; + +declare module 'egg' { + interface Application { + agentShow: typeof ExtendAgent.agentShow; + applicationShow: typeof ExtendApplication.applicationShow; + } + + interface Context { + contextShow: typeof ExtendContext.contextShow; + } + + interface Request { + requestShow: typeof ExtendRequest.requestShow; + } + + interface Response { + responseShow: typeof ExtendResponse.responseShow; + } + + interface IHelper { + helperShow: typeof ExtendHelper.helperShow; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/service/index.d.ts b/test/fixtures/egg-ts/app/service/index.d.ts new file mode 100644 index 00000000..72f5bcca --- /dev/null +++ b/test/fixtures/egg-ts/app/service/index.d.ts @@ -0,0 +1,7 @@ +import Test from './Test'; + +declare module 'egg' { + interface IService { + test: Test; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/controller/index.d.ts b/test/fixtures/egg-ts/typings/app/controller/index.d.ts deleted file mode 100644 index 4c562c87..00000000 --- a/test/fixtures/egg-ts/typings/app/controller/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -// This file was auto generated by ts-helper -// Do not modify this file!!!!!!!!! - -import Home from '../../../app/controller/home'; - -declare module 'egg' { - interface IController { - home: Home; - } -} diff --git a/test/fixtures/egg-ts/typings/app/extend/application.d.ts b/test/fixtures/egg-ts/typings/app/extend/application.d.ts deleted file mode 100644 index 727bd8dd..00000000 --- a/test/fixtures/egg-ts/typings/app/extend/application.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// This file was auto generated by ts-helper -// Do not modify this file!!!!!!!!! - -import ExtendObject from '../../../app/extend/application'; -declare module 'egg' { - interface Application { - applicationShow: typeof ExtendObject.applicationShow; - } -} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/extend/context.d.ts b/test/fixtures/egg-ts/typings/app/extend/context.d.ts deleted file mode 100644 index 91c6fb2e..00000000 --- a/test/fixtures/egg-ts/typings/app/extend/context.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// This file was auto generated by ts-helper -// Do not modify this file!!!!!!!!! - -import ExtendObject from '../../../app/extend/context'; -declare module 'egg' { - interface Context { - contextShow: typeof ExtendObject.contextShow; - } -} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/extend/request.d.ts b/test/fixtures/egg-ts/typings/app/extend/request.d.ts deleted file mode 100644 index 0a37fb46..00000000 --- a/test/fixtures/egg-ts/typings/app/extend/request.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// This file was auto generated by ts-helper -// Do not modify this file!!!!!!!!! - -import ExtendObject from '../../../app/extend/request'; -declare module 'egg' { - interface Request { - requestShow: typeof ExtendObject.requestShow; - } -} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/extend/response.d.ts b/test/fixtures/egg-ts/typings/app/extend/response.d.ts deleted file mode 100644 index 9eb51c7d..00000000 --- a/test/fixtures/egg-ts/typings/app/extend/response.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// This file was auto generated by ts-helper -// Do not modify this file!!!!!!!!! - -import ExtendObject from '../../../app/extend/response'; -declare module 'egg' { - interface Response { - responseShow: typeof ExtendObject.responseShow; - } -} \ No newline at end of file diff --git a/test/fixtures/egg-ts/typings/app/service/index.d.ts b/test/fixtures/egg-ts/typings/app/service/index.d.ts deleted file mode 100644 index e2754cfa..00000000 --- a/test/fixtures/egg-ts/typings/app/service/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -// This file was auto generated by ts-helper -// Do not modify this file!!!!!!!!! - -import Test from '../../../app/service/Test'; - -declare module 'egg' { - interface IService { - test: Test; - } -} From 88117fbefa077dc423c829b2b00529798d847461 Mon Sep 17 00:00:00 2001 From: wanghx Date: Wed, 21 Mar 2018 19:13:11 +0800 Subject: [PATCH 09/20] fix: spelling mistake --- test/egg-ts.test.js | 2 ++ test/fixtures/egg-ts/app/extend/helper.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index d4c66ffa..fd640bc0 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -42,6 +42,8 @@ describe('test/egg-ts.test.js', () => { assert(res.text.includes('from extend context')); assert(res.text.includes('from extend application')); assert(res.text.includes('from extend request')); + assert(res.text.includes('from extend agent')); + assert(res.text.includes('from extend helper')); assert(res.text.includes('from extend response')); assert(res.text.includes('from custom app')); assert(res.text.includes('from custom agent')); diff --git a/test/fixtures/egg-ts/app/extend/helper.ts b/test/fixtures/egg-ts/app/extend/helper.ts index f9e7bff4..e3faca08 100644 --- a/test/fixtures/egg-ts/app/extend/helper.ts +++ b/test/fixtures/egg-ts/app/extend/helper.ts @@ -1,5 +1,5 @@ export default { helperShow() { - return 'from extend show'; + return 'from extend helper'; } } \ No newline at end of file From 47635fce7179e612e0a44fe500abadf385e65475 Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 10:42:12 +0800 Subject: [PATCH 10/20] feat: add typescript options --- lib/egg.js | 2 + lib/loader/egg_loader.js | 3 ++ lib/loader/file_loader.js | 24 +++-------- package.json | 5 +-- test/egg-ts.test.js | 40 +++++++++++++----- .../egg-ts-js/app/controller/god.d.ts | 0 .../fixtures/egg-ts-js/app/controller/test.ts | 3 ++ test/fixtures/egg-ts-js/app/service/lord.js | 5 +++ test/fixtures/egg-ts-js/app/service/test.ts | 5 +++ test/fixtures/egg-ts-js/package.json | 3 ++ test/fixtures/egg-ts/agent.ts | 10 +---- test/fixtures/egg-ts/app.ts | 11 +---- test/fixtures/egg-ts/app/controller/home.ts | 42 ++++++++----------- .../fixtures/egg-ts/app/controller/index.d.ts | 7 ---- test/fixtures/egg-ts/app/extend/agent.ts | 2 +- .../fixtures/egg-ts/app/extend/application.ts | 2 +- test/fixtures/egg-ts/app/extend/context.ts | 2 +- test/fixtures/egg-ts/app/extend/helper.ts | 2 +- test/fixtures/egg-ts/app/extend/index.d.ts | 29 ------------- test/fixtures/egg-ts/app/extend/request.ts | 2 +- test/fixtures/egg-ts/app/extend/response.ts | 2 +- test/fixtures/egg-ts/app/middleware/mid.ts | 6 +-- test/fixtures/egg-ts/app/router.ts | 6 +-- test/fixtures/egg-ts/app/service/Test.ts | 4 +- test/fixtures/egg-ts/app/service/index.d.ts | 7 ---- test/fixtures/egg-ts/config/config.default.ts | 10 +---- test/fixtures/egg-ts/config/plugin.ts | 4 +- .../egg-ts/plugins/a/config/config.default.ts | 10 +---- test/loader/file_loader.test.js | 11 +++++ 29 files changed, 104 insertions(+), 155 deletions(-) create mode 100644 test/fixtures/egg-ts-js/app/controller/god.d.ts create mode 100644 test/fixtures/egg-ts-js/app/controller/test.ts create mode 100644 test/fixtures/egg-ts-js/app/service/lord.js create mode 100644 test/fixtures/egg-ts-js/app/service/test.ts create mode 100644 test/fixtures/egg-ts-js/package.json delete mode 100644 test/fixtures/egg-ts/app/controller/index.d.ts delete mode 100644 test/fixtures/egg-ts/app/extend/index.d.ts delete mode 100644 test/fixtures/egg-ts/app/service/index.d.ts diff --git a/lib/egg.js b/lib/egg.js index f8f0ddbf..4e3bd2c0 100644 --- a/lib/egg.js +++ b/lib/egg.js @@ -28,6 +28,7 @@ class EggCore extends KoaApplication { * @param {Object} options - options * @param {String} [options.baseDir=process.cwd()] - the directory of application * @param {String} [options.type=application|agent] - whether it's running in app worker or agent worker + * @param {Boolean} [options.typescript] - whether support typescript. * @param {Object} [options.plugins] - custom plugins * @since 1.0.0 */ @@ -119,6 +120,7 @@ class EggCore extends KoaApplication { baseDir: options.baseDir, app: this, plugins: options.plugins, + typescript: options.typescript, logger: this.console, serverScope: options.serverScope, }); diff --git a/lib/loader/egg_loader.js b/lib/loader/egg_loader.js index 9a1cbe65..20b526a7 100644 --- a/lib/loader/egg_loader.js +++ b/lib/loader/egg_loader.js @@ -18,6 +18,7 @@ class EggLoader { * @constructor * @param {Object} options - options * @param {String} options.baseDir - the directory of application + * @param {Boolean} options.typescript - whether support typescript * @param {EggCore} options.app - Application instance * @param {Logger} options.logger - logger * @param {Object} [options.plugins] - custom plugins @@ -354,6 +355,7 @@ class EggLoader { directory, target, inject: this.app, + typescript: this.options.typescript, }, opt); new FileLoader(opt).load(); } @@ -370,6 +372,7 @@ class EggLoader { directory, property, inject: this.app, + typescript: this.options.typescript, }, opt); new ContextLoader(opt).load(); } diff --git a/lib/loader/file_loader.js b/lib/loader/file_loader.js index 6d0c54b0..8398acad 100644 --- a/lib/loader/file_loader.js +++ b/lib/loader/file_loader.js @@ -10,12 +10,12 @@ const deprecate = require('depd')('egg'); const utils = require('../utils'); const FULLPATH = Symbol('EGG_LOADER_ITEM_FULLPATH'); const EXPORTS = Symbol('EGG_LOADER_ITEM_EXPORTS'); -const MATCH = Symbol('EGG_LOADER_ITEM_MATCH'); const defaults = { directory: null, target: null, match: undefined, + typescript: false, ignore: undefined, lowercaseFirst: false, caseStyle: 'camel', @@ -38,6 +38,7 @@ class FileLoader { * @param {String|Array} options.directory - directories to be loaded * @param {Object} options.target - attach the target object from loaded files * @param {String} options.match - match the files when load, support glob, default to all js files + * @param {Boolean} options.typescript - whether support typescript, default to false. * @param {String} options.ignore - ignore the files when load, support glob * @param {Function} options.initializer - custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path` * @param {Boolean} options.call - determine whether invoke when exports is function @@ -49,6 +50,7 @@ class FileLoader { constructor(options) { assert(options.directory, 'options.directory is required'); assert(options.target, 'options.target is required'); + assert(!options.typescript || (options.typescript && require.extensions['.ts']), 'require.extensions should contains .ts while options.typescript was true'); this.options = Object.assign({}, defaults, options); // compatible old options _lowercaseFirst_ @@ -58,22 +60,6 @@ class FileLoader { } } - /** - * default glob used to match files, creating by require.extensions. - * @return {Array} match - */ - get defaultMatch() { - if (!this[MATCH]) { - // cache the default match - const extensions = Object.keys(require.extensions).map(ext => ext.substring(1)); - this[MATCH] = [ '**/*.(' + extensions.join('|') + ')' ]; - if (extensions.includes('ts')) { - this[MATCH].push('!**/*.d.ts'); - } - } - return this[MATCH]; - } - /** * attach items to target object. Mapping the directory to properties. * `app/controller/group/repository.js` => `target.group.repository` @@ -139,7 +125,9 @@ class FileLoader { parse() { let files = this.options.match; if (!files) { - files = this.defaultMatch; + files = this.options.typescript + ? [ '**/*.(js|ts)', '!**/*.d.ts' ] + : [ '**/*.js' ]; } else { files = Array.isArray(files) ? files : [ files ]; } diff --git a/package.json b/package.json index b19b2400..bec17e68 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "devDependencies": { "autod": "^3.0.1", "coffee": "^4.1.0", - "egg": "^2.5.0", "egg-bin": "^4.3.7", "egg-ci": "^1.8.0", "eslint": "^4.18.2", @@ -46,9 +45,7 @@ "pedding": "^1.1.0", "rimraf": "^2.6.2", "spy": "^1.0.0", - "supertest": "^3.0.0", - "ts-node": "^5.0.1", - "typescript": "^2.7.2" + "supertest": "^3.0.0" }, "dependencies": { "co": "^4.6.0", diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index fd640bc0..59f4db5d 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -3,22 +3,20 @@ const request = require('supertest'); const assert = require('assert'); const utils = require('./utils'); -const tsNode = require('ts-node'); describe('test/egg-ts.test.js', () => { let app; - it('should support ts-node', async () => { - tsNode.register({ - typeCheck: true, - compilerOptions: { - target: 'es2017', - module: 'commonjs', - moduleResolution: 'node', - }, + afterEach(() => { + delete require.extensions['.ts']; + }); + + it('should support load ts file', async () => { + require.extensions['.ts'] = require.extensions['.js']; + app = utils.createApp('egg-ts', { + typescript: true, }); - app = utils.createApp('egg-ts'); app.Helper = class Helper {}; app.loader.loadPlugin(); app.loader.loadConfig(); @@ -54,4 +52,26 @@ describe('test/egg-ts.test.js', () => { }) .expect(200); }); + + it('should not load d.ts files while typescript was true', async () => { + require.extensions['.ts'] = require.extensions['.js']; + app = utils.createApp('egg-ts-js', { + typescript: true, + }); + + app.loader.loadController(); + assert(!app.controller.god); + assert(!!app.controller.test); + }); + + it('should support load ts,js files', async () => { + require.extensions['.ts'] = require.extensions['.js']; + app = utils.createApp('egg-ts-js', { + typescript: true, + }); + + app.loader.loadService(); + assert(!!app.serviceClasses.lord); + assert(!!app.serviceClasses.test); + }); }); diff --git a/test/fixtures/egg-ts-js/app/controller/god.d.ts b/test/fixtures/egg-ts-js/app/controller/god.d.ts new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/egg-ts-js/app/controller/test.ts b/test/fixtures/egg-ts-js/app/controller/test.ts new file mode 100644 index 00000000..e868e3f7 --- /dev/null +++ b/test/fixtures/egg-ts-js/app/controller/test.ts @@ -0,0 +1,3 @@ +module.exports = async ctx => { + ctx.body = 'ok'; +} \ No newline at end of file diff --git a/test/fixtures/egg-ts-js/app/service/lord.js b/test/fixtures/egg-ts-js/app/service/lord.js new file mode 100644 index 00000000..c9d1df43 --- /dev/null +++ b/test/fixtures/egg-ts-js/app/service/lord.js @@ -0,0 +1,5 @@ +module.exports = class LordService { + jsService() { + return 'from js service'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts-js/app/service/test.ts b/test/fixtures/egg-ts-js/app/service/test.ts new file mode 100644 index 00000000..96ac64eb --- /dev/null +++ b/test/fixtures/egg-ts-js/app/service/test.ts @@ -0,0 +1,5 @@ +module.exports = class TestService { + tsService() { + return 'from ts service'; + } +} \ No newline at end of file diff --git a/test/fixtures/egg-ts-js/package.json b/test/fixtures/egg-ts-js/package.json new file mode 100644 index 00000000..d71db5a8 --- /dev/null +++ b/test/fixtures/egg-ts-js/package.json @@ -0,0 +1,3 @@ +{ + "name": "egg-ts" +} diff --git a/test/fixtures/egg-ts/agent.ts b/test/fixtures/egg-ts/agent.ts index 866ebb73..b4dc7cbf 100644 --- a/test/fixtures/egg-ts/agent.ts +++ b/test/fixtures/egg-ts/agent.ts @@ -1,11 +1,3 @@ -import { Application } from 'egg'; - -export default (app: Application) => { +module.exports = app => { app.fromCustomAgent = 'from custom agent'; }; - -declare module 'egg' { - interface Application { - fromCustomAgent: string; - } -} diff --git a/test/fixtures/egg-ts/app.ts b/test/fixtures/egg-ts/app.ts index fa687470..56b5238b 100644 --- a/test/fixtures/egg-ts/app.ts +++ b/test/fixtures/egg-ts/app.ts @@ -1,12 +1,3 @@ -import { Application } from 'egg'; - -export default (app: Application) => { +module.exports = app => { app.fromCustomApp = 'from custom app'; }; - -declare module 'egg' { - interface Application { - Helper: any; - fromCustomApp: string; - } -} diff --git a/test/fixtures/egg-ts/app/controller/home.ts b/test/fixtures/egg-ts/app/controller/home.ts index 6dc892a3..353e856a 100644 --- a/test/fixtures/egg-ts/app/controller/home.ts +++ b/test/fixtures/egg-ts/app/controller/home.ts @@ -1,24 +1,18 @@ -import { Controller } from 'egg'; - -export default class HomeController extends Controller { - public async index() { - const { ctx, app } = this; - const serviceText = ctx.service.test.getTest(); - const helper = new ctx.app.Helper(); - - ctx.body = [ - ctx.contextShow(), - ctx.app.applicationShow(), - ctx.request.requestShow(), - ctx.response.responseShow(), - ctx.app.agentShow(), - helper.helperShow(), - app.fromCustomApp, - app.fromCustomAgent, - app.config.test, - app.config.testFromA, - ctx.mid, - serviceText - ].join(','); - } -} +module.exports = async ctx => { + const serviceText = ctx.service.test.getTest(); + const helper = ctx.helper = new ctx.app.Helper(); + ctx.body = [ + ctx.contextShow(), + ctx.app.applicationShow(), + ctx.request.requestShow(), + ctx.response.responseShow(), + ctx.app.agentShow(), + ctx.helper.helperShow(), + ctx.app.fromCustomApp, + ctx.app.fromCustomAgent, + ctx.app.config.test, + ctx.app.config.testFromA, + ctx.mid, + serviceText + ].join(','); +} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/controller/index.d.ts b/test/fixtures/egg-ts/app/controller/index.d.ts deleted file mode 100644 index a6c6e24c..00000000 --- a/test/fixtures/egg-ts/app/controller/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Home from './home'; - -declare module 'egg' { - interface IController { - home: Home; - } -} diff --git a/test/fixtures/egg-ts/app/extend/agent.ts b/test/fixtures/egg-ts/app/extend/agent.ts index aaec7288..48f7a077 100644 --- a/test/fixtures/egg-ts/app/extend/agent.ts +++ b/test/fixtures/egg-ts/app/extend/agent.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { agentShow() { return 'from extend agent'; } diff --git a/test/fixtures/egg-ts/app/extend/application.ts b/test/fixtures/egg-ts/app/extend/application.ts index b72822d8..f08d3b3f 100644 --- a/test/fixtures/egg-ts/app/extend/application.ts +++ b/test/fixtures/egg-ts/app/extend/application.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { applicationShow() { return 'from extend application'; } diff --git a/test/fixtures/egg-ts/app/extend/context.ts b/test/fixtures/egg-ts/app/extend/context.ts index 7649a2cb..99624e1e 100644 --- a/test/fixtures/egg-ts/app/extend/context.ts +++ b/test/fixtures/egg-ts/app/extend/context.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { contextShow() { return 'from extend context'; } diff --git a/test/fixtures/egg-ts/app/extend/helper.ts b/test/fixtures/egg-ts/app/extend/helper.ts index e3faca08..1f7209d6 100644 --- a/test/fixtures/egg-ts/app/extend/helper.ts +++ b/test/fixtures/egg-ts/app/extend/helper.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { helperShow() { return 'from extend helper'; } diff --git a/test/fixtures/egg-ts/app/extend/index.d.ts b/test/fixtures/egg-ts/app/extend/index.d.ts deleted file mode 100644 index de225c7d..00000000 --- a/test/fixtures/egg-ts/app/extend/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import ExtendAgent from './agent'; -import ExtendApplication from './application'; -import ExtendContext from './context'; -import ExtendRequest from './request'; -import ExtendResponse from './response'; -import ExtendHelper from './helper'; - -declare module 'egg' { - interface Application { - agentShow: typeof ExtendAgent.agentShow; - applicationShow: typeof ExtendApplication.applicationShow; - } - - interface Context { - contextShow: typeof ExtendContext.contextShow; - } - - interface Request { - requestShow: typeof ExtendRequest.requestShow; - } - - interface Response { - responseShow: typeof ExtendResponse.responseShow; - } - - interface IHelper { - helperShow: typeof ExtendHelper.helperShow; - } -} \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/extend/request.ts b/test/fixtures/egg-ts/app/extend/request.ts index f2d92839..5672f9bc 100644 --- a/test/fixtures/egg-ts/app/extend/request.ts +++ b/test/fixtures/egg-ts/app/extend/request.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { requestShow() { return 'from extend request'; } diff --git a/test/fixtures/egg-ts/app/extend/response.ts b/test/fixtures/egg-ts/app/extend/response.ts index f7de36cc..21a270d8 100644 --- a/test/fixtures/egg-ts/app/extend/response.ts +++ b/test/fixtures/egg-ts/app/extend/response.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { responseShow() { return 'from extend response'; } diff --git a/test/fixtures/egg-ts/app/middleware/mid.ts b/test/fixtures/egg-ts/app/middleware/mid.ts index 20563fce..386cbc8c 100644 --- a/test/fixtures/egg-ts/app/middleware/mid.ts +++ b/test/fixtures/egg-ts/app/middleware/mid.ts @@ -1,7 +1,5 @@ -import { Context } from 'egg'; - -export default () => { - return async (ctx: Context, next) => { +module.exports = () => { + return async (ctx, next) => { ctx.mid = 'from middleware'; await next(); } diff --git a/test/fixtures/egg-ts/app/router.ts b/test/fixtures/egg-ts/app/router.ts index d16b27c6..366095d1 100644 --- a/test/fixtures/egg-ts/app/router.ts +++ b/test/fixtures/egg-ts/app/router.ts @@ -1,6 +1,4 @@ -import { Application } from 'egg'; - -export default (app: Application) => { +module.exports = app => { const { router, controller } = app; - router.get('/', controller.home.index); + router.get('/', controller.home); } \ No newline at end of file diff --git a/test/fixtures/egg-ts/app/service/Test.ts b/test/fixtures/egg-ts/app/service/Test.ts index 62df3b1f..8da345f7 100644 --- a/test/fixtures/egg-ts/app/service/Test.ts +++ b/test/fixtures/egg-ts/app/service/Test.ts @@ -1,6 +1,4 @@ -import { Service } from 'egg'; - -export default class TestService extends Service { +module.exports = class TestService { getTest() { return 'from service'; } diff --git a/test/fixtures/egg-ts/app/service/index.d.ts b/test/fixtures/egg-ts/app/service/index.d.ts deleted file mode 100644 index 72f5bcca..00000000 --- a/test/fixtures/egg-ts/app/service/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Test from './Test'; - -declare module 'egg' { - interface IService { - test: Test; - } -} \ No newline at end of file diff --git a/test/fixtures/egg-ts/config/config.default.ts b/test/fixtures/egg-ts/config/config.default.ts index 1cf03e60..bc4c4552 100644 --- a/test/fixtures/egg-ts/config/config.default.ts +++ b/test/fixtures/egg-ts/config/config.default.ts @@ -1,14 +1,6 @@ -import { EggAppConfig } from 'egg'; - -export default (appInfo: EggAppConfig) => { +module.exports = () => { return { middleware: [ 'mid' ], test: 'from config.default', }; -} - -declare module 'egg' { - interface EggAppConfig { - test: string; - } } \ No newline at end of file diff --git a/test/fixtures/egg-ts/config/plugin.ts b/test/fixtures/egg-ts/config/plugin.ts index f41e1830..917b0963 100644 --- a/test/fixtures/egg-ts/config/plugin.ts +++ b/test/fixtures/egg-ts/config/plugin.ts @@ -1,6 +1,6 @@ -import * as path from 'path'; +const path = require('path'); -export default { +module.exports = { a: { path: path.resolve(__dirname, '../plugins/a'), } diff --git a/test/fixtures/egg-ts/plugins/a/config/config.default.ts b/test/fixtures/egg-ts/plugins/a/config/config.default.ts index 841e3bae..6878f7f3 100644 --- a/test/fixtures/egg-ts/plugins/a/config/config.default.ts +++ b/test/fixtures/egg-ts/plugins/a/config/config.default.ts @@ -1,13 +1,5 @@ -import { EggAppConfig } from 'egg'; - -export default (appInfo: EggAppConfig) => { +module.exports = () => { return { testFromA: 'from plugins', }; } - -declare module 'egg' { - interface EggAppConfig { - testFromA: string; - } -} \ No newline at end of file diff --git a/test/loader/file_loader.test.js b/test/loader/file_loader.test.js index 3da37eec..8a3006dd 100644 --- a/test/loader/file_loader.test.js +++ b/test/loader/file_loader.test.js @@ -254,6 +254,17 @@ describe('test/loader/file_loader.test.js', () => { }, /_private is not match 'a-z0-9_-' in _private.js/); }); + it('should throw when typescript was true but no ts extension', () => { + const mod = {}; + assert.throws(() => { + new FileLoader({ + directory: path.join(dirBase, 'error/dotdir'), + target: mod, + typescript: true, + }).load(); + }, /require.extensions should contains .ts while options.typescript was true/); + }); + describe('caseStyle', () => { it('should load when caseStyle = upper', () => { const target = {}; From 5dc16bd22e120500c002c8f1c3ef76614b83cffd Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 10:42:34 +0800 Subject: [PATCH 11/20] docs: update typescript opt to docs --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b065855..62b3f2ac 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ EggLoader can easily load files or directories in your [egg] project. In additio - {String} baseDir - current directory of application - {Object} app - instance of egg application - {Object} plugins - merge plugins for test +- {Boolean} typescript - whether support typescript - {Logger} logger - logger instance,default is console ### High Level APIs @@ -226,7 +227,8 @@ Param | Type | Description -------------- | -------------- | ------------------------ directory | `String/Array` | directories to be loaded target | `Object` | attach the target object from loaded files -match | `String/Array` | match the files when load, default to `**/*.js` +match | `String/Array` | match the files when load, default to `**/*.js`(if typescript was true, default to `[ '**/*.(js|ts)', '!**/*.d.ts' ]`) +typescript | `Boolean` | whether support typescript ignore | `String/Array` | ignore the files when load initializer | `Function` | custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path` caseStyle | `String/Function` | set property's case when converting a filepath to property list. From 12307ecb95da6f00e1b2435caed64433e72f638e Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 10:49:38 +0800 Subject: [PATCH 12/20] chore: update comment --- lib/egg.js | 2 +- lib/loader/file_loader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/egg.js b/lib/egg.js index 4e3bd2c0..49172e99 100644 --- a/lib/egg.js +++ b/lib/egg.js @@ -28,7 +28,7 @@ class EggCore extends KoaApplication { * @param {Object} options - options * @param {String} [options.baseDir=process.cwd()] - the directory of application * @param {String} [options.type=application|agent] - whether it's running in app worker or agent worker - * @param {Boolean} [options.typescript] - whether support typescript. + * @param {Boolean} [options.typescript] - whether support typescript * @param {Object} [options.plugins] - custom plugins * @since 1.0.0 */ diff --git a/lib/loader/file_loader.js b/lib/loader/file_loader.js index 8398acad..93b2a3f8 100644 --- a/lib/loader/file_loader.js +++ b/lib/loader/file_loader.js @@ -38,7 +38,7 @@ class FileLoader { * @param {String|Array} options.directory - directories to be loaded * @param {Object} options.target - attach the target object from loaded files * @param {String} options.match - match the files when load, support glob, default to all js files - * @param {Boolean} options.typescript - whether support typescript, default to false. + * @param {Boolean} options.typescript - whether support typescript, default to false * @param {String} options.ignore - ignore the files when load, support glob * @param {Function} options.initializer - custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path` * @param {Boolean} options.call - determine whether invoke when exports is function From 8ce0beb3c2578f5353862feb2c1c71c589f35bdf Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 10:55:54 +0800 Subject: [PATCH 13/20] test: add more unittest for ts --- test/egg-ts.test.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index 59f4db5d..9a8fb4c3 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -61,7 +61,7 @@ describe('test/egg-ts.test.js', () => { app.loader.loadController(); assert(!app.controller.god); - assert(!!app.controller.test); + assert(app.controller.test); }); it('should support load ts,js files', async () => { @@ -71,7 +71,16 @@ describe('test/egg-ts.test.js', () => { }); app.loader.loadService(); - assert(!!app.serviceClasses.lord); - assert(!!app.serviceClasses.test); + assert(app.serviceClasses.lord); + assert(app.serviceClasses.test); + }); + + it('should not load ts files while typescript was false', async () => { + require.extensions['.ts'] = require.extensions['.js']; + app = utils.createApp('egg-ts-js'); + + app.loader.loadService(); + assert(app.serviceClasses.lord); + assert(!app.serviceClasses.test); }); }); From 9b26274607ab8452c2c7318afe2340123549818f Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 14:30:38 +0800 Subject: [PATCH 14/20] refactor: code optimization --- lib/loader/file_loader.js | 4 +++- test/egg-ts.test.js | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/loader/file_loader.js b/lib/loader/file_loader.js index 93b2a3f8..311b5d2f 100644 --- a/lib/loader/file_loader.js +++ b/lib/loader/file_loader.js @@ -50,7 +50,9 @@ class FileLoader { constructor(options) { assert(options.directory, 'options.directory is required'); assert(options.target, 'options.target is required'); - assert(!options.typescript || (options.typescript && require.extensions['.ts']), 'require.extensions should contains .ts while options.typescript was true'); + if (options.typescript) { + assert(require.extensions['.ts'], 'require.extensions should contains .ts while options.typescript was true'); + } this.options = Object.assign({}, defaults, options); // compatible old options _lowercaseFirst_ diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index 9a8fb4c3..3feb4485 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -7,12 +7,15 @@ const utils = require('./utils'); describe('test/egg-ts.test.js', () => { let app; + beforeEach(() => { + require.extensions['.ts'] = require.extensions['.js']; + }); + afterEach(() => { delete require.extensions['.ts']; }); it('should support load ts file', async () => { - require.extensions['.ts'] = require.extensions['.js']; app = utils.createApp('egg-ts', { typescript: true, }); @@ -54,7 +57,6 @@ describe('test/egg-ts.test.js', () => { }); it('should not load d.ts files while typescript was true', async () => { - require.extensions['.ts'] = require.extensions['.js']; app = utils.createApp('egg-ts-js', { typescript: true, }); @@ -65,7 +67,6 @@ describe('test/egg-ts.test.js', () => { }); it('should support load ts,js files', async () => { - require.extensions['.ts'] = require.extensions['.js']; app = utils.createApp('egg-ts-js', { typescript: true, }); @@ -76,7 +77,6 @@ describe('test/egg-ts.test.js', () => { }); it('should not load ts files while typescript was false', async () => { - require.extensions['.ts'] = require.extensions['.js']; app = utils.createApp('egg-ts-js'); app.loader.loadService(); From c37fdb927d55fa4bc0dca1244f1126bc524eca08 Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 14:52:26 +0800 Subject: [PATCH 15/20] chore: update error msg --- lib/loader/file_loader.js | 2 +- test/loader/file_loader.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/loader/file_loader.js b/lib/loader/file_loader.js index 311b5d2f..36f258af 100644 --- a/lib/loader/file_loader.js +++ b/lib/loader/file_loader.js @@ -51,7 +51,7 @@ class FileLoader { assert(options.directory, 'options.directory is required'); assert(options.target, 'options.target is required'); if (options.typescript) { - assert(require.extensions['.ts'], 'require.extensions should contains .ts while options.typescript was true'); + assert(require.extensions['.ts'], '`require.extensions` should contains `.ts` while `options.typescript` was true'); } this.options = Object.assign({}, defaults, options); diff --git a/test/loader/file_loader.test.js b/test/loader/file_loader.test.js index 8a3006dd..d6fa9c41 100644 --- a/test/loader/file_loader.test.js +++ b/test/loader/file_loader.test.js @@ -262,7 +262,7 @@ describe('test/loader/file_loader.test.js', () => { target: mod, typescript: true, }).load(); - }, /require.extensions should contains .ts while options.typescript was true/); + }, /`require.extensions` should contains `.ts` while `options.typescript` was true/); }); describe('caseStyle', () => { From 5363b4a82dd88db89bcb8f77a1e0daa6fbb5e457 Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 14:56:05 +0800 Subject: [PATCH 16/20] test: change beforeEach/afterEach to before/after --- test/egg-ts.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index 3feb4485..0e700f00 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -7,11 +7,11 @@ const utils = require('./utils'); describe('test/egg-ts.test.js', () => { let app; - beforeEach(() => { + before(() => { require.extensions['.ts'] = require.extensions['.js']; }); - afterEach(() => { + after(() => { delete require.extensions['.ts']; }); From 46dc8100786a11b520497871c1d2ed9e31dda9ba Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 15:25:21 +0800 Subject: [PATCH 17/20] feat: add ts check in loadFile --- lib/loader/egg_loader.js | 4 ++++ lib/loader/mixin/extend.js | 3 ++- test/egg-ts.test.js | 2 ++ test/fixtures/egg-ts-js/app/extend/application.ts | 3 +++ 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/egg-ts-js/app/extend/application.ts diff --git a/lib/loader/egg_loader.js b/lib/loader/egg_loader.js index 20b526a7..6ce88416 100644 --- a/lib/loader/egg_loader.js +++ b/lib/loader/egg_loader.js @@ -287,6 +287,10 @@ class EggLoader { return null; } + if (!this.options.typescript && filepath.endsWith('.ts')) { + return null; + } + const ret = utils.loadFile(filepath); // function(arg1, args, ...) {} if (inject.length === 0) inject = [ this.app ]; diff --git a/lib/loader/mixin/extend.js b/lib/loader/mixin/extend.js index 8a9fab4f..86995bfb 100644 --- a/lib/loader/mixin/extend.js +++ b/lib/loader/mixin/extend.js @@ -110,7 +110,8 @@ module.exports = { deprecate(`app/extend/${name}/index.js is deprecated, use app/extend/${name}.js instead`); } - const ext = utils.loadFile(filepath); + const ext = this.loadFile(filepath); + if (!ext) continue; const properties = Object.getOwnPropertyNames(ext) .concat(Object.getOwnPropertySymbols(ext)); diff --git a/test/egg-ts.test.js b/test/egg-ts.test.js index 0e700f00..699ca95d 100644 --- a/test/egg-ts.test.js +++ b/test/egg-ts.test.js @@ -79,7 +79,9 @@ describe('test/egg-ts.test.js', () => { it('should not load ts files while typescript was false', async () => { app = utils.createApp('egg-ts-js'); + app.loader.loadApplicationExtend(); app.loader.loadService(); + assert(!app.appExtend); assert(app.serviceClasses.lord); assert(!app.serviceClasses.test); }); diff --git a/test/fixtures/egg-ts-js/app/extend/application.ts b/test/fixtures/egg-ts-js/app/extend/application.ts new file mode 100644 index 00000000..a867bb33 --- /dev/null +++ b/test/fixtures/egg-ts-js/app/extend/application.ts @@ -0,0 +1,3 @@ +module.exports = { + appExtend: 'hello' +} \ No newline at end of file From 50d2d6ed2000811af3aca1d62c1beafe6ce2a1e4 Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 17:53:40 +0800 Subject: [PATCH 18/20] feat: move resolveModule to egg_loader --- lib/loader/egg_loader.js | 18 ++++++++++++++---- lib/loader/mixin/config.js | 4 ++-- lib/loader/mixin/custom.js | 4 ++-- lib/loader/mixin/extend.js | 3 +-- lib/loader/mixin/plugin.js | 4 ++-- lib/loader/mixin/router.js | 2 +- lib/utils/index.js | 8 -------- 7 files changed, 22 insertions(+), 21 deletions(-) diff --git a/lib/loader/egg_loader.js b/lib/loader/egg_loader.js index 6ce88416..c0b87cc6 100644 --- a/lib/loader/egg_loader.js +++ b/lib/loader/egg_loader.js @@ -287,10 +287,6 @@ class EggLoader { return null; } - if (!this.options.typescript && filepath.endsWith('.ts')) { - return null; - } - const ret = utils.loadFile(filepath); // function(arg1, args, ...) {} if (inject.length === 0) inject = [ this.app ]; @@ -406,6 +402,20 @@ class EggLoader { if (this.serverScope) files.push(`${filename}.${this.serverScope}_${this.serverEnv}`); return files; } + + resolveModule(filepath) { + const useTs = this.options.typescript; + try { + const fullPath = require.resolve(filepath); + if (!useTs && fullPath.endsWith('.ts')) { + return undefined; + } + + return fullPath; + } catch (e) { + return undefined; + } + } } /** diff --git a/lib/loader/mixin/config.js b/lib/loader/mixin/config.js index cf1e4a61..8e8d06fb 100644 --- a/lib/loader/mixin/config.js +++ b/lib/loader/mixin/config.js @@ -70,10 +70,10 @@ module.exports = { const isPlugin = type === 'plugin'; const isApp = type === 'app'; - let filepath = utils.resolveModule(path.join(dirpath, 'config', filename)); + let filepath = this.resolveModule(path.join(dirpath, 'config', filename)); // let config.js compatible if (filename === 'config.default' && !filepath) { - filepath = utils.resolveModule(path.join(dirpath, 'config/config')); + filepath = this.resolveModule(path.join(dirpath, 'config/config')); } const config = this.loadFile(filepath, this.appInfo, extraInject); diff --git a/lib/loader/mixin/custom.js b/lib/loader/mixin/custom.js index e5e08888..fad01f72 100644 --- a/lib/loader/mixin/custom.js +++ b/lib/loader/mixin/custom.js @@ -23,7 +23,7 @@ module.exports = { */ loadCustomApp() { this.getLoadUnits() - .forEach(unit => this.loadFile(utils.resolveModule(path.join(unit.path, 'app')))); + .forEach(unit => this.loadFile(this.resolveModule(path.join(unit.path, 'app')))); }, /** @@ -31,7 +31,7 @@ module.exports = { */ loadCustomAgent() { this.getLoadUnits() - .forEach(unit => this.loadFile(utils.resolveModule(path.join(unit.path, 'agent')))); + .forEach(unit => this.loadFile(this.resolveModule(path.join(unit.path, 'agent')))); }, }; diff --git a/lib/loader/mixin/extend.js b/lib/loader/mixin/extend.js index 86995bfb..b70ce14b 100644 --- a/lib/loader/mixin/extend.js +++ b/lib/loader/mixin/extend.js @@ -102,7 +102,7 @@ module.exports = { const mergeRecord = new Map(); for (let filepath of filepaths) { - filepath = utils.resolveModule(filepath); + filepath = this.resolveModule(filepath); if (!filepath) { continue; } else if (filepath.endsWith('/index.js')) { @@ -111,7 +111,6 @@ module.exports = { } const ext = this.loadFile(filepath); - if (!ext) continue; const properties = Object.getOwnPropertyNames(ext) .concat(Object.getOwnPropertySymbols(ext)); diff --git a/lib/loader/mixin/plugin.js b/lib/loader/mixin/plugin.js index f8693d37..e31446ce 100644 --- a/lib/loader/mixin/plugin.js +++ b/lib/loader/mixin/plugin.js @@ -161,11 +161,11 @@ module.exports = { const plugins = {}; for (const configPath of newConfigPaths) { - let filepath = utils.resolveModule(configPath); + let filepath = this.resolveModule(configPath); // let plugin.js compatible if (configPath.endsWith('plugin.default') && !filepath) { - filepath = utils.resolveModule(configPath.replace(/plugin\.default$/, 'plugin')); + filepath = this.resolveModule(configPath.replace(/plugin\.default$/, 'plugin')); } if (!filepath) { diff --git a/lib/loader/mixin/router.js b/lib/loader/mixin/router.js index 3fbe4771..cf9ea9ba 100644 --- a/lib/loader/mixin/router.js +++ b/lib/loader/mixin/router.js @@ -13,6 +13,6 @@ module.exports = { */ loadRouter() { // 加载 router.js - this.loadFile(utils.resolveModule(path.join(this.options.baseDir, 'app/router'))); + this.loadFile(this.resolveModule(path.join(this.options.baseDir, 'app/router'))); }, }; diff --git a/lib/utils/index.js b/lib/utils/index.js index 3311ec07..d3266470 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -27,14 +27,6 @@ module.exports = { } }, - resolveModule(filepath) { - try { - return require.resolve(filepath); - } catch (e) { - return undefined; - } - }, - methods: [ 'head', 'options', 'get', 'put', 'patch', 'post', 'delete' ], async callFn(fn, args, ctx) { From c51ae2d3c5f4f108de9177156d307e034c342804 Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 17:58:57 +0800 Subject: [PATCH 19/20] fix: lint fix --- lib/loader/mixin/config.js | 1 - lib/loader/mixin/custom.js | 1 - lib/loader/mixin/extend.js | 1 - lib/loader/mixin/plugin.js | 1 - lib/loader/mixin/router.js | 1 - 5 files changed, 5 deletions(-) diff --git a/lib/loader/mixin/config.js b/lib/loader/mixin/config.js index 8e8d06fb..204938a9 100644 --- a/lib/loader/mixin/config.js +++ b/lib/loader/mixin/config.js @@ -4,7 +4,6 @@ const debug = require('debug')('egg-core:config'); const path = require('path'); const extend = require('extend2'); const assert = require('assert'); -const utils = require('../../utils'); const SET_CONFIG_META = Symbol('Loader#setConfigMeta'); diff --git a/lib/loader/mixin/custom.js b/lib/loader/mixin/custom.js index fad01f72..adfd4f92 100644 --- a/lib/loader/mixin/custom.js +++ b/lib/loader/mixin/custom.js @@ -1,7 +1,6 @@ 'use strict'; const path = require('path'); -const utils = require('../../utils'); module.exports = { diff --git a/lib/loader/mixin/extend.js b/lib/loader/mixin/extend.js index b70ce14b..fc24b391 100644 --- a/lib/loader/mixin/extend.js +++ b/lib/loader/mixin/extend.js @@ -3,7 +3,6 @@ const debug = require('debug')('egg-core:extend'); const deprecate = require('depd')('egg'); const path = require('path'); -const utils = require('../../utils'); const originalPrototypes = { request: require('koa/lib/request'), diff --git a/lib/loader/mixin/plugin.js b/lib/loader/mixin/plugin.js index e31446ce..ba563b68 100644 --- a/lib/loader/mixin/plugin.js +++ b/lib/loader/mixin/plugin.js @@ -5,7 +5,6 @@ const path = require('path'); const debug = require('debug')('egg-core:plugin'); const sequencify = require('../../utils/sequencify'); const loadFile = require('../../utils').loadFile; -const utils = require('../../utils'); module.exports = { diff --git a/lib/loader/mixin/router.js b/lib/loader/mixin/router.js index cf9ea9ba..8a95a3b1 100644 --- a/lib/loader/mixin/router.js +++ b/lib/loader/mixin/router.js @@ -1,7 +1,6 @@ 'use strict'; const path = require('path'); -const utils = require('../../utils'); module.exports = { From 8f2c5b39b8f9663fe51eaa947101f1505278a987 Mon Sep 17 00:00:00 2001 From: wanghx Date: Fri, 23 Mar 2018 17:59:13 +0800 Subject: [PATCH 20/20] refactor: code optimization --- lib/loader/egg_loader.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/loader/egg_loader.js b/lib/loader/egg_loader.js index c0b87cc6..753ac112 100644 --- a/lib/loader/egg_loader.js +++ b/lib/loader/egg_loader.js @@ -404,17 +404,18 @@ class EggLoader { } resolveModule(filepath) { - const useTs = this.options.typescript; + let fullPath; try { - const fullPath = require.resolve(filepath); - if (!useTs && fullPath.endsWith('.ts')) { - return undefined; - } - - return fullPath; + fullPath = require.resolve(filepath); } catch (e) { return undefined; } + + if (!this.options.typescript && fullPath.endsWith('.ts')) { + return undefined; + } + + return fullPath; } }