serve.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. "use strict";
  2. const inquirer = require("inquirer");
  3. const path = require("path");
  4. const chalk = require("chalk");
  5. const spawn = require("cross-spawn");
  6. const List = require("webpack-addons").List;
  7. const processPromise = require("../utils/resolve-packages").processPromise;
  8. /**
  9. *
  10. * Installs WDS using NPM with --save --dev etc
  11. *
  12. * @param {Object} cmd - arg to spawn with
  13. * @returns {Void}
  14. */
  15. const spawnNPMWithArg = cmd =>
  16. spawn.sync("npm", ["install", "webpack-dev-server", cmd], {
  17. stdio: "inherit"
  18. });
  19. /**
  20. *
  21. * Installs WDS using Yarn with add etc
  22. *
  23. * @param {Object} cmd - arg to spawn with
  24. * @returns {Void}
  25. */
  26. const spawnYarnWithArg = cmd =>
  27. spawn.sync("yarn", ["add", "webpack-dev-server", cmd], {
  28. stdio: "inherit"
  29. });
  30. /**
  31. *
  32. * Find the path of a given module
  33. *
  34. * @param {Object} dep - dependency to find
  35. * @returns {String} string with given path
  36. */
  37. const getRootPathModule = dep => path.resolve(process.cwd(), dep);
  38. /**
  39. *
  40. * Prompts for installing the devServer and running it
  41. *
  42. * @param {Object} args - args processed from the CLI
  43. * @returns {Function} invokes the devServer API
  44. */
  45. function serve() {
  46. let packageJSONPath = getRootPathModule("package.json");
  47. if (!packageJSONPath) {
  48. console.log(
  49. "\n",
  50. chalk.red("✖ Could not find your package.json file"),
  51. "\n"
  52. );
  53. process.exit(1);
  54. }
  55. let packageJSON = require(packageJSONPath);
  56. /*
  57. * We gotta do this, cause some configs might not have devdep,
  58. * dep or optional dep, so we'd need sanity checks for each
  59. */
  60. let hasDevServerDep = packageJSON
  61. ? Object.keys(packageJSON).filter(p => packageJSON[p]["webpack-dev-server"])
  62. : [];
  63. if (hasDevServerDep.length) {
  64. let WDSPath = getRootPathModule(
  65. "node_modules/webpack-dev-server/bin/webpack-dev-server.js"
  66. );
  67. if (!WDSPath) {
  68. console.log(
  69. "\n",
  70. chalk.red(
  71. "✖ Could not find the webpack-dev-server dependency in node_modules root path"
  72. )
  73. );
  74. console.log(
  75. chalk.bold.green(" ✔︎"),
  76. "Try this command:",
  77. chalk.bold.green("rm -rf node_modules && npm install")
  78. );
  79. process.exit(1);
  80. }
  81. return require(WDSPath);
  82. } else {
  83. process.stdout.write(
  84. "\n" +
  85. chalk.bold(
  86. "✖ We didn't find any webpack-dev-server dependency in your project,"
  87. ) +
  88. "\n" +
  89. chalk.bold.green(" 'webpack serve'") +
  90. " " +
  91. chalk.bold("requires you to have it installed ") +
  92. "\n\n"
  93. );
  94. return inquirer
  95. .prompt([
  96. {
  97. type: "confirm",
  98. name: "confirmDevserver",
  99. message: "Do you want to install it? (default: Y)",
  100. default: "Y"
  101. }
  102. ])
  103. .then(answer => {
  104. if (answer["confirmDevserver"]) {
  105. return inquirer
  106. .prompt(
  107. List(
  108. "confirmDepType",
  109. "What kind of dependency do you want it to be under? (default: devDependency)",
  110. ["devDependency", "optionalDependency", "dependency"]
  111. )
  112. )
  113. .then(depTypeAns => {
  114. const packager = getRootPathModule("package-lock.json")
  115. ? "npm"
  116. : "yarn";
  117. let spawnAction;
  118. if (depTypeAns["confirmDepType"] === "devDependency") {
  119. if (packager === "yarn") {
  120. spawnAction = _ => spawnYarnWithArg("--dev");
  121. } else {
  122. spawnAction = _ => spawnNPMWithArg("--save-dev");
  123. }
  124. }
  125. if (depTypeAns["confirmDepType"] === "dependency") {
  126. if (packager === "yarn") {
  127. spawnAction = _ => spawnYarnWithArg(" ");
  128. } else {
  129. spawnAction = _ => spawnNPMWithArg("--save");
  130. }
  131. }
  132. if (depTypeAns["confirmDepType"] === "optionalDependency") {
  133. if (packager === "yarn") {
  134. spawnAction = _ => spawnYarnWithArg("--optional");
  135. } else {
  136. spawnAction = _ => spawnNPMWithArg("--save-optional");
  137. }
  138. }
  139. return processPromise(spawnAction()).then(_ => {
  140. // Recursion doesn't work well with require call being cached
  141. delete require.cache[require.resolve(packageJSONPath)];
  142. return serve();
  143. });
  144. });
  145. } else {
  146. console.log(chalk.bold.red("✖ Serve aborted due cancelling"));
  147. process.exitCode = 1;
  148. }
  149. })
  150. .catch(err => {
  151. console.log(chalk.red("✖ Serve aborted due to some errors"));
  152. console.error(err);
  153. process.exitCode = 1;
  154. });
  155. }
  156. }
  157. module.exports = {
  158. serve,
  159. getRootPathModule,
  160. spawnNPMWithArg,
  161. spawnYarnWithArg
  162. };