前端工具nodejs-自动生成css样式中图片宽高

101 阅读3分钟

需求

在写了大量功能结构相同的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.');
    }
});
}
})