diff --git a/lib/loader/egg_loader.js b/lib/loader/egg_loader.js index f60a78f9..c82b86f1 100644 --- a/lib/loader/egg_loader.js +++ b/lib/loader/egg_loader.js @@ -78,6 +78,12 @@ class EggLoader { * @since 1.0.0 */ this.appInfo = this.getAppInfo(); + + /** + * @member {String} EggLoader#serverScope + * @see AppInfo#serverScope + */ + this.serverScope = this.getServerScope(); } /** @@ -112,6 +118,15 @@ class EggLoader { return serverEnv; } + /** + * Get {@link AppInfo#scope} + * @return {String} serverScope + * @private + */ + getServerScope() { + return process.env.EGG_SERVER_SCOPE || ''; + } + /** * Get {@link AppInfo#name} * @return {String} appname @@ -144,6 +159,7 @@ class EggLoader { */ getAppInfo() { const env = this.serverEnv; + const scope = this.serverScope; const home = this.getHomedir(); const baseDir = this.options.baseDir; @@ -183,6 +199,11 @@ class EggLoader { */ env, + /** + * @member {String} AppInfo#scope + */ + scope, + /** * The use directory, same as `process.env.HOME` * @member {String} AppInfo#HOME @@ -366,6 +387,15 @@ class EggLoader { return ContextLoader; } + getTypeFiles(filename) { + const files = [ `${filename}.default.js` ]; + if (this.serverScope) files.push(`${filename}.${this.serverScope}.js`); + if (this.serverEnv === 'default') return files; + + files.push(`${filename}.${this.serverEnv}.js`); + if (this.serverScope) files.push(`${filename}.${this.serverScope}_${this.serverEnv}.js`); + return files; + } } /** diff --git a/lib/loader/mixin/config.js b/lib/loader/mixin/config.js index 736ad88a..0d4c25b0 100644 --- a/lib/loader/mixin/config.js +++ b/lib/loader/mixin/config.js @@ -23,11 +23,6 @@ module.exports = { const target = {}; - const names = [ - 'config.default.js', - `config.${this.serverEnv}.js`, - ]; - // Load Application config first const appConfig = this._preloadAppConfig(); @@ -37,7 +32,7 @@ module.exports = { // plugin config.{env} // framework config.{env} // app config.{env} - for (const filename of names) { + for (const filename of this.getTypeFiles('config')) { for (const unit of this.getLoadUnits()) { const isApp = unit.type === 'app'; const config = this._loadConfig(unit.path, filename, isApp ? undefined : appConfig, unit.type); diff --git a/lib/loader/mixin/plugin.js b/lib/loader/mixin/plugin.js index 933cfa9b..de531701 100644 --- a/lib/loader/mixin/plugin.js +++ b/lib/loader/mixin/plugin.js @@ -152,17 +152,21 @@ module.exports = { configPaths = [ configPaths ]; } - // read plugin.default.js and plugins.${env}.js - if (this.serverEnv !== 'default') { - // note: can't use for-of - for (let i = 0, l = configPaths.length; i < l; i++) { - const configPath = configPaths[i]; - configPaths.push(configPath.replace(/plugin\.default\.js$/, `plugin.${this.serverEnv}.js`)); + // Get all plugin configurations + // plugin.default.js + // plugin.${scope}.js + // plugin.${env}.js + // plugin.${scope}_${env}.js + const newConfigPaths = []; + for (const filename of this.getTypeFiles('plugin')) { + for (let configPath of configPaths) { + configPath = path.join(path.dirname(configPath), filename); + newConfigPaths.push(configPath); } } const plugins = {}; - for (let configPath of configPaths) { + for (let configPath of newConfigPaths) { // let plugin.js compatible if (configPath.endsWith('plugin.default.js') && !fs.existsSync(configPath)) { configPath = configPath.replace(/plugin\.default\.js$/, 'plugin.js'); diff --git a/test/fixtures/scope-env/config/config.default.js b/test/fixtures/scope-env/config/config.default.js new file mode 100644 index 00000000..ab33cf12 --- /dev/null +++ b/test/fixtures/scope-env/config/config.default.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + from: 'default', +}; diff --git a/test/fixtures/scope-env/config/config.en.js b/test/fixtures/scope-env/config/config.en.js new file mode 100644 index 00000000..425190fe --- /dev/null +++ b/test/fixtures/scope-env/config/config.en.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + from: 'en', +}; diff --git a/test/fixtures/scope-env/config/config.en_prod.js b/test/fixtures/scope-env/config/config.en_prod.js new file mode 100644 index 00000000..3acf3d4c --- /dev/null +++ b/test/fixtures/scope-env/config/config.en_prod.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + from: 'en_prod', +}; diff --git a/test/fixtures/scope-env/config/config.prod.js b/test/fixtures/scope-env/config/config.prod.js new file mode 100644 index 00000000..9c73a419 --- /dev/null +++ b/test/fixtures/scope-env/config/config.prod.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + from: 'prod', +}; diff --git a/test/fixtures/scope-env/config/plugin.en.js b/test/fixtures/scope-env/config/plugin.en.js new file mode 100644 index 00000000..4fa5a117 --- /dev/null +++ b/test/fixtures/scope-env/config/plugin.en.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = { + a: { + enable: false, + package: 'a', + }, + b: { + enable: true, + package: 'b', + }, +}; diff --git a/test/fixtures/scope-env/config/plugin.en_prod.js b/test/fixtures/scope-env/config/plugin.en_prod.js new file mode 100644 index 00000000..d315e6ff --- /dev/null +++ b/test/fixtures/scope-env/config/plugin.en_prod.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = { + c: false, + d: { + enable: true, + package: 'd', + } +}; diff --git a/test/fixtures/scope-env/config/plugin.js b/test/fixtures/scope-env/config/plugin.js new file mode 100644 index 00000000..efe2bc00 --- /dev/null +++ b/test/fixtures/scope-env/config/plugin.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + a: { + enable: true, + package: 'a', + }, +}; diff --git a/test/fixtures/scope-env/config/plugin.prod.js b/test/fixtures/scope-env/config/plugin.prod.js new file mode 100644 index 00000000..54f24882 --- /dev/null +++ b/test/fixtures/scope-env/config/plugin.prod.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = { + b: false, + c: { + enable: true, + package: 'c', + }, +}; diff --git a/test/fixtures/scope-env/node_modules/a/package.json b/test/fixtures/scope-env/node_modules/a/package.json new file mode 100644 index 00000000..0993be8f --- /dev/null +++ b/test/fixtures/scope-env/node_modules/a/package.json @@ -0,0 +1,5 @@ +{ + "eggPlugin": { + "name": "a" + } +} diff --git a/test/fixtures/scope-env/node_modules/b/package.json b/test/fixtures/scope-env/node_modules/b/package.json new file mode 100644 index 00000000..2df18dea --- /dev/null +++ b/test/fixtures/scope-env/node_modules/b/package.json @@ -0,0 +1,5 @@ +{ + "eggPlugin": { + "name": "c" + } +} diff --git a/test/fixtures/scope-env/node_modules/c/package.json b/test/fixtures/scope-env/node_modules/c/package.json new file mode 100644 index 00000000..0993be8f --- /dev/null +++ b/test/fixtures/scope-env/node_modules/c/package.json @@ -0,0 +1,5 @@ +{ + "eggPlugin": { + "name": "a" + } +} diff --git a/test/fixtures/scope-env/package.json b/test/fixtures/scope-env/package.json new file mode 100644 index 00000000..60a3d7b7 --- /dev/null +++ b/test/fixtures/scope-env/package.json @@ -0,0 +1,3 @@ +{ + "name": "scope" +} diff --git a/test/fixtures/scope/config/plugin.en.js b/test/fixtures/scope/config/plugin.en.js new file mode 100644 index 00000000..c6e58ebd --- /dev/null +++ b/test/fixtures/scope/config/plugin.en.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + a: false, +}; diff --git a/test/fixtures/scope/config/plugin.js b/test/fixtures/scope/config/plugin.js new file mode 100644 index 00000000..efe2bc00 --- /dev/null +++ b/test/fixtures/scope/config/plugin.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + a: { + enable: true, + package: 'a', + }, +}; diff --git a/test/fixtures/scope/node_modules/a/package.json b/test/fixtures/scope/node_modules/a/package.json new file mode 100644 index 00000000..0993be8f --- /dev/null +++ b/test/fixtures/scope/node_modules/a/package.json @@ -0,0 +1,5 @@ +{ + "eggPlugin": { + "name": "a" + } +} diff --git a/test/fixtures/scope/package.json b/test/fixtures/scope/package.json new file mode 100644 index 00000000..60a3d7b7 --- /dev/null +++ b/test/fixtures/scope/package.json @@ -0,0 +1,3 @@ +{ + "name": "scope" +} diff --git a/test/loader/mixin/load_config.test.js b/test/loader/mixin/load_config.test.js index 3bc9250e..7a6b56b3 100644 --- a/test/loader/mixin/load_config.test.js +++ b/test/loader/mixin/load_config.test.js @@ -2,12 +2,14 @@ const path = require('path'); const assert = require('assert'); +const mm = require('mm'); const utils = require('../../utils'); const Application = require('../../..').EggCore; describe('test/loader/mixin/load_config.test.js', () => { let app; afterEach(() => app.close()); + afterEach(mm.restore); it('should load application config overriding default of egg', () => { app = utils.createApp('config'); @@ -144,4 +146,43 @@ describe('test/loader/mixin/load_config.test.js', () => { assert(!configMeta.urllib.bar); }); + describe('get config with scope', () => { + it('should return without scope when env = default', function* () { + mm(process.env, 'EGG_SERVER_ENV', 'default'); + app = utils.createApp('scope-env'); + const loader = app.loader; + loader.loadPlugin(); + app.loader.loadConfig(); + assert(loader.config.from === 'default'); + }); + + it('should return without scope when env = prod', function* () { + mm(process.env, 'EGG_SERVER_ENV', 'prod'); + app = utils.createApp('scope-env'); + const loader = app.loader; + loader.loadPlugin(); + app.loader.loadConfig(); + assert(loader.config.from === 'prod'); + }); + + it('should return with scope when env = default', function* () { + mm(process.env, 'EGG_SERVER_ENV', 'default'); + mm(process.env, 'EGG_SERVER_SCOPE', 'en'); + app = utils.createApp('scope-env'); + const loader = app.loader; + loader.loadPlugin(); + app.loader.loadConfig(); + assert(loader.config.from === 'en'); + }); + + it('should return with scope when env = prod', function* () { + mm(process.env, 'EGG_SERVER_ENV', 'prod'); + mm(process.env, 'EGG_SERVER_SCOPE', 'en'); + app = utils.createApp('scope-env'); + const loader = app.loader; + loader.loadPlugin(); + app.loader.loadConfig(); + assert(loader.config.from === 'en_prod'); + }); + }); }); diff --git a/test/loader/mixin/load_plugin.test.js b/test/loader/mixin/load_plugin.test.js index 99d386f6..e37abcb0 100644 --- a/test/loader/mixin/load_plugin.test.js +++ b/test/loader/mixin/load_plugin.test.js @@ -493,4 +493,35 @@ describe('test/load_plugin.test.js', function() { ]); }); + it('should load plugin from scope', () => { + mm(process.env, 'EGG_SERVER_SCOPE', 'en'); + app = utils.createApp('scope'); + const loader = app.loader; + loader.loadPlugin(); + assert(loader.allPlugins.a.enable === false); + }); + + it('should load plugin from scope and default env', () => { + mm(process.env, 'EGG_SERVER_ENV', 'default'); + mm(process.env, 'EGG_SERVER_SCOPE', 'en'); + app = utils.createApp('scope-env'); + const loader = app.loader; + loader.loadPlugin(); + assert(loader.allPlugins.a.enable === false); + assert(loader.allPlugins.b.enable === true); + assert(!loader.allPlugins.c); + assert(!loader.allPlugins.d); + }); + + it('should load plugin from scope and prod env', () => { + mm(process.env, 'EGG_SERVER_ENV', 'prod'); + mm(process.env, 'EGG_SERVER_SCOPE', 'en'); + app = utils.createApp('scope-env'); + const loader = app.loader; + loader.loadPlugin(); + assert(loader.allPlugins.a.enable === false); + assert(loader.allPlugins.b.enable === false); + assert(loader.allPlugins.c.enable === false); + assert(loader.allPlugins.d.enable === true); + }); });