需求
在写了大量功能结构相同的H5页面之后,对逻辑部分已经进行了模板化。那么前端在写代码的时候基本上时间就都放到了切图和修改css样式上了,而对于修改css样式来说,其时间主要是消耗在了对图片进行宽高的修改上了。为了尽量的节省时间和加快效率,目前需要写一个工具实现自动来获取图片宽高并重写css文件
语言选取
能够对文件实现读写的主要是后端语言。但是使用该工具的基本上前端人员尽量不额外的添加新的环境,那么就选取了nodejs来实现。
具体逻辑
-
读取css文件拿到样式数据
-
读取css样式中图片数据,并拿到对应的图片宽高
-
读取到宽高之后,对对应的声明数据进行修改
-
将新生成样式数据重新到文件中
读取css文件拿到样式数据
读取文件可以通过fs来实现
// 读取文件
const fs = require('fs');
const cssFile = 'index.css'; //文件地址
fs.readFile(cssFile, 'utf8', (err, data) => {
if (err) {
console.error(err);
} else {
// data 就是读取到的css内容字符串
console.log(data)
}
});
读取css样式中图片数据,并拿到对应的图片宽高
- 获取到css字符串之后,对字符串进行正则处理拿到每个类名及对应的声明块
const regex = /([^{]+)\s*\{([^}]*)\}/g;
const cssArray = [];
let match;
while ((match = regex.exec(data)) !== null) {
const selector = match[1].trim();
const rule = match[2].trim();
cssArray.push({
selector,rule,isSetWidth:false
})
}
其中cssArray格式是
const cssArray = [{
selector : '.name',
rule:'width:222px;background: url(./image/close.png) center center / 100% 100% no-repeat;',
isSetWidth:false
}]
其中isSetWidth的设置主要是为了后续所有声明块是否已经都处理过了。
- 对
rule进行正则处理,拿到对应的图片地址
const backgroundImageRegex = /background:\s*url\((.*?)\)/;
const backgroundImageMatch = backgroundImageRegex.exec(rule);
const backgroundImageUrl = backgroundImageMatch ? backgroundImageMatch[1].trim() : '';
if(backgroundImageUrl && backgroundImageUrl.length > 0){
// 对于其中包含background的数据才进行读取否则直接忽略
}else{
item.isSetWidth = true
}
- 解析图片拿到图片宽高
const sharp = require('sharp');
// 读取图片大小
function getWidthAndHeight(url,success, fail){
sharp(url)
.metadata()
.then(metadata => {
// metadata 图片数据
success && success(metadata)
})
.catch(err => {
fail && fail(err)
//读取线上图片时会抛出异常
});
}
- 拿到图片宽高之后,对旧有数据进行更新
getWidthAndHeight(backgroundImageUrl,(data)=>{
// 完成对应的,直接追加到当前的rule中就可以了
let widthR = 'width:' + data.width / 100 + 'rem;'
let heightR = 'height:' + data.height / 100 + 'rem;'
//替换规则中的width 和 height
const regexWidth = /width:.*;/g;
const regexHeight = /height:.*;/g;
if(regexWidth.test(item.rule)){
item.rule = item.rule.replace(regexWidth,widthR);
}else{
item.rule = item.rule + widthR
}
if(regexHeight.test(item.rule)){
item.rule = item.rule.replace(regexHeight,heightR);
}else{
item.rule = item.rule + heightR
}
item.isSetWidth = true
},()=>{
item.isSetWidth = true
})
将改好的数据重新写入到样式文件中
其中图片读取数据是异步的,所以设置了定时器来判断啥时候完成处理,
let setWidthTime = setInterval(()=>{
let isSetWidthItem = cssArray.find(item => !item.isSetWidth)
if(!isSetWidthItem){
clearInterval(setWidthTime)
// 然后再将所有的数据都进行处理
cssArray.forEach(item => {
let rule = item.selector + '{'+ item.rule +'}'
resultRules = resultRules + rule
})
// 完成之后就是重新生成一个css文件,并将对应结果写到文件中
fs.writeFile(newCreateFile, resultRules, (err) => {
if (err) {
console.error('Error writing CSS file:', err);
} else {
console.log('CSS file written successfully.');
}
});
}
})