theme-color-replacer-extend.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. const {cssResolve} = require('../config/replacer')
  2. // 修正 webpack-theme-color-replacer 插件提取的 css 结果
  3. function resolveCss(output, srcArr) {
  4. let regExps = []
  5. // 提取 resolve 配置中所有的正则配置
  6. Object.keys(cssResolve).forEach(key => {
  7. let isRegExp = false
  8. let reg = {}
  9. try {
  10. reg = eval(key)
  11. isRegExp = reg instanceof RegExp
  12. } catch (e) {
  13. isRegExp = false
  14. }
  15. if (isRegExp) {
  16. regExps.push([reg, cssResolve[key]])
  17. }
  18. })
  19. // 去重
  20. srcArr = dropDuplicate(srcArr)
  21. // 处理 css
  22. let outArr = []
  23. srcArr.forEach(text => {
  24. // 转换为 css 对象
  25. let cssObj = parseCssObj(text)
  26. // 根据selector匹配配置,匹配成功,则按配置处理 css
  27. if (cssResolve[cssObj.selector] != undefined) {
  28. let cfg = cssResolve[cssObj.selector]
  29. if (cfg) {
  30. outArr.push(cfg.resolve(text, cssObj))
  31. }
  32. } else {
  33. let cssText = ''
  34. // 匹配不成功,则测试是否有匹配的正则配置,有则按正则对应的配置处理
  35. for (let regExp of regExps) {
  36. if (regExp[0].test(cssObj.selector)) {
  37. let cssCfg = regExp[1]
  38. cssText = cssCfg ? cssCfg.resolve(text, cssObj) : ''
  39. break
  40. }
  41. // 未匹配到正则,则设置 cssText 为默认的 css(即不处理)
  42. cssText = text
  43. }
  44. if (cssText != '') {
  45. outArr.push(cssText)
  46. }
  47. }
  48. })
  49. output = outArr.join('\n')
  50. return output
  51. }
  52. // 数组去重
  53. function dropDuplicate(arr) {
  54. let map = {}
  55. let r = []
  56. for (let s of arr) {
  57. if (!map[s]) {
  58. r.push(s)
  59. map[s] = 1
  60. }
  61. }
  62. return r
  63. }
  64. /**
  65. * 从字符串解析 css 对象
  66. * @param cssText
  67. * @returns {{
  68. * name: String,
  69. * rules: Array[String],
  70. * toText: function
  71. * }}
  72. */
  73. function parseCssObj(cssText) {
  74. let css = {}
  75. const ruleIndex = cssText.indexOf('{')
  76. css.selector = cssText.substring(0, ruleIndex)
  77. const ruleBody = cssText.substring(ruleIndex + 1, cssText.length - 1)
  78. const rules = ruleBody.split(';')
  79. css.rules = rules
  80. css.toText = function () {
  81. let body = ''
  82. this.rules.forEach(item => {body += item + ';'})
  83. return `${this.selector}{${body}}`
  84. }
  85. return css
  86. }
  87. module.exports = {resolveCss}