基于上一篇可视化适配,为了方便引用,特些一篇文章,使用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"],
}),
],
到这里就结束了,欢迎有问题随时讨论