找到未引用的图片

介绍

小蓝在公司负责图文编辑器的开发,每次在编辑器中插入图片都会调用一次上传接口,将图片上传至服务器中,但是文章最终编辑完成时可能并未引用所有上传的图片,这就导致许多“无效文件”的产生,于是小蓝想编写一个维护脚本,定期清理那些未被引用的图片文件。

下面就请你使用 Node.js 帮助小蓝找出那些未引用的图片。

准备

开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:

1
2
3
4
├── articles
├── images
├── index.js
└── test.js

其中:

  • articles 是项目的文章目录。
  • images 是项目的图片目录。
  • test.js 是验证答案是否正确的工具方法。
  • index.js 是需要补充代码的 js 文件。

注意:打开环境后发现缺少项目代码,请复制下述命令至命令行进行下载。

1
2
3
4
wget https://labfile.oss.aliyuncs.com/courses/16666/dist_04.zip
unzip dist_04.zip
mv dist/* ./
rm -rf dist*

目标

找到 index.js 中的 findUnlinkImages 函数,完善其中的 TODO 部分。使用 Node.js 中的 fs 等内置模块进行文件操作,查找出 images 目录下未被任何文章(articles 文件夹下的 .md 文档)引用的“无效图片”,最终需要在 findUnlinkImages 这个函数中返回包含这些“无效图片”的数组。

提示:Markdown 中插入图片语法为:![](xxxxxx.png)

提示:代码中提供了工具函数 traversalDirsearchImage 可供参考使用。

请保证封装的函数满足所有测试用例,并在终端运行以下命令:

1
node test.js

如果你的结果正确,则在终端将会输出“测试通过”。

规定

  • 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。
  • 满足需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动检测。

判分标准

  • 本题完全实现题目目标得满分,否则得 0 分

总通过次数: 1 | 总提交次数: 1 | 通过率: 100%

难度: 中等 标签: 蓝桥杯, 2023, 国赛, Web 前端, Node.js

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
const path = require("path");
const fs = require("fs");
const { log } = require("console");

const articlesPath = path.resolve(__dirname, "articles");
const imagesPath = path.resolve(__dirname, "images");

const findUnlinkImages = async function () {
const unlinkImages = []; // 未被任何 md 文件引用的图片的数组
// TODO 请通过 Node.js 在此处继续完成代码编写

// 1. 从articles中,提取UsedImages,使用过的图片
let usedImages = []
const UsedMarkdownFiles = await traversalDir(articlesPath)
for (let file of UsedMarkdownFiles) {
const content = await new Promise((resolve, reject) => {
fs.readFile(path.join(articlesPath, file), "utf-8", (err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
usedImages.push(...searchImage(content));
}

// 2. 从images中,整理出AllImages,所有的图片
const AllImages = await traversalDir(imagesPath)


// 3. 2的数组减去1的数组,返回结果
// 取巧方法,将usedImages数组每一项字符串规范为指定格式
// usedImages = usedImages.map(item => item.slice(10));
// unlinkImages.push(...AllImages.filter(image => !usedImages.includes(image)));
// 取巧方法,将usedImages数组每一项字符串规范为指定格式 END

// 直接叠起来匹配
// usedImages.item = ../images/62599960.png'
// allimages.item = 62599960.png
unlinkImages.push(...AllImages.filter(image => !usedImages.some(item => item.includes(image)) // 返回 true 为 usedImages 没有包含 image
));


console.log(unlinkImages);
return unlinkImages; // 此处应返回一个数组,如不明白,请仔细阅读题目
};

findUnlinkImages()

// 参考方法: 遍历文件列表
function traversalDir(path) {
return new Promise((resolve) => {
fs.readdir(path, async function (err, files) {
if (!err) {
resolve(files);
}
});
});
}

let useImgs = [];
/**
* 参考方法: 正则提取文章内的全部图片链接
* @param {string} md 传入的markdown文本内容
* @returns 包含所有图片链接的数组
*/
function searchImage(md) {
const pattern = /!\[(.*?)\]\((.*?)\)/gm;
let matcher;
while ((matcher = pattern.exec(md)) !== null) {
if (matcher[2].indexOf("images") !== -1) {
// 判断存在图片,matcher[2] 即为包含的链接
useImgs.push(matcher[2]);
}
}
return useImgs;
}

module.exports = findUnlinkImages; // 请勿删除该行代码,否则影响判题!