webpack.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. #!/usr/bin/env node
  2. /*
  3. MIT License http://www.opensource.org/licenses/mit-license.php
  4. Author Tobias Koppers @sokra
  5. */
  6. var path = require("path");
  7. // Local version replace global one
  8. try {
  9. var localWebpack = require.resolve(path.join(process.cwd(), "node_modules", "webpack", "bin", "webpack.js"));
  10. if(__filename !== localWebpack) {
  11. return require(localWebpack);
  12. }
  13. } catch(e) {}
  14. var yargs = require("yargs")
  15. .usage("webpack " + require("../package.json").version + "\n" +
  16. "Usage: https://webpack.js.org/api/cli/\n" +
  17. "Usage without config file: webpack <entry> [<entry>] <output>\n" +
  18. "Usage with config file: webpack");
  19. require("./config-yargs")(yargs);
  20. var DISPLAY_GROUP = "Stats options:";
  21. var BASIC_GROUP = "Basic options:";
  22. yargs.options({
  23. "json": {
  24. type: "boolean",
  25. alias: "j",
  26. describe: "Prints the result as JSON."
  27. },
  28. "progress": {
  29. type: "boolean",
  30. describe: "Print compilation progress in percentage",
  31. group: BASIC_GROUP
  32. },
  33. "color": {
  34. type: "boolean",
  35. alias: "colors",
  36. default: function supportsColor() {
  37. return require("supports-color");
  38. },
  39. group: DISPLAY_GROUP,
  40. describe: "Enables/Disables colors on the console"
  41. },
  42. "sort-modules-by": {
  43. type: "string",
  44. group: DISPLAY_GROUP,
  45. describe: "Sorts the modules list by property in module"
  46. },
  47. "sort-chunks-by": {
  48. type: "string",
  49. group: DISPLAY_GROUP,
  50. describe: "Sorts the chunks list by property in chunk"
  51. },
  52. "sort-assets-by": {
  53. type: "string",
  54. group: DISPLAY_GROUP,
  55. describe: "Sorts the assets list by property in asset"
  56. },
  57. "hide-modules": {
  58. type: "boolean",
  59. group: DISPLAY_GROUP,
  60. describe: "Hides info about modules"
  61. },
  62. "display-exclude": {
  63. type: "string",
  64. group: DISPLAY_GROUP,
  65. describe: "Exclude modules in the output"
  66. },
  67. "display-modules": {
  68. type: "boolean",
  69. group: DISPLAY_GROUP,
  70. describe: "Display even excluded modules in the output"
  71. },
  72. "display-max-modules": {
  73. type: "number",
  74. group: DISPLAY_GROUP,
  75. describe: "Sets the maximum number of visible modules in output"
  76. },
  77. "display-chunks": {
  78. type: "boolean",
  79. group: DISPLAY_GROUP,
  80. describe: "Display chunks in the output"
  81. },
  82. "display-entrypoints": {
  83. type: "boolean",
  84. group: DISPLAY_GROUP,
  85. describe: "Display entry points in the output"
  86. },
  87. "display-origins": {
  88. type: "boolean",
  89. group: DISPLAY_GROUP,
  90. describe: "Display origins of chunks in the output"
  91. },
  92. "display-cached": {
  93. type: "boolean",
  94. group: DISPLAY_GROUP,
  95. describe: "Display also cached modules in the output"
  96. },
  97. "display-cached-assets": {
  98. type: "boolean",
  99. group: DISPLAY_GROUP,
  100. describe: "Display also cached assets in the output"
  101. },
  102. "display-reasons": {
  103. type: "boolean",
  104. group: DISPLAY_GROUP,
  105. describe: "Display reasons about module inclusion in the output"
  106. },
  107. "display-depth": {
  108. type: "boolean",
  109. group: DISPLAY_GROUP,
  110. describe: "Display distance from entry point for each module"
  111. },
  112. "display-used-exports": {
  113. type: "boolean",
  114. group: DISPLAY_GROUP,
  115. describe: "Display information about used exports in modules (Tree Shaking)"
  116. },
  117. "display-provided-exports": {
  118. type: "boolean",
  119. group: DISPLAY_GROUP,
  120. describe: "Display information about exports provided from modules"
  121. },
  122. "display-error-details": {
  123. type: "boolean",
  124. group: DISPLAY_GROUP,
  125. describe: "Display details about errors"
  126. },
  127. "verbose": {
  128. type: "boolean",
  129. group: DISPLAY_GROUP,
  130. describe: "Show more details"
  131. }
  132. });
  133. var argv = yargs.argv;
  134. if(argv.verbose) {
  135. argv["display-reasons"] = true;
  136. argv["display-depth"] = true;
  137. argv["display-entrypoints"] = true;
  138. argv["display-used-exports"] = true;
  139. argv["display-provided-exports"] = true;
  140. argv["display-error-details"] = true;
  141. argv["display-modules"] = true;
  142. argv["display-cached"] = true;
  143. argv["display-cached-assets"] = true;
  144. }
  145. var options = require("./convert-argv")(yargs, argv);
  146. function ifArg(name, fn, init) {
  147. if(Array.isArray(argv[name])) {
  148. if(init) init();
  149. argv[name].forEach(fn);
  150. } else if(typeof argv[name] !== "undefined") {
  151. if(init) init();
  152. fn(argv[name], -1);
  153. }
  154. }
  155. function processOptions(options) {
  156. // process Promise
  157. if(typeof options.then === "function") {
  158. options.then(processOptions).catch(function(err) {
  159. console.error(err.stack || err);
  160. process.exit(1); // eslint-disable-line
  161. });
  162. return;
  163. }
  164. var firstOptions = [].concat(options)[0];
  165. var statsPresetToOptions = require("../lib/Stats.js").presetToOptions;
  166. var outputOptions = options.stats;
  167. if(typeof outputOptions === "boolean" || typeof outputOptions === "string") {
  168. outputOptions = statsPresetToOptions(outputOptions);
  169. } else if(!outputOptions) {
  170. outputOptions = {};
  171. }
  172. outputOptions = Object.create(outputOptions);
  173. if(Array.isArray(options) && !outputOptions.children) {
  174. outputOptions.children = options.map(o => o.stats);
  175. }
  176. if(typeof outputOptions.context === "undefined")
  177. outputOptions.context = firstOptions.context;
  178. ifArg("json", function(bool) {
  179. if(bool)
  180. outputOptions.json = bool;
  181. });
  182. if(typeof outputOptions.colors === "undefined")
  183. outputOptions.colors = require("supports-color");
  184. ifArg("sort-modules-by", function(value) {
  185. outputOptions.modulesSort = value;
  186. });
  187. ifArg("sort-chunks-by", function(value) {
  188. outputOptions.chunksSort = value;
  189. });
  190. ifArg("sort-assets-by", function(value) {
  191. outputOptions.assetsSort = value;
  192. });
  193. ifArg("display-exclude", function(value) {
  194. outputOptions.exclude = value;
  195. });
  196. if(!outputOptions.json) {
  197. if(typeof outputOptions.cached === "undefined")
  198. outputOptions.cached = false;
  199. if(typeof outputOptions.cachedAssets === "undefined")
  200. outputOptions.cachedAssets = false;
  201. ifArg("display-chunks", function(bool) {
  202. outputOptions.modules = !bool;
  203. outputOptions.chunks = bool;
  204. });
  205. ifArg("display-entrypoints", function(bool) {
  206. outputOptions.entrypoints = bool;
  207. });
  208. ifArg("display-reasons", function(bool) {
  209. outputOptions.reasons = bool;
  210. });
  211. ifArg("display-depth", function(bool) {
  212. outputOptions.depth = bool;
  213. });
  214. ifArg("display-used-exports", function(bool) {
  215. outputOptions.usedExports = bool;
  216. });
  217. ifArg("display-provided-exports", function(bool) {
  218. outputOptions.providedExports = bool;
  219. });
  220. ifArg("display-error-details", function(bool) {
  221. outputOptions.errorDetails = bool;
  222. });
  223. ifArg("display-origins", function(bool) {
  224. outputOptions.chunkOrigins = bool;
  225. });
  226. ifArg("display-max-modules", function(value) {
  227. outputOptions.maxModules = value;
  228. });
  229. ifArg("display-cached", function(bool) {
  230. if(bool)
  231. outputOptions.cached = true;
  232. });
  233. ifArg("display-cached-assets", function(bool) {
  234. if(bool)
  235. outputOptions.cachedAssets = true;
  236. });
  237. if(!outputOptions.exclude)
  238. outputOptions.exclude = ["node_modules", "bower_components", "components"];
  239. if(argv["display-modules"]) {
  240. outputOptions.maxModules = Infinity;
  241. outputOptions.exclude = undefined;
  242. }
  243. } else {
  244. if(typeof outputOptions.chunks === "undefined")
  245. outputOptions.chunks = true;
  246. if(typeof outputOptions.entrypoints === "undefined")
  247. outputOptions.entrypoints = true;
  248. if(typeof outputOptions.modules === "undefined")
  249. outputOptions.modules = true;
  250. if(typeof outputOptions.chunkModules === "undefined")
  251. outputOptions.chunkModules = true;
  252. if(typeof outputOptions.reasons === "undefined")
  253. outputOptions.reasons = true;
  254. if(typeof outputOptions.cached === "undefined")
  255. outputOptions.cached = true;
  256. if(typeof outputOptions.cachedAssets === "undefined")
  257. outputOptions.cachedAssets = true;
  258. }
  259. ifArg("hide-modules", function(bool) {
  260. if(bool) {
  261. outputOptions.modules = false;
  262. outputOptions.chunkModules = false;
  263. }
  264. });
  265. var webpack = require("../lib/webpack.js");
  266. Error.stackTraceLimit = 30;
  267. var lastHash = null;
  268. var compiler;
  269. try {
  270. compiler = webpack(options);
  271. } catch(e) {
  272. var WebpackOptionsValidationError = require("../lib/WebpackOptionsValidationError");
  273. if(e instanceof WebpackOptionsValidationError) {
  274. if(argv.color)
  275. console.error("\u001b[1m\u001b[31m" + e.message + "\u001b[39m\u001b[22m");
  276. else
  277. console.error(e.message);
  278. process.exit(1); // eslint-disable-line no-process-exit
  279. }
  280. throw e;
  281. }
  282. if(argv.progress) {
  283. var ProgressPlugin = require("../lib/ProgressPlugin");
  284. compiler.apply(new ProgressPlugin({
  285. profile: argv.profile
  286. }));
  287. }
  288. function compilerCallback(err, stats) {
  289. if(!options.watch || err) {
  290. // Do not keep cache anymore
  291. compiler.purgeInputFileSystem();
  292. }
  293. if(err) {
  294. lastHash = null;
  295. console.error(err.stack || err);
  296. if(err.details) console.error(err.details);
  297. process.exit(1); // eslint-disable-line
  298. }
  299. if(outputOptions.json) {
  300. process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + "\n");
  301. } else if(stats.hash !== lastHash) {
  302. lastHash = stats.hash;
  303. process.stdout.write(stats.toString(outputOptions) + "\n");
  304. }
  305. if(!options.watch && stats.hasErrors()) {
  306. process.on("exit", function() {
  307. process.exit(2); // eslint-disable-line
  308. });
  309. }
  310. }
  311. if(firstOptions.watch || options.watch) {
  312. var watchOptions = firstOptions.watchOptions || firstOptions.watch || options.watch || {};
  313. if(watchOptions.stdin) {
  314. process.stdin.on("end", function() {
  315. process.exit(0); // eslint-disable-line
  316. });
  317. process.stdin.resume();
  318. }
  319. compiler.watch(watchOptions, compilerCallback);
  320. console.log("\nWebpack is watching the files…\n");
  321. } else
  322. compiler.run(compilerCallback);
  323. }
  324. processOptions(options);