nodeJs生成项目文件中用到的本地图片

我心飞翔 分类:javascript

作为一名前端仔,在项目开发过程中,当你需要对一个项目中的某些文件使用到的图片,全部搬运到另一个项目中时,如果不想将整个图片文件拷贝过去,通常会选择一张张图片查找后手动复制过去。如果这个页面用到了很多图片,这种做法就慢如乌龟。于是,我选择利用nodeJs实现快速地生成项目文件中用到的本地图片。

注意: 本代码例子只适用于windows系统,若想适配其他系统,请修改输出路径。

先康康最终效果:

ceshi.gif

可以发现,终端运行命令后生成了该文件中使用到的所有本地图片的文件。

PS: nodeJs神通广大,利用它可以干很多事情。

1. 初始化

新建一个copyimg.js文件,并初始化代码:

    #!/usr/bin/env node

    //引入模块
    const path = require('path');
    const fs = require('fs');

    var args = process.argv.splice(2);
    let curPath = args[0];  //想要获取图片的项目文件的绝对路径
    var outputPath = "c:\Users\Administrator\Desktop\copyimg\";  //图片文件输入路径
 

如上,我们将在终端运行node copyimg [项目文件名]生成图片文件,并将得到的图片文件保存到电脑桌面的copyimg文件夹里。

2. 获取图片文件的绝对路径

