nodeJs生成项目文件中用到的本地图片
分类:javascript
作为一名前端仔,在项目开发过程中,当你需要对一个项目中的某些文件使用到的图片,全部搬运到另一个项目中时,如果不想将整个图片文件拷贝过去,通常会选择一张张图片查找后手动复制过去。如果这个页面用到了很多图片,这种做法就慢如乌龟。于是,我选择利用nodeJs实现快速地生成项目文件中用到的本地图片。
注意: 本代码例子只适用于windows系统,若想适配其他系统,请修改输出路径。
先康康最终效果:
可以发现,终端运行命令后生成了该文件中使用到的所有本地图片的文件。
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项目的文件夹里来了,一步到位。
完整代码如下: