config.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. 'use strict';
  2. const debug = require('debug')('egg-core:config');
  3. const path = require('path');
  4. const extend = require('extend2');
  5. const assert = require('assert');
  6. const { Console } = require('console');
  7. module.exports = {
  8. /**
  9. * Load config/config.js
  10. *
  11. * Will merge config.default.js 和 config.${env}.js
  12. *
  13. * @function EggLoader#loadConfig
  14. * @since 1.0.0
  15. */
  16. loadConfig() {
  17. this.timing.start('Load Config');
  18. this.configMeta = {};
  19. const target = {};
  20. // Load Application config first
  21. const appConfig = this._preloadAppConfig();
  22. // plugin config.default
  23. // framework config.default
  24. // app config.default
  25. // plugin config.{env}
  26. // framework config.{env}
  27. // app config.{env}
  28. for (const filename of this.getTypeFiles('config')) {
  29. for (const unit of this.getLoadUnits()) {
  30. const isApp = unit.type === 'app';
  31. const config = this._loadConfig(unit.path, filename, isApp ? undefined : appConfig, unit.type);
  32. if (!config) {
  33. continue;
  34. }
  35. debug('Loaded config %s/%s, %j', unit.path, filename, config);
  36. extend(true, target, config);
  37. }
  38. }
  39. // load env from process.env.EGG_APP_CONFIG
  40. const envConfig = this._loadConfigFromEnv();
  41. debug('Loaded config from env, %j', envConfig);
  42. extend(true, target, envConfig);
  43. // You can manipulate the order of app.config.coreMiddleware and app.config.appMiddleware in app.js
  44. target.coreMiddleware = target.coreMiddlewares = target.coreMiddleware || [];
  45. target.appMiddleware = target.appMiddlewares = target.middleware || [];
  46. this.config = target;
  47. this.timing.end('Load Config');
  48. },
  49. _preloadAppConfig() {
  50. const names = [
  51. 'config.default',
  52. `config.${this.serverEnv}`,
  53. ];
  54. const target = {};
  55. for (const filename of names) {
  56. const config = this._loadConfig(this.options.baseDir, filename, undefined, 'app');
  57. extend(true, target, config);
  58. }
  59. return target;
  60. },
  61. _loadConfig(dirpath, filename, extraInject, type) {
  62. const isPlugin = type === 'plugin';
  63. const isApp = type === 'app';
  64. let filepath = this.resolveModule(path.join(dirpath, 'config', filename));
  65. // let config.js compatible
  66. if (filename === 'config.default' && !filepath) {
  67. filepath = this.resolveModule(path.join(dirpath, 'config/config'));
  68. }
  69. const config = this.loadFile(filepath, this.appInfo, extraInject);
  70. if (!config) return null;
  71. if (isPlugin || isApp) {
  72. assert(!config.coreMiddleware, 'Can not define coreMiddleware in app or plugin');
  73. }
  74. if (!isApp) {
  75. assert(!config.middleware, 'Can not define middleware in ' + filepath);
  76. }
  77. // store config meta, check where is the property of config come from.
  78. this._setConfigMeta(config, filepath);
  79. return config;
  80. },
  81. _loadConfigFromEnv() {
  82. const envConfigStr = process.env.EGG_APP_CONFIG;
  83. if (!envConfigStr) return;
  84. try {
  85. const envConfig = JSON.parse(envConfigStr);
  86. this._setConfigMeta(envConfig, '<process.env.EGG_APP_CONFIG>');
  87. return envConfig;
  88. } catch (err) {
  89. this.options.logger.warn('[egg-loader] process.env.EGG_APP_CONFIG is not invalid JSON: %s', envConfigStr);
  90. }
  91. },
  92. _setConfigMeta(config, filepath) {
  93. config = extend(true, {}, config);
  94. setConfig(config, filepath);
  95. extend(true, this.configMeta, config);
  96. },
  97. };
  98. function setConfig(obj, filepath) {
  99. for (const key of Object.keys(obj)) {
  100. const val = obj[key];
  101. // ignore console
  102. if (key === 'console' && val && typeof val.Console === 'function' && val.Console === Console) {
  103. obj[key] = filepath;
  104. continue;
  105. }
  106. if (val && Object.getPrototypeOf(val) === Object.prototype && Object.keys(val).length > 0) {
  107. setConfig(val, filepath);
  108. continue;
  109. }
  110. obj[key] = filepath;
  111. }
  112. }