anywhere 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #!/usr/bin/env node
  2. var os = require('os');
  3. var fs = require('fs');
  4. var path = require('path');
  5. var http = require('http');
  6. var https = require('https');
  7. const { URL } = require('url');
  8. var connect = require('connect');
  9. var serveStatic = require('serve-static');
  10. var serveIndex = require('serve-index');
  11. var fallback = require('connect-history-api-fallback');
  12. var proxy = require('http-proxy-middleware');
  13. var debug = require('debug');
  14. debug.enable('anywhere');
  15. var exec = require('child_process').exec;
  16. var spawn = require('child_process').spawn;
  17. var argv = require("minimist")(process.argv.slice(2), {
  18. alias: {
  19. 'silent': 's',
  20. 'port': 'p',
  21. 'hostname': 'h',
  22. 'dir': 'd',
  23. 'proxy': 'x',
  24. 'log': 'l',
  25. 'fallback': 'f'
  26. },
  27. string: ['port', 'hostname', 'fallback'],
  28. boolean: ['silent', 'log'],
  29. 'default': {
  30. 'port': 8000,
  31. 'dir': process.cwd()
  32. }
  33. });
  34. if (argv.help) {
  35. console.log("Usage:");
  36. console.log(" anywhere --help // print help information");
  37. console.log(" anywhere // 8000 as default port, current folder as root");
  38. console.log(" anywhere 8888 // 8888 as port");
  39. console.log(" anywhere -p 8989 // 8989 as port");
  40. console.log(" anywhere -s // don't open browser");
  41. console.log(" anywhere -h localhost // localhost as hostname");
  42. console.log(" anywhere -d /home // /home as root");
  43. console.log(" anywhere -l // print log");
  44. console.log(" anywhere -f // Enable history fallback");
  45. console.log(" anywhere --proxy http://localhost:7000/api // Support shorthand URL, webpack.config.js or customize config file");
  46. process.exit(0);
  47. }
  48. var openURL = function (url) {
  49. switch (process.platform) {
  50. case "darwin":
  51. exec('open ' + url);
  52. break;
  53. case "win32":
  54. exec('start ' + url);
  55. break;
  56. default:
  57. spawn('xdg-open', [url]);
  58. // I use `spawn` since `exec` fails on my machine (Linux i386).
  59. // I heard that `exec` has memory limitation of buffer size of 512k.
  60. // http://stackoverflow.com/a/16099450/222893
  61. // But I am not sure if this memory limit causes the failure of `exec`.
  62. // `xdg-open` is specified in freedesktop standard, so it should work on
  63. // Linux, *BSD, solaris, etc.
  64. }
  65. };
  66. /**
  67. * Get ip(v4) address
  68. * @return {String} the ipv4 address or 'localhost'
  69. */
  70. var getIPAddress = function () {
  71. var ifaces = os.networkInterfaces();
  72. var ipList = [];
  73. for (var dev in ifaces) {
  74. ifaces[dev].forEach(function (details) {
  75. if (details.family === 'IPv4' && !details.internal) {
  76. ipList.push(details.address);
  77. }
  78. });
  79. }
  80. // Local IP first
  81. ipList.sort(function (ip1, ip2) {
  82. if(ip1.indexOf('192') >= 0){
  83. return -1;
  84. }
  85. return 1;
  86. });
  87. return ipList[0] || "127.0.0.1";
  88. };
  89. var log = debug('anywhere');
  90. var app = connect();
  91. app.use(function (req, res, next) {
  92. res.setHeader("Access-Control-Allow-Origin", "*");
  93. if (argv.log) {
  94. log(req.method + ' ' + req.url);
  95. }
  96. next();
  97. });
  98. if (argv.fallback !== undefined) {
  99. console.log('Enable html5 history mode.');
  100. app.use(fallback({
  101. index: argv.fallback || '/index.html'
  102. }));
  103. }
  104. app.use(serveStatic(argv.dir, { 'index': ['index.html'] }));
  105. app.use(serveIndex(argv.dir, { 'icons': true }));
  106. // anywhere --proxy webpack.config.js
  107. // anywhere --proxy proxy.config.js
  108. // anywhere --proxy http://localhost:7000/api
  109. if (argv.proxy) {
  110. try {
  111. // if url
  112. var url = new URL(argv.proxy);
  113. app.use(proxy(url.toString(), { changeOrigin: true }));
  114. } catch (e) {
  115. // if config file
  116. var config = require(path.resolve(argv.dir, argv.proxy));
  117. // support webpack-dev-server proxy options
  118. try {
  119. config = config.devServer.proxy;
  120. } catch (e) {
  121. if (argv.log) {
  122. log(e);
  123. }
  124. }
  125. var contexts = Object.keys(config);
  126. contexts.forEach(context => {
  127. var options = config[context];
  128. app.use(proxy(context, options));
  129. });
  130. }
  131. }
  132. // anywhere 8888
  133. // anywhere -p 8989
  134. // anywhere 8888 -s // silent
  135. // anywhere -h localhost
  136. // anywhere -d /home
  137. var port = parseInt(argv._[0] || argv.port, 10);
  138. var secure = port + 1;
  139. var hostname = argv.hostname || getIPAddress();
  140. http.createServer(app).listen(port, function () {
  141. // 忽略80端口
  142. port = (port != 80 ? ':' + port : '');
  143. var url = "http://" + hostname + port + '/';
  144. console.log("Running at " + url);
  145. if (!argv.silent) {
  146. openURL(url+'?editor');
  147. openURL(url);
  148. }
  149. });
  150. var options = {
  151. key: fs.readFileSync(path.join(__dirname, '../keys', 'key.pem')),
  152. cert: fs.readFileSync(path.join(__dirname, '../keys', 'cert.pem'))
  153. };
  154. https.createServer(options, app).listen(secure, function () {
  155. secure = (secure != 80 ? ':' + secure : '');
  156. var url = "https://" + hostname + secure + '/';
  157. console.log("Also running at " + url);
  158. });