项目中的本地图片一般会以相对路径引用,例如:"../../images/button.png",我们需要将他们都转为绝对路径。
这里用到的正则如下:

    /(?<quotes>['"])(?<content>[-\w/.]+?)\.(?<suffix>png|jpg)\k<quotes>/ug
 

该正则规避了上传到CDN的图片链接,虽然没有怎么考虑到回溯的问题,但已足以使用,这里不是讨论重点。

    let imgList = [];

    toReadImg();

    //获取img绝对路径
    function getImgPath(imgRelativePath = "") {
        return path.resolve(path.dirname(curPath), imgRelativePath);
    }

    function toReadImg() {
        fs.readFile(curPath, { encoding: 'utf-8' }, (err, data) => {
            data.replace(/(?<quotes>['"])(?<content>[-\w/.]+?)\.(?<suffix>png|jpg)\k<quotes>/ug, (...args) => {
                let groups = args[args.length -1];
                let { content, suffix } = groups;
                let imgPath = getImgPath(content + '.' + suffix);
                imgList.push(imgPath);
            });

            console.log("imgList", imgList);
        });
    }
 

到这里,我们已经可以获得所有本地图片的绝对路径。运行后终端将打印出包含图片绝对路径的数组imgList

3. 获取所有图片文件和该项目文件的根路径

这一步是必要的,因为我们将要将图片复制到我们自定义的路径里,即outputPath

    //获取最长公共前缀路径
    getCommonPath = function getCommonPath (path1 = '', path2 = '', ...rest) {
        path1 = path1.replace(/[^\]+$/, '');
        if (!path2) return path1;
        path2 = path2.replace(/[^\]+$/, '');

        let base = '';
        for (let i = 0; i < path1.length && i < path2.length; i++) {
          if (path1[i] === path2[i]) {
            base += path2[i]
          } else {
            break
          }
        }
        if (rest.length) {
          return getCommonPath(base, ...rest);
        }
        return base
    };

    let commonPath = getCommonPath(curPath, ...imgList);

    console.log('commonPath: ', commonPath);
 

4. 生成图片到outputPath对应的文件夹

    imgList.forEach(imgPath => {
writeImg(imgPath, imgPath.replace(commonPath, outputPath));
})
//路径尾部添加斜杠
function addSlash(pathStr) {
if (pathStr[pathStr.length - 1] != "\\") {
pathStr += "\\"
}
return pathStr
}
//文件夹某一路径不存在时的回退处理
function handleDirReturn(folder, dirList) {
if (dirList.length) {
folder = addSlash(folder) + dirList.pop();
mkdirFolder(folder, dirList)
}
}
//创建文件夹
function mkdirFolder(folder, dirList = []) {
try {
fs.accessSync (folder);
handleDirReturn(folder, dirList);
} catch(error) {
try {
fs.mkdirSync(folder, 0777);
handleDirReturn(folder, dirList);
} catch(err) {
let newPath = path.resolve(folder, '..');
dirList.push(path.basename(folder));
let num = 0;
newPath.replace(/\\/g, () => {
++num;
})
if (num > 1) {
mkdirFolder(newPath, dirList);
}
}
}
}
//生成图片
function writeImg(oldPath, newPath) {
let imgDir = path.resolve(newPath, '..');
mkdirFolder(imgDir);
fs.readFile(oldPath, function(err,originBuffer) {            //读取图片位置
fs.writeFile(newPath, originBuffer, function(err){      //生成图片
if (err) {
console.log(err)
}
});
})
}

至此,该功能已经实现。
当然,我们可以加一点小小的代码,使它支持自定义输出路径:

    if (args[1]) {
outputPath = args[1];
}
outputPath = addSlash(outputPath);

这样就可以直接将A项目的图片直接复制到B项目的文件夹里来了,一步到位。

完整代码如下:

    #!/usr/bin/env node
const path = require('path');
const fs = require('fs');
var args = process.argv.splice(2);
let curPath = args[0];
var outputPath = "c:\\Users\\Administrator\\Desktop\\copyimg\\";  //根据实际情况修改
let imgList = [];
if (curPath) {
if (args[1]) {
outputPath = args[1];
}
outputPath = addSlash(outputPath);
console.log('文件绝对路径: ', curPath);
console.log('文件输出路径: ', outputPath);
mkdirFolder(outputPath);
toReadImg();
} else {
console.log('请输入文件绝对路径');
}
//获取img绝对路径
function getImgPath(imgRelativePath = "") {
return path.resolve(path.dirname(curPath), imgRelativePath);
}
function toReadImg() {
fs.readFile(curPath, { encoding: 'utf-8' }, (err, data) => {
if (err) {
console.log(`err`, err);
}
data.replace(/(?<quotes>['"])(?<content>[-\w/.]+?)\.(?<suffix>png|jpg)\k<quotes>/ug,(...args) => {
var groups = args[args.length -1];
let { content, suffix } = groups;
let imgPath = getImgPath(content + '.' + suffix);
imgList.push(imgPath);
});
let commonPath = getCommonPath(curPath, ...imgList);
// console.log('commonPath: ', commonPath);
imgList.forEach(item => {
writeImg(item, item.replace(commonPath, outputPath));
})
});
}
function handleDirReturn(folder, dirList) {
if (dirList.length) {
// console.log('handleDirReturn: ', folder, [...dirList]);
folder = addSlash(folder) + dirList.pop();
mkdirFolder(folder, dirList)
}
}
function mkdirFolder(folder, dirList = []) {
// if (!dirList.length) {
//     console.log('mkdirFolder: ', folder, [...dirList]);
// }
try {
fs.accessSync (folder);
handleDirReturn(folder, dirList);
} catch(error) {
try {
fs.mkdirSync(folder, 0777);
handleDirReturn(folder, dirList);
} catch(err) {
let newPath = path.resolve(folder, '..');
dirList.push(path.basename(folder));
let num = 0;
newPath.replace(/\\/g, () => {
++num;
})
if (num > 1) {
mkdirFolder(newPath, dirList);
}
}
}
}
//生成图片
function writeImg(oldPath, newPath) {
let imgDir = path.resolve(newPath, '..');
mkdirFolder(imgDir);
fs.readFile(oldPath, function(err,originBuffer) {            //读取图片位置
fs.writeFile(newPath, originBuffer, function(err){      //生成图片
if (err) {
console.log(err)
}
});
})
}
//获取最长公共前缀路径
getCommonPath = function getCommonPath (path1 = '', path2 = '', ...rest) {
path1 = path1.replace(/[^\\]+$/, '')
if (!path2) return path1
path2 = path2.replace(/[^\\]+$/, '')
let base = ''
for (let i = 0; i < path1.length && i < path2.length; i++) {
if (path1[i] === path2[i]) {
base += path2[i]
} else {
break
}
}
if (rest.length) {
return getCommonPath(base, ...rest)
}
return base
};
//尾部添加斜杠
function addSlash(pathStr) {
if (pathStr[pathStr.length - 1] != "\\") {
pathStr += "\\"
}
return pathStr
}

回复

我来回复
  • 暂无回复内容