config.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. 'use strict';
  2. const PLUGIN = require('./constants.js').PLUGIN;
  3. const DEFAULT_HASH = {
  4. test: []
  5. };
  6. const DEFAULT_RESOURCE_HINT_HASH = {
  7. test: [],
  8. chunks: 'initial'
  9. };
  10. const DEFAULT_CUSTOM_HASH = {
  11. test: [],
  12. attribute: '',
  13. value: true
  14. };
  15. const DEFAULT_OPTIONS = {
  16. inline: DEFAULT_HASH,
  17. sync: DEFAULT_HASH,
  18. async: DEFAULT_HASH,
  19. defer: DEFAULT_HASH,
  20. module: DEFAULT_HASH,
  21. prefetch: DEFAULT_RESOURCE_HINT_HASH,
  22. preload: DEFAULT_RESOURCE_HINT_HASH,
  23. defaultAttribute: 'sync',
  24. removeInlinedAssets: true,
  25. custom: []
  26. };
  27. const POSSIBLE_VALUES = ['chunks', 'attribute', 'value'];
  28. const normaliseOptions = options => {
  29. if (!options) return DEFAULT_OPTIONS;
  30. validate(options);
  31. const normalised = Object.assign({}, DEFAULT_OPTIONS, options);
  32. // now overwrite values which are not of DEFAULT_HASH form
  33. Object.keys(options).forEach(key => {
  34. const value = options[key];
  35. switch (key) {
  36. case 'inline':
  37. case 'sync':
  38. case 'async':
  39. case 'defer':
  40. case 'module':
  41. normalised[key] = normaliseAttribute(value);
  42. break;
  43. case 'prefetch':
  44. case 'preload':
  45. normalised[key] = normaliseResourceHint(value);
  46. break;
  47. case 'custom':
  48. normalised[key] = normaliseCustomArray(value);
  49. break;
  50. default:
  51. break;
  52. }
  53. });
  54. return normalised;
  55. };
  56. const validate = options => {
  57. const failureTests = []; // TODO!
  58. if (failureTests.some(test => test(options))) error();
  59. };
  60. const error = () => {
  61. throw new Error(`${PLUGIN}: invalid configuration - please see https://github.com/numical/script-ext-html-webpack-plugin#configuration`);
  62. };
  63. const normaliseValue = (defaultProps, value) => {
  64. let normalised = Object.assign({}, defaultProps);
  65. if (value) {
  66. normalised.test = convertToArray(value, () => {
  67. if (typeof value === 'object') {
  68. POSSIBLE_VALUES.forEach(key => copyValue(key, normalised, value));
  69. if (value.test) {
  70. return convertToArray(value.test, error);
  71. } else {
  72. error();
  73. }
  74. }
  75. });
  76. }
  77. return normalised;
  78. };
  79. const normaliseAttribute = normaliseValue.bind(null, DEFAULT_HASH);
  80. const normaliseResourceHint = normaliseValue.bind(null, DEFAULT_RESOURCE_HINT_HASH);
  81. const normaliseCustomAttribute = normaliseValue.bind(null, DEFAULT_CUSTOM_HASH);
  82. const normaliseCustomArray = value => {
  83. const array = Array.isArray(value) ? value : [value];
  84. return array.map(normaliseCustomAttribute);
  85. };
  86. const convertToArray = (value, elseFn) => {
  87. if (typeof value === 'string') {
  88. return [value];
  89. } else if (value instanceof RegExp) {
  90. return [value];
  91. } else if (Array.isArray(value)) {
  92. return value;
  93. } else {
  94. return elseFn();
  95. }
  96. };
  97. const copyValue = (key, to, from) => {
  98. if (from.hasOwnProperty(key)) {
  99. to[key] = from[key];
  100. }
  101. };
  102. module.exports = normaliseOptions;
  103. module.exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS;