dev.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. 'use strict';
  2. const debug = require('debug')('egg-bin');
  3. const Command = require('../command');
  4. const path = require('path');
  5. const utils = require('egg-utils');
  6. const detect = require('detect-port');
  7. class DevCommand extends Command {
  8. constructor(rawArgv) {
  9. super(rawArgv);
  10. this.usage = 'Usage: egg-bin dev [dir] [options]';
  11. this.defaultPort = 7001;
  12. this.serverBin = path.join(__dirname, '../start-cluster');
  13. this.options = {
  14. baseDir: {
  15. description: 'directory of application, default to `process.cwd()`',
  16. type: 'string',
  17. },
  18. workers: {
  19. description: 'numbers of app workers, default to 1 at local mode',
  20. type: 'number',
  21. alias: [ 'c', 'cluster' ],
  22. default: 1,
  23. },
  24. port: {
  25. description: 'listening port, default to 7001',
  26. type: 'number',
  27. alias: 'p',
  28. },
  29. framework: {
  30. description: 'specify framework that can be absolute path or npm package',
  31. type: 'string',
  32. },
  33. require: {
  34. description: 'will add to execArgv --require',
  35. type: 'array',
  36. alias: 'r',
  37. },
  38. };
  39. }
  40. get description() {
  41. return 'Start server at local dev mode';
  42. }
  43. get context() {
  44. const context = super.context;
  45. const { argv, execArgvObj } = context;
  46. execArgvObj.require = execArgvObj.require || [];
  47. // add require to execArgv
  48. if (argv.require) {
  49. execArgvObj.require.push(...argv.require);
  50. argv.require = undefined;
  51. }
  52. return context;
  53. }
  54. * run(context) {
  55. const devArgs = yield this.formatArgs(context);
  56. const env = {
  57. NODE_ENV: 'development',
  58. EGG_MASTER_CLOSE_TIMEOUT: 1000,
  59. };
  60. const options = {
  61. execArgv: context.execArgv,
  62. env: Object.assign(env, context.env),
  63. };
  64. debug('%s %j %j, %j', this.serverBin, devArgs, options.execArgv, options.env.NODE_ENV);
  65. const task = this.helper.forkNode(this.serverBin, devArgs, options);
  66. this.proc = task.proc;
  67. yield task;
  68. }
  69. /**
  70. * format egg startCluster args then change it to json string style
  71. * @function helper#formatArgs
  72. * @param {Object} context - { cwd, argv }
  73. * @return {Array} pass to start-cluster, [ '{"port":7001,"framework":"egg"}' ]
  74. */
  75. * formatArgs(context) {
  76. const { cwd, argv } = context;
  77. /* istanbul ignore next */
  78. argv.baseDir = argv.baseDir || cwd;
  79. /* istanbul ignore next */
  80. if (!path.isAbsolute(argv.baseDir)) argv.baseDir = path.join(cwd, argv.baseDir);
  81. argv.port = argv.port || argv.p;
  82. argv.framework = utils.getFrameworkPath({
  83. framework: argv.framework,
  84. baseDir: argv.baseDir,
  85. });
  86. // remove unused properties
  87. argv.cluster = undefined;
  88. argv.c = undefined;
  89. argv.p = undefined;
  90. argv._ = undefined;
  91. argv.$0 = undefined;
  92. // auto detect available port
  93. if (!argv.port) {
  94. debug('detect available port');
  95. const port = yield detect(this.defaultPort);
  96. if (port !== this.defaultPort) {
  97. argv.port = port;
  98. console.warn(`[egg-bin] server port ${this.defaultPort} is in use, now using port ${port}\n`);
  99. }
  100. debug(`use available port ${port}`);
  101. }
  102. return [ JSON.stringify(argv) ];
  103. }
  104. }
  105. module.exports = DevCommand;