async.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. "use strict";
  2. var _ = require("./lodash.custom");
  3. var Immutable = require("immutable");
  4. var utils = require("./utils");
  5. var pluginUtils = require("./plugins");
  6. var connectUtils = require("./connect-utils");
  7. module.exports = {
  8. /**
  9. * BrowserSync needs at least 1 free port.
  10. * It will check the one provided in config
  11. * and keep incrementing until an available one is found.
  12. * @param {BrowserSync} bs
  13. * @param {Function} done
  14. */
  15. getEmptyPort: function (bs, done) {
  16. utils.getPorts(bs.options, function (err, port) {
  17. if (err) {
  18. return utils.fail(true, err, bs.cb);
  19. }
  20. bs.debug("Found a free port: {magenta:%s", port);
  21. done(null, {
  22. options: {
  23. port: port
  24. }
  25. });
  26. });
  27. },
  28. /**
  29. * If the running mode is proxy, we'll use a separate port
  30. * for the Browsersync web-socket server. This is to eliminate any issues
  31. * with trying to proxy web sockets through to the users server.
  32. * @param bs
  33. * @param done
  34. */
  35. getExtraPortForProxy: function (bs, done) {
  36. /**
  37. * An extra port is not needed in snippet/server mode
  38. */
  39. if (bs.options.get("mode") !== "proxy") {
  40. return done();
  41. }
  42. /**
  43. * Web socket support is disabled by default
  44. */
  45. if (!bs.options.getIn(["proxy", "ws"])) {
  46. return done();
  47. }
  48. /**
  49. * Use 1 higher than server port by default...
  50. */
  51. var socketPort = bs.options.get("port") + 1;
  52. /**
  53. * Or use the user-defined socket.port option instead
  54. */
  55. if (bs.options.hasIn(["socket", "port"])) {
  56. socketPort = bs.options.getIn(["socket", "port"]);
  57. }
  58. utils.getPort(bs.options.get("listen", "localhost"), socketPort, null, function (err, port) {
  59. if (err) {
  60. return utils.fail(true, err, bs.cb);
  61. }
  62. done(null, {
  63. optionsIn: [
  64. {
  65. path: ["socket", "port"],
  66. value: port
  67. }
  68. ]
  69. });
  70. });
  71. },
  72. /**
  73. * Some features require an internet connection.
  74. * If the user did not provide either `true` or `false`
  75. * for the online option, we will attempt to resolve www.google.com
  76. * as a way of determining network connectivity
  77. * @param {BrowserSync} bs
  78. * @param {Function} done
  79. */
  80. getOnlineStatus: function (bs, done) {
  81. if (_.isUndefined(bs.options.get("online")) &&
  82. _.isUndefined(process.env.TESTING)) {
  83. require("dns").resolve("www.google.com", function (err) {
  84. var online = false;
  85. if (err) {
  86. bs.debug("Could not resolve www.google.com, setting {magenta:online: false}");
  87. }
  88. else {
  89. bs.debug("Resolved www.google.com, setting {magenta:online: true}");
  90. online = true;
  91. }
  92. done(null, {
  93. options: {
  94. online: online
  95. }
  96. });
  97. });
  98. }
  99. else {
  100. done();
  101. }
  102. },
  103. /**
  104. * Try to load plugins that were given in options
  105. * @param {BrowserSync} bs
  106. * @param {Function} done
  107. */
  108. resolveInlineUserPlugins: function (bs, done) {
  109. var plugins = bs.options
  110. .get("plugins")
  111. .map(pluginUtils.resolvePlugin)
  112. .map(pluginUtils.requirePlugin);
  113. plugins.forEach(function (plugin) {
  114. if (plugin.get("errors").size) {
  115. return logPluginError(plugin);
  116. }
  117. var jsPlugin = plugin.toJS();
  118. jsPlugin.options = jsPlugin.options || {};
  119. jsPlugin.options.moduleName = jsPlugin.moduleName;
  120. bs.registerPlugin(jsPlugin.module, jsPlugin.options);
  121. });
  122. function logPluginError(plugin) {
  123. utils.fail(true, plugin.getIn(["errors", 0]), bs.cb);
  124. }
  125. done();
  126. },
  127. /**
  128. *
  129. * @param {BrowserSync} bs
  130. * @param {Function} done
  131. */
  132. setOptions: function (bs, done) {
  133. done(null, {
  134. options: {
  135. urls: utils.getUrlOptions(bs.options),
  136. snippet: connectUtils.enabled(bs.options)
  137. ? connectUtils.scriptTags(bs.options)
  138. : false,
  139. scriptPaths: Immutable.fromJS(connectUtils.clientScript(bs.options, true)),
  140. files: bs.pluginManager.hook("files:watch", bs.options.get("files"), bs.pluginManager.pluginOptions)
  141. }
  142. });
  143. },
  144. /**
  145. * @param {BrowserSync} bs
  146. * @param {Function} done
  147. */
  148. setInternalEvents: function (bs, done) {
  149. require("./internal-events")(bs);
  150. done();
  151. },
  152. /**
  153. * @param {BrowserSync} bs
  154. * @param {Function} done
  155. */
  156. setFileWatchers: function (bs, done) {
  157. done(null, {
  158. instance: {
  159. watchers: bs.pluginManager.get("file:watcher")(bs)
  160. }
  161. });
  162. },
  163. /**
  164. * @param {BrowserSync} bs
  165. * @param {Function} done
  166. */
  167. mergeMiddlewares: function (bs, done) {
  168. done(null, {
  169. options: {
  170. middleware: bs.pluginManager.hook("server:middleware", bs.options.get("middleware"))
  171. }
  172. });
  173. },
  174. /**
  175. * @param {BrowserSync} bs
  176. * @param {Function} done
  177. */
  178. startServer: function (bs, done) {
  179. var server = bs.pluginManager.get("server")(bs);
  180. done(null, {
  181. instance: {
  182. server: server.server,
  183. app: server.app
  184. }
  185. });
  186. },
  187. /**
  188. * @param {BrowserSync} bs
  189. * @param {Function} done
  190. */
  191. startTunnel: function (bs, done) {
  192. if (bs.options.get("tunnel") && bs.options.get("online")) {
  193. var localTunnel = require("./tunnel");
  194. localTunnel(bs, function (err, tunnel) {
  195. if (err) {
  196. return done(err);
  197. }
  198. else {
  199. return done(null, {
  200. optionsIn: [
  201. {
  202. path: ["urls", "tunnel"],
  203. value: tunnel.url
  204. }
  205. ],
  206. instance: {
  207. tunnel: tunnel
  208. }
  209. });
  210. }
  211. });
  212. }
  213. else {
  214. done();
  215. }
  216. },
  217. /**
  218. * @param {BrowserSync} bs
  219. * @param {Function} done
  220. */
  221. startSockets: function (bs, done) {
  222. var clientEvents = bs.pluginManager.hook("client:events", bs.options.get("clientEvents").toJS());
  223. // Start the socket, needs an existing server.
  224. var io = bs.pluginManager.get("socket")(bs.server, clientEvents, bs);
  225. done(null, {
  226. instance: {
  227. io: io
  228. },
  229. options: {
  230. clientEvents: Immutable.fromJS(clientEvents)
  231. }
  232. });
  233. },
  234. /**
  235. *
  236. * @param {BrowserSync} bs
  237. * @param {Function} done
  238. */
  239. startUi: function (bs, done) {
  240. var PLUGIN_NAME = "UI";
  241. var userPlugins = bs.getUserPlugins();
  242. var ui = bs.pluginManager.get(PLUGIN_NAME);
  243. var uiOpts = bs.options.get("ui");
  244. if (!uiOpts || uiOpts.get("enabled") === false) {
  245. return done();
  246. }
  247. // if user provided a UI, use it instead
  248. if (userPlugins.some(function (item) {
  249. return item.name === PLUGIN_NAME;
  250. })) {
  251. uiOpts = bs.options
  252. .get("ui")
  253. .mergeDeep(Immutable.fromJS(bs.pluginManager.pluginOptions[PLUGIN_NAME]));
  254. }
  255. /**
  256. * Append the 'listen' option
  257. */
  258. const opts = uiOpts.update(uiOpts => {
  259. const listen = bs.options.get("listen");
  260. if (listen) {
  261. return uiOpts.set("listen", listen);
  262. }
  263. return uiOpts;
  264. });
  265. return ui(opts.toJS(), bs, function (err, ui) {
  266. if (err) {
  267. return done(err);
  268. }
  269. done(null, {
  270. instance: {
  271. ui: ui
  272. }
  273. });
  274. });
  275. },
  276. /**
  277. * @param {BrowserSync} bs
  278. * @param {Function} done
  279. */
  280. mergeUiSettings: function (bs, done) {
  281. if (!bs.ui) {
  282. return done();
  283. }
  284. done(null, {
  285. options: {
  286. urls: bs.options.get("urls").merge(bs.ui.options.get("urls"))
  287. }
  288. });
  289. },
  290. /**
  291. * @param {BrowserSync} bs
  292. * @param {Function} done
  293. */
  294. initUserPlugins: function (bs, done) {
  295. bs.pluginManager.initUserPlugins(bs);
  296. done(null, {
  297. options: {
  298. userPlugins: bs.getUserPlugins()
  299. }
  300. });
  301. }
  302. };
  303. //# sourceMappingURL=async.js.map