gen-vant-mp-safe-css.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /**
  2. * 从 vant/lib/index.css 生成 WXSS 兼容样式:去掉含 * / *= 的选择器规则。
  3. * 升级 vant 后执行:node scripts/gen-vant-mp-safe-css.js
  4. */
  5. const fs = require('fs')
  6. const path = require('path')
  7. const root = path.join(__dirname, '..')
  8. const src = path.join(root, 'node_modules', 'vant', 'lib', 'index.css')
  9. const dest = path.join(root, 'styles', 'vant-mp-safe.css')
  10. if (!fs.existsSync(src)) {
  11. console.error('[gen-vant-mp-safe-css] missing', src)
  12. process.exit(1)
  13. }
  14. const text = fs.readFileSync(src, 'utf8')
  15. const out = []
  16. let i = 0
  17. const n = text.length
  18. let removed = 0
  19. let kept = 0
  20. function isBadSelector(sel) {
  21. // universal selector `*` (not `*=` attr or content "*")
  22. if (/(^|[,)\s>+~])\*(?!=)/.test(sel)) return true
  23. if (sel.includes('*=')) return true
  24. return false
  25. }
  26. while (i < n) {
  27. if (text.startsWith('/*', i)) {
  28. const j = text.indexOf('*/', i + 2)
  29. if (j < 0) break
  30. out.push(text.slice(i, j + 2))
  31. i = j + 2
  32. continue
  33. }
  34. if (/\s/.test(text[i])) {
  35. out.push(text[i])
  36. i += 1
  37. continue
  38. }
  39. if (text[i] === '@') {
  40. const brace = text.indexOf('{', i)
  41. const semi = text.indexOf(';', i)
  42. if (semi !== -1 && (brace === -1 || semi < brace)) {
  43. out.push(text.slice(i, semi + 1))
  44. i = semi + 1
  45. continue
  46. }
  47. if (brace < 0) {
  48. out.push(text.slice(i))
  49. break
  50. }
  51. let depth = 0
  52. let j = brace
  53. while (j < n) {
  54. if (text[j] === '{') depth += 1
  55. else if (text[j] === '}') {
  56. depth -= 1
  57. if (depth === 0) {
  58. j += 1
  59. break
  60. }
  61. }
  62. j += 1
  63. }
  64. const block = text.slice(i, j)
  65. if (isBadSelector(block)) removed += 1
  66. else {
  67. out.push(block)
  68. kept += 1
  69. }
  70. i = j
  71. continue
  72. }
  73. const brace = text.indexOf('{', i)
  74. if (brace < 0) {
  75. out.push(text.slice(i))
  76. break
  77. }
  78. let depth = 0
  79. let j = brace
  80. while (j < n) {
  81. if (text[j] === '{') depth += 1
  82. else if (text[j] === '}') {
  83. depth -= 1
  84. if (depth === 0) {
  85. j += 1
  86. break
  87. }
  88. }
  89. j += 1
  90. }
  91. const sel = text.slice(i, brace)
  92. const rule = text.slice(i, j)
  93. if (isBadSelector(sel)) removed += 1
  94. else {
  95. out.push(rule)
  96. kept += 1
  97. }
  98. i = j
  99. }
  100. const header =
  101. '/* auto-generated from vant/lib/index.css — WXSS-safe (no * / *= selectors). Do not edit. */\n'
  102. fs.writeFileSync(dest, header + out.join(''))
  103. console.log('[gen-vant-mp-safe-css] kept=%s removed=%s -> %s', kept, removed, dest)