vite插件之可视化适配

48 阅读1分钟

基于上一篇可视化适配,为了方便引用,特些一篇文章,使用vite插件实现

方案:使用js向html文件头部添加less代码

reactive.ts

type TargetStr = {
  w: Array<string>
  h: Array<string>
  margin: Array<string>
  padding: Array<string>
};

interface OptionConfig {
  ignore?: Array<string>
}



const targetStr: TargetStr = {
  w: ["width", "margin-left", "margin-right", "padding-left", "padding-right", "left", "right"],
  h: ["height", "margin-top", "margin-bottom", "padding-top", "padding-bottom", "top", "bottom"],
  margin: ['margin'],
  padding: ['padding']
}


import { PluginOption } from 'vite'
import { resolve } from 'path'
function ignoreFunc(key, attrs) {
  return attrs.includes(key)
}




export default function createPx2VwLoader(options: PluginOption & OptionConfig) {
  const { ignore = [] } = options
  return {
    config(config) {
      return {
        ...config,
        css: {
          preprocessorOptions: {
            less: {
              javascriptEnabled: true,
              additionalData: `@import "${resolve(__dirname, './reactive.less')}";`,
            },
          },
        },
      }
    },
    name: 'px2vw-loader', // 插件名,必须是唯一的
    enforce: 'pre', // 确保这个插件在其他所有插件之前执行
    transform(code, id) {
      if (id.endsWith('.less')) {

        for (let key in targetStr) {
          if (!ignoreFunc(key, ignore)) {
            const category = targetStr[key];
            category.forEach(item => {
              if (item !== 'margin' && item !== 'padding') {
                let regex = new RegExp(`${item}:\\s*(\\d+)px;`, "g")
                code = code.replace(regex, (match, p1) => `.px2v${key}(${item},${p1});`)
              } else {
                const regex1 = new RegExp(`${item}:\s*([^;]+);?`, 'g')
                let match;
                while ((match = regex1.exec(code))) {
                  // 这里可以处理匹配到的margin值,例如打印出来
                  let val = match[1].trim()
                  let matchValue = match[1].replaceAll('px', ',').split(',').map((v, idx) => v !== '' && v).filter(Boolean)

                  if (val.includes('px')) {
                    if (matchValue.length === 1) {
                      code = code.replace(regex1, (match, p1) => {
                        return `.px2vh(${item}-top,${matchValue[0]});\n  .px2vh(${item}-bottom,${matchValue[0]});\n  .px2vw(${item}-left,${matchValue[0]});\n  .px2vw(${item}-right,${matchValue[0]});`
                      })
                    } else if (matchValue.length === 2) {
                      code = code.replace(regex1, (match, p1) => {
                        return `.px2vh(${item}-top,${matchValue[0]});\n  .px2vh(${item}-bottom,${matchValue[0]});\n  .px2vw(${item}-left,${matchValue[1] ? matchValue[1] : matchValue[0]});\n  .px2vw(${item}-right,${matchValue[1] ? matchValue[1] : matchValue[0]});`
                      })
                    } else if (matchValue.length === 4) {
                      code = code.replace(regex1, (match, p1) => {
                        return `.px2vh(${item}-top,${matchValue[0]});\n  .px2vh(${item}-bottom,${matchValue[1]});\n  .px2vw(${item}-left,${matchValue[2]});\n  .px2vw(${item}-right,${matchValue[3]});`
                      })
                    }
                  }
                  console.log(code);
                }
              }
            })
          }
        }
        return {
          code,
          map: null, // 如果需要 source map,这里可以返回相应的数据
        };
      }
    },
  };
}

vite.config.ts 向vite添加配置

import createPx2VwLoader from "./src/assets/loaders/index.js";

可以在plugin中配置

  plugins: [ 
    createPx2VwLoader({
      // ignore: ["padding"],
    }),
  ],

到这里就结束了,欢迎有问题随时讨论