rpx-to-px.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. const loaderUtils = require('loader-utils');
  2. // 匹配到 template 标签
  3. const template = /<template>([\s\S]+)<\/template>/gi;
  4. const stylePXRegExp = /(\d+)px/;
  5. let defaultsProp = {
  6. unitToConvert: 'px',
  7. ignoreUnitCase: true, // 转换单位是否忽略大小写
  8. viewportWidth: 750,
  9. unitPrecision: 5,
  10. viewportUnit: 'vw',
  11. fontViewportUnit: 'vw',
  12. minPixelValue: 1
  13. };
  14. module.exports = function(source) {
  15. const opts = loaderUtils.getOptions(this);
  16. const dpo = {...defaultsProp, ...opts};
  17. let newSource = '';
  18. if (template.test(source)) {
  19. newSource = source.match(template)[0];
  20. }
  21. const pxReg = new RegExp(stylePXRegExp.source, dpo.ignoreUnitCase ? 'ig' : 'g');
  22. if(pxReg.test(newSource)) {
  23. const _source = newSource.replace(pxReg, createPxReplace(dpo.viewportWidth, dpo.minPixelValue, dpo.unitPrecision, dpo.viewportUnit))
  24. return source.replace(template, _source)
  25. }
  26. return source
  27. }
  28. function createPxReplace (viewportSize, minPixelValue, unitPrecision, viewportUnit) {
  29. return function ($0, $1) {
  30. if (!$1) return
  31. const pixels = parseFloat($1)
  32. if (pixels <= minPixelValue) return
  33. return toFixed((pixels / viewportSize * 100), unitPrecision) + viewportUnit
  34. }
  35. }
  36. function toFixed (number, precision) {
  37. const multiplier = Math.pow(10, precision + 1),
  38. wholeNumber = Math.floor(number * multiplier)
  39. return Math.round(wholeNumber / 10) * 10 / multiplier
  40. }