config-yargs.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. const optionsSchema = require("./optionsSchema.json");
  2. const nestedProperties = ["anyOf", "oneOf", "allOf"];
  3. const resolveSchema = schema => {
  4. let current = schema;
  5. if (schema && typeof schema === "object" && "$ref" in schema) {
  6. const path = schema.$ref.split("/");
  7. for (const element of path) {
  8. if (element === "#") {
  9. current = optionsSchema;
  10. } else {
  11. current = current[element];
  12. }
  13. }
  14. }
  15. return current;
  16. };
  17. const findPropertyInSchema = (schema, property, subProperty) => {
  18. if (!schema) return null;
  19. if (subProperty) {
  20. if (schema[property] && typeof schema[property] === "object" && subProperty in schema[property]) {
  21. return resolveSchema(schema[property][subProperty]);
  22. }
  23. } else {
  24. if (property in schema) return resolveSchema(schema[property]);
  25. }
  26. for (const name of nestedProperties) {
  27. if (schema[name]) {
  28. for (const item of schema[name]) {
  29. const resolvedItem = resolveSchema(item);
  30. const result = findPropertyInSchema(resolvedItem, property, subProperty);
  31. if (result) return result;
  32. }
  33. }
  34. }
  35. return undefined;
  36. };
  37. const getSchemaInfo = (path, property, subProperty) => {
  38. const pathSegments = path.split(".");
  39. let current = optionsSchema;
  40. for (const segment of pathSegments) {
  41. if (segment === "*") {
  42. current = findPropertyInSchema(current, "additionalProperties") || findPropertyInSchema(current, "items");
  43. } else {
  44. current = findPropertyInSchema(current, "properties", segment);
  45. }
  46. if (!current) return undefined;
  47. }
  48. return findPropertyInSchema(current, property, subProperty);
  49. };
  50. const CONFIG_GROUP = "Config options:";
  51. const BASIC_GROUP = "Basic options:";
  52. const MODULE_GROUP = "Module options:";
  53. const OUTPUT_GROUP = "Output options:";
  54. const ADVANCED_GROUP = "Advanced options:";
  55. const RESOLVE_GROUP = "Resolving options:";
  56. const OPTIMIZE_GROUP = "Optimizing options:";
  57. module.exports = function(yargs) {
  58. yargs
  59. .help("help")
  60. .alias("help", "h")
  61. .version()
  62. .alias("version", "v")
  63. .options({
  64. config: {
  65. type: "string",
  66. describe: "Path to the config file",
  67. group: CONFIG_GROUP,
  68. defaultDescription: "webpack.config.js or webpackfile.js",
  69. requiresArg: true
  70. },
  71. "config-register": {
  72. type: "array",
  73. alias: "r",
  74. describe: "Preload one or more modules before loading the webpack configuration",
  75. group: CONFIG_GROUP,
  76. defaultDescription: "module id or path",
  77. requiresArg: true
  78. },
  79. "config-name": {
  80. type: "string",
  81. describe: "Name of the config to use",
  82. group: CONFIG_GROUP,
  83. requiresArg: true
  84. },
  85. env: {
  86. describe: "Environment passed to the config, when it is a function",
  87. group: CONFIG_GROUP
  88. },
  89. mode: {
  90. type: getSchemaInfo("mode", "type"),
  91. choices: getSchemaInfo("mode", "enum"),
  92. describe: getSchemaInfo("mode", "description"),
  93. group: CONFIG_GROUP,
  94. requiresArg: true
  95. },
  96. context: {
  97. type: getSchemaInfo("context", "type"),
  98. describe: getSchemaInfo("context", "description"),
  99. group: BASIC_GROUP,
  100. defaultDescription: "The current directory",
  101. requiresArg: true
  102. },
  103. entry: {
  104. type: "string",
  105. describe: getSchemaInfo("entry", "description"),
  106. group: BASIC_GROUP,
  107. requiresArg: true
  108. },
  109. "module-bind": {
  110. type: "string",
  111. describe: "Bind an extension to a loader",
  112. group: MODULE_GROUP,
  113. requiresArg: true
  114. },
  115. "module-bind-post": {
  116. type: "string",
  117. describe: "Bind an extension to a post loader",
  118. group: MODULE_GROUP,
  119. requiresArg: true
  120. },
  121. "module-bind-pre": {
  122. type: "string",
  123. describe: "Bind an extension to a pre loader",
  124. group: MODULE_GROUP,
  125. requiresArg: true
  126. },
  127. output: {
  128. alias: "o",
  129. describe: "The output path and file for compilation assets",
  130. group: OUTPUT_GROUP,
  131. requiresArg: true
  132. },
  133. "output-path": {
  134. type: "string",
  135. describe: getSchemaInfo("output.path", "description"),
  136. group: OUTPUT_GROUP,
  137. defaultDescription: "The current directory",
  138. requiresArg: true
  139. },
  140. "output-filename": {
  141. type: "string",
  142. describe: getSchemaInfo("output.filename", "description"),
  143. group: OUTPUT_GROUP,
  144. defaultDescription: "[name].js",
  145. requiresArg: true
  146. },
  147. "output-chunk-filename": {
  148. type: "string",
  149. describe: getSchemaInfo("output.chunkFilename", "description"),
  150. group: OUTPUT_GROUP,
  151. defaultDescription: "filename with [id] instead of [name] or [id] prefixed",
  152. requiresArg: true
  153. },
  154. "output-source-map-filename": {
  155. type: "string",
  156. describe: getSchemaInfo("output.sourceMapFilename", "description"),
  157. group: OUTPUT_GROUP,
  158. requiresArg: true
  159. },
  160. "output-public-path": {
  161. type: "string",
  162. describe: getSchemaInfo("output.publicPath", "description"),
  163. group: OUTPUT_GROUP,
  164. requiresArg: true
  165. },
  166. "output-jsonp-function": {
  167. type: "string",
  168. describe: getSchemaInfo("output.jsonpFunction", "description"),
  169. group: OUTPUT_GROUP,
  170. requiresArg: true
  171. },
  172. "output-pathinfo": {
  173. type: "boolean",
  174. describe: getSchemaInfo("output.pathinfo", "description"),
  175. group: OUTPUT_GROUP
  176. },
  177. "output-library": {
  178. type: "array",
  179. describe: "Expose the exports of the entry point as library",
  180. group: OUTPUT_GROUP,
  181. requiresArg: true
  182. },
  183. "output-library-target": {
  184. type: "string",
  185. describe: getSchemaInfo("output.libraryTarget", "description"),
  186. choices: getSchemaInfo("output.libraryTarget", "enum"),
  187. group: OUTPUT_GROUP,
  188. requiresArg: true
  189. },
  190. "records-input-path": {
  191. type: "string",
  192. describe: getSchemaInfo("recordsInputPath", "description"),
  193. group: ADVANCED_GROUP,
  194. requiresArg: true
  195. },
  196. "records-output-path": {
  197. type: "string",
  198. describe: getSchemaInfo("recordsOutputPath", "description"),
  199. group: ADVANCED_GROUP,
  200. requiresArg: true
  201. },
  202. "records-path": {
  203. type: "string",
  204. describe: getSchemaInfo("recordsPath", "description"),
  205. group: ADVANCED_GROUP,
  206. requiresArg: true
  207. },
  208. define: {
  209. type: "string",
  210. describe: "Define any free var in the bundle",
  211. group: ADVANCED_GROUP,
  212. requiresArg: true
  213. },
  214. target: {
  215. type: "string",
  216. describe: getSchemaInfo("target", "description"),
  217. group: ADVANCED_GROUP,
  218. requiresArg: true
  219. },
  220. cache: {
  221. type: "boolean",
  222. describe: getSchemaInfo("cache", "description"),
  223. default: null,
  224. group: ADVANCED_GROUP,
  225. defaultDescription: "It's enabled by default when watching"
  226. },
  227. watch: {
  228. type: "boolean",
  229. alias: "w",
  230. describe: getSchemaInfo("watch", "description"),
  231. group: BASIC_GROUP
  232. },
  233. "watch-stdin": {
  234. type: "boolean",
  235. alias: "stdin",
  236. describe: getSchemaInfo("watchOptions.stdin", "description"),
  237. group: ADVANCED_GROUP
  238. },
  239. "watch-aggregate-timeout": {
  240. describe: getSchemaInfo("watchOptions.aggregateTimeout", "description"),
  241. type: getSchemaInfo("watchOptions.aggregateTimeout", "type"),
  242. group: ADVANCED_GROUP,
  243. requiresArg: true
  244. },
  245. "watch-poll": {
  246. type: "string",
  247. describe: getSchemaInfo("watchOptions.poll", "description"),
  248. group: ADVANCED_GROUP
  249. },
  250. hot: {
  251. type: "boolean",
  252. describe: "Enables Hot Module Replacement",
  253. group: ADVANCED_GROUP
  254. },
  255. debug: {
  256. type: "boolean",
  257. describe: "Switch loaders to debug mode",
  258. group: BASIC_GROUP
  259. },
  260. devtool: {
  261. type: "string",
  262. describe: getSchemaInfo("devtool", "description"),
  263. group: BASIC_GROUP,
  264. requiresArg: true
  265. },
  266. "resolve-alias": {
  267. type: "string",
  268. describe: getSchemaInfo("resolve.alias", "description"),
  269. group: RESOLVE_GROUP,
  270. requiresArg: true
  271. },
  272. "resolve-extensions": {
  273. type: "array",
  274. describe: getSchemaInfo("resolve.alias", "description"),
  275. group: RESOLVE_GROUP,
  276. requiresArg: true
  277. },
  278. "resolve-loader-alias": {
  279. type: "string",
  280. describe: "Setup a loader alias for resolving",
  281. group: RESOLVE_GROUP,
  282. requiresArg: true
  283. },
  284. "optimize-max-chunks": {
  285. describe: "Try to keep the chunk count below a limit",
  286. group: OPTIMIZE_GROUP,
  287. requiresArg: true
  288. },
  289. "optimize-min-chunk-size": {
  290. describe: getSchemaInfo("optimization.splitChunks.minSize", "description"),
  291. group: OPTIMIZE_GROUP,
  292. requiresArg: true
  293. },
  294. "optimize-minimize": {
  295. type: "boolean",
  296. describe: getSchemaInfo("optimization.minimize", "description"),
  297. group: OPTIMIZE_GROUP
  298. },
  299. prefetch: {
  300. type: "string",
  301. describe: "Prefetch this request (Example: --prefetch ./file.js)",
  302. group: ADVANCED_GROUP,
  303. requiresArg: true
  304. },
  305. provide: {
  306. type: "string",
  307. describe: "Provide these modules as free vars in all modules (Example: --provide jQuery=jquery)",
  308. group: ADVANCED_GROUP,
  309. requiresArg: true
  310. },
  311. "labeled-modules": {
  312. type: "boolean",
  313. describe: "Enables labeled modules",
  314. group: ADVANCED_GROUP
  315. },
  316. plugin: {
  317. type: "string",
  318. describe: "Load this plugin",
  319. group: ADVANCED_GROUP,
  320. requiresArg: true
  321. },
  322. bail: {
  323. type: getSchemaInfo("bail", "type"),
  324. describe: getSchemaInfo("bail", "description"),
  325. group: ADVANCED_GROUP,
  326. default: null
  327. },
  328. profile: {
  329. type: "boolean",
  330. describe: getSchemaInfo("profile", "description"),
  331. group: ADVANCED_GROUP,
  332. default: null
  333. },
  334. d: {
  335. type: "boolean",
  336. describe: "shortcut for --debug --devtool eval-cheap-module-source-map --output-pathinfo",
  337. group: BASIC_GROUP
  338. },
  339. p: {
  340. type: "boolean",
  341. describe: "shortcut for --optimize-minimize --define process.env.NODE_ENV=\"production\"",
  342. group: BASIC_GROUP
  343. }
  344. });
  345. };