You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

504 lines
13 KiB

4 years ago
  1. const optionsSchema = require("../config/optionsSchema.json");
  2. const { GROUPS } = require("../utils/constants");
  3. const {
  4. CONFIG_GROUP,
  5. BASIC_GROUP,
  6. MODULE_GROUP,
  7. OUTPUT_GROUP,
  8. ADVANCED_GROUP,
  9. RESOLVE_GROUP,
  10. OPTIMIZE_GROUP,
  11. DISPLAY_GROUP
  12. } = GROUPS;
  13. const nestedProperties = ["anyOf", "oneOf", "allOf"];
  14. const resolveSchema = schema => {
  15. let current = schema;
  16. if (schema && typeof schema === "object" && "$ref" in schema) {
  17. const path = schema.$ref.split("/");
  18. for (const element of path) {
  19. if (element === "#") {
  20. current = optionsSchema;
  21. } else {
  22. current = current[element];
  23. }
  24. }
  25. }
  26. return current;
  27. };
  28. const findPropertyInSchema = (schema, property, subProperty) => {
  29. if (!schema) return null;
  30. if (subProperty) {
  31. if (schema[property] && typeof schema[property] === "object" && subProperty in schema[property]) {
  32. return resolveSchema(schema[property][subProperty]);
  33. }
  34. } else {
  35. if (property in schema) return resolveSchema(schema[property]);
  36. }
  37. for (const name of nestedProperties) {
  38. if (schema[name]) {
  39. for (const item of schema[name]) {
  40. const resolvedItem = resolveSchema(item);
  41. const result = findPropertyInSchema(resolvedItem, property, subProperty);
  42. if (result) return result;
  43. }
  44. }
  45. }
  46. return undefined;
  47. };
  48. const getSchemaInfo = (path, property, subProperty) => {
  49. const pathSegments = path.split(".");
  50. let current = optionsSchema;
  51. for (const segment of pathSegments) {
  52. if (segment === "*") {
  53. current = findPropertyInSchema(current, "additionalProperties") || findPropertyInSchema(current, "items");
  54. } else {
  55. current = findPropertyInSchema(current, "properties", segment);
  56. }
  57. if (!current) return undefined;
  58. }
  59. return findPropertyInSchema(current, property, subProperty);
  60. };
  61. module.exports = function(yargs) {
  62. yargs
  63. .help("help")
  64. .alias("help", "h")
  65. .version()
  66. .alias("version", "v")
  67. .options({
  68. config: {
  69. type: "string",
  70. describe: "Path to the config file",
  71. group: CONFIG_GROUP,
  72. defaultDescription: "webpack.config.js or webpackfile.js",
  73. requiresArg: true
  74. },
  75. "config-register": {
  76. type: "array",
  77. alias: "r",
  78. describe: "Preload one or more modules before loading the webpack configuration",
  79. group: CONFIG_GROUP,
  80. defaultDescription: "module id or path",
  81. requiresArg: true
  82. },
  83. "config-name": {
  84. type: "string",
  85. describe: "Name of the config to use",
  86. group: CONFIG_GROUP,
  87. requiresArg: true
  88. },
  89. env: {
  90. describe: "Environment passed to the config, when it is a function",
  91. group: CONFIG_GROUP
  92. },
  93. mode: {
  94. type: getSchemaInfo("mode", "type"),
  95. choices: getSchemaInfo("mode", "enum"),
  96. describe: getSchemaInfo("mode", "description"),
  97. group: CONFIG_GROUP,
  98. requiresArg: true
  99. },
  100. context: {
  101. type: getSchemaInfo("context", "type"),
  102. describe: getSchemaInfo("context", "description"),
  103. group: BASIC_GROUP,
  104. defaultDescription: "The current directory",
  105. requiresArg: true
  106. },
  107. entry: {
  108. type: "string",
  109. describe: getSchemaInfo("entry", "description"),
  110. group: BASIC_GROUP,
  111. requiresArg: true
  112. },
  113. "no-cache": {
  114. type: "boolean",
  115. describe: "Disables cached builds",
  116. group: BASIC_GROUP
  117. },
  118. "module-bind": {
  119. type: "string",
  120. describe: "Bind an extension to a loader",
  121. group: MODULE_GROUP,
  122. requiresArg: true
  123. },
  124. "module-bind-post": {
  125. type: "string",
  126. describe: "Bind an extension to a post loader",
  127. group: MODULE_GROUP,
  128. requiresArg: true
  129. },
  130. "module-bind-pre": {
  131. type: "string",
  132. describe: "Bind an extension to a pre loader",
  133. group: MODULE_GROUP,
  134. requiresArg: true
  135. },
  136. output: {
  137. alias: "o",
  138. describe: "The output path and file for compilation assets",
  139. group: OUTPUT_GROUP,
  140. requiresArg: true
  141. },
  142. "output-path": {
  143. type: "string",
  144. describe: getSchemaInfo("output.path", "description"),
  145. group: OUTPUT_GROUP,
  146. defaultDescription: "The current directory",
  147. requiresArg: true
  148. },
  149. "output-filename": {
  150. type: "string",
  151. describe: getSchemaInfo("output.filename", "description"),
  152. group: OUTPUT_GROUP,
  153. defaultDescription: "[name].js",
  154. requiresArg: true
  155. },
  156. "output-chunk-filename": {
  157. type: "string",
  158. describe: getSchemaInfo("output.chunkFilename", "description"),
  159. group: OUTPUT_GROUP,
  160. defaultDescription: "filename with [id] instead of [name] or [id] prefixed",
  161. requiresArg: true
  162. },
  163. "output-source-map-filename": {
  164. type: "string",
  165. describe: getSchemaInfo("output.sourceMapFilename", "description"),
  166. group: OUTPUT_GROUP,
  167. requiresArg: true
  168. },
  169. "output-public-path": {
  170. type: "string",
  171. describe: getSchemaInfo("output.publicPath", "description"),
  172. group: OUTPUT_GROUP,
  173. requiresArg: true
  174. },
  175. "output-jsonp-function": {
  176. type: "string",
  177. describe: getSchemaInfo("output.jsonpFunction", "description"),
  178. group: OUTPUT_GROUP,
  179. requiresArg: true
  180. },
  181. "output-pathinfo": {
  182. type: "boolean",
  183. describe: getSchemaInfo("output.pathinfo", "description"),
  184. group: OUTPUT_GROUP
  185. },
  186. "output-library": {
  187. type: "array",
  188. describe: "Expose the exports of the entry point as library",
  189. group: OUTPUT_GROUP,
  190. requiresArg: true
  191. },
  192. "output-library-target": {
  193. type: "string",
  194. describe: getSchemaInfo("output.libraryTarget", "description"),
  195. choices: getSchemaInfo("output.libraryTarget", "enum"),
  196. group: OUTPUT_GROUP,
  197. requiresArg: true
  198. },
  199. "records-input-path": {
  200. type: "string",
  201. describe: getSchemaInfo("recordsInputPath", "description"),
  202. group: ADVANCED_GROUP,
  203. requiresArg: true
  204. },
  205. "records-output-path": {
  206. type: "string",
  207. describe: getSchemaInfo("recordsOutputPath", "description"),
  208. group: ADVANCED_GROUP,
  209. requiresArg: true
  210. },
  211. "records-path": {
  212. type: "string",
  213. describe: getSchemaInfo("recordsPath", "description"),
  214. group: ADVANCED_GROUP,
  215. requiresArg: true
  216. },
  217. define: {
  218. type: "string",
  219. describe: "Define any free var in the bundle",
  220. group: ADVANCED_GROUP,
  221. requiresArg: true
  222. },
  223. target: {
  224. type: "string",
  225. describe: getSchemaInfo("target", "description"),
  226. group: ADVANCED_GROUP,
  227. requiresArg: true
  228. },
  229. cache: {
  230. type: "boolean",
  231. describe: getSchemaInfo("cache", "description"),
  232. default: null,
  233. group: ADVANCED_GROUP,
  234. defaultDescription: "It's enabled by default when watching"
  235. },
  236. watch: {
  237. type: "boolean",
  238. alias: "w",
  239. describe: getSchemaInfo("watch", "description"),
  240. group: BASIC_GROUP
  241. },
  242. "watch-stdin": {
  243. type: "boolean",
  244. alias: "stdin",
  245. describe: getSchemaInfo("watchOptions.stdin", "description"),
  246. group: ADVANCED_GROUP
  247. },
  248. "watch-aggregate-timeout": {
  249. describe: getSchemaInfo("watchOptions.aggregateTimeout", "description"),
  250. type: getSchemaInfo("watchOptions.aggregateTimeout", "type"),
  251. group: ADVANCED_GROUP,
  252. requiresArg: true
  253. },
  254. "watch-poll": {
  255. type: "string",
  256. describe: getSchemaInfo("watchOptions.poll", "description"),
  257. group: ADVANCED_GROUP
  258. },
  259. hot: {
  260. type: "boolean",
  261. describe: "Enables Hot Module Replacement",
  262. group: ADVANCED_GROUP
  263. },
  264. debug: {
  265. type: "boolean",
  266. describe: "Switch loaders to debug mode",
  267. group: BASIC_GROUP
  268. },
  269. devtool: {
  270. type: "string",
  271. describe: getSchemaInfo("devtool", "description"),
  272. group: BASIC_GROUP,
  273. requiresArg: true
  274. },
  275. "resolve-alias": {
  276. type: "string",
  277. describe: getSchemaInfo("resolve.alias", "description"),
  278. group: RESOLVE_GROUP,
  279. requiresArg: true
  280. },
  281. "resolve-extensions": {
  282. type: "array",
  283. describe: getSchemaInfo("resolve.alias", "description"),
  284. group: RESOLVE_GROUP,
  285. requiresArg: true
  286. },
  287. "resolve-loader-alias": {
  288. type: "string",
  289. describe: "Setup a loader alias for resolving",
  290. group: RESOLVE_GROUP,
  291. requiresArg: true
  292. },
  293. "optimize-max-chunks": {
  294. describe: "Try to keep the chunk count below a limit",
  295. group: OPTIMIZE_GROUP,
  296. requiresArg: true
  297. },
  298. "optimize-min-chunk-size": {
  299. describe: getSchemaInfo("optimization.splitChunks.minSize", "description"),
  300. group: OPTIMIZE_GROUP,
  301. requiresArg: true
  302. },
  303. "optimize-minimize": {
  304. type: "boolean",
  305. describe: getSchemaInfo("optimization.minimize", "description"),
  306. group: OPTIMIZE_GROUP
  307. },
  308. prefetch: {
  309. type: "string",
  310. describe: "Prefetch this request (Example: --prefetch ./file.js)",
  311. group: ADVANCED_GROUP,
  312. requiresArg: true
  313. },
  314. provide: {
  315. type: "string",
  316. describe: "Provide these modules as free vars in all modules (Example: --provide jQuery=jquery)",
  317. group: ADVANCED_GROUP,
  318. requiresArg: true
  319. },
  320. "labeled-modules": {
  321. type: "boolean",
  322. describe: "Enables labeled modules",
  323. group: ADVANCED_GROUP
  324. },
  325. plugin: {
  326. type: "string",
  327. describe: "Load this plugin",
  328. group: ADVANCED_GROUP,
  329. requiresArg: true
  330. },
  331. bail: {
  332. type: getSchemaInfo("bail", "type"),
  333. describe: getSchemaInfo("bail", "description"),
  334. group: ADVANCED_GROUP,
  335. default: null
  336. },
  337. profile: {
  338. type: "boolean",
  339. describe: getSchemaInfo("profile", "description"),
  340. group: ADVANCED_GROUP,
  341. default: null
  342. },
  343. d: {
  344. type: "boolean",
  345. describe: "shortcut for --debug --devtool eval-cheap-module-source-map --output-pathinfo",
  346. group: BASIC_GROUP
  347. },
  348. p: {
  349. type: "boolean",
  350. // eslint-disable-next-line quotes
  351. describe: 'shortcut for --optimize-minimize --define process.env.NODE_ENV="production"',
  352. group: BASIC_GROUP
  353. },
  354. silent: {
  355. type: "boolean",
  356. describe: "Prevent output from being displayed in stdout"
  357. },
  358. json: {
  359. type: "boolean",
  360. alias: "j",
  361. describe: "Prints the result as JSON."
  362. },
  363. progress: {
  364. type: "boolean",
  365. describe: "Print compilation progress in percentage",
  366. group: BASIC_GROUP
  367. },
  368. color: {
  369. type: "boolean",
  370. alias: "colors",
  371. default: function supportsColor() {
  372. return require("supports-color").stdout;
  373. },
  374. group: DISPLAY_GROUP,
  375. describe: "Force colors on the console"
  376. },
  377. "no-color": {
  378. type: "boolean",
  379. alias: "no-colors",
  380. group: DISPLAY_GROUP,
  381. describe: "Force no colors on the console"
  382. },
  383. "sort-modules-by": {
  384. type: "string",
  385. group: DISPLAY_GROUP,
  386. describe: "Sorts the modules list by property in module"
  387. },
  388. "sort-chunks-by": {
  389. type: "string",
  390. group: DISPLAY_GROUP,
  391. describe: "Sorts the chunks list by property in chunk"
  392. },
  393. "sort-assets-by": {
  394. type: "string",
  395. group: DISPLAY_GROUP,
  396. describe: "Sorts the assets list by property in asset"
  397. },
  398. "hide-modules": {
  399. type: "boolean",
  400. group: DISPLAY_GROUP,
  401. describe: "Hides info about modules"
  402. },
  403. "display-exclude": {
  404. type: "string",
  405. group: DISPLAY_GROUP,
  406. describe: "Exclude modules in the output"
  407. },
  408. "display-modules": {
  409. type: "boolean",
  410. group: DISPLAY_GROUP,
  411. describe: "Display even excluded modules in the output"
  412. },
  413. "display-max-modules": {
  414. type: "number",
  415. group: DISPLAY_GROUP,
  416. describe: "Sets the maximum number of visible modules in output"
  417. },
  418. "display-chunks": {
  419. type: "boolean",
  420. group: DISPLAY_GROUP,
  421. describe: "Display chunks in the output"
  422. },
  423. "display-entrypoints": {
  424. type: "boolean",
  425. group: DISPLAY_GROUP,
  426. describe: "Display entry points in the output"
  427. },
  428. "display-origins": {
  429. type: "boolean",
  430. group: DISPLAY_GROUP,
  431. describe: "Display origins of chunks in the output"
  432. },
  433. "display-cached": {
  434. type: "boolean",
  435. group: DISPLAY_GROUP,
  436. describe: "Display also cached modules in the output"
  437. },
  438. "display-cached-assets": {
  439. type: "boolean",
  440. group: DISPLAY_GROUP,
  441. describe: "Display also cached assets in the output"
  442. },
  443. "display-reasons": {
  444. type: "boolean",
  445. group: DISPLAY_GROUP,
  446. describe: "Display reasons about module inclusion in the output"
  447. },
  448. "display-depth": {
  449. type: "boolean",
  450. group: DISPLAY_GROUP,
  451. describe: "Display distance from entry point for each module"
  452. },
  453. "display-used-exports": {
  454. type: "boolean",
  455. group: DISPLAY_GROUP,
  456. describe: "Display information about used exports in modules (Tree Shaking)"
  457. },
  458. "display-provided-exports": {
  459. type: "boolean",
  460. group: DISPLAY_GROUP,
  461. describe: "Display information about exports provided from modules"
  462. },
  463. "display-optimization-bailout": {
  464. type: "boolean",
  465. group: DISPLAY_GROUP,
  466. describe: "Display information about why optimization bailed out for modules"
  467. },
  468. "display-error-details": {
  469. type: "boolean",
  470. group: DISPLAY_GROUP,
  471. describe: "Display details about errors"
  472. },
  473. display: {
  474. type: "string",
  475. choices: ["", "verbose", "detailed", "normal", "minimal", "errors-only", "none"],
  476. group: DISPLAY_GROUP,
  477. describe: "Select display preset"
  478. },
  479. verbose: {
  480. type: "boolean",
  481. group: DISPLAY_GROUP,
  482. describe: "Show more details"
  483. },
  484. "info-verbosity": {
  485. type: "string",
  486. default: "info",
  487. choices: ["none", "info", "verbose"],
  488. group: DISPLAY_GROUP,
  489. describe: "Controls the output of lifecycle messaging e.g. Started watching files..."
  490. },
  491. "build-delimiter": {
  492. type: "string",
  493. group: DISPLAY_GROUP,
  494. describe: "Display custom text after build output"
  495. }
  496. });
  497. };