一开始想实现爬虫获取链接,然后直接执行脚本,拉取到本地ts文件,但是没实现,有点四不像,代码如下:
const puppeteer = require("puppeteer-core");
const fs = require("fs");
const { JSDOM } = require("jsdom");
const path = require("path");
const processArgs = process.argv.slice(2);
// 定义 Iconfont 网址和输出文件名
const iconfontUrl = "https://" + processArgs[0];
const outputIconFile = "..//src/" + processArgs[1];
(async () => {
const browser = await puppeteer.launch({
executablePath: "C:/Program Files/Google/chrome.exe", // 你的 Chrome 或 Chromium 可执行文件路径
headless: true, // 设置为 true 表示无头模式,不会打开浏览器窗口
});
const page = await browser.newPage();
try {
// 访问 Iconfont 网址
await page.goto(iconfontUrl, { waitUntil: "networkidle0" });
const pageContent = await page.content();
// 使用正则表达式从页面内容中匹配 SVG 字符串
const svgRegex = /window\._iconfont_svg_string_\d+='([^']+)'/g;
let match;
const svgStrings = {};
// 遍历匹配的结果,提取所有 SVG 字符串
while ((match = svgRegex.exec(pageContent)) !== null) {
const svgContent = match[1];
let replacedHtml = svgContent.replace(/</g, "<");
replacedHtml = replacedHtml.replace(/>/g, ">");
console.log(match[1], "biu", replacedHtml);
const dom = new JSDOM(replacedHtml);
const document = dom.window.document;
// 定义用于存储 SVG 数据的对象
const extractedIcons = {};
// 遍历每个 SVG 元素
Array.from(document.querySelectorAll("symbol")).forEach((svgElement) => {
const symbolId = svgElement.getAttribute("id");
const viewBox = svgElement.getAttribute("viewBox");
// 获取所有 path 元素
const pathElements = svgElement.querySelectorAll("path");
// 构建 paths 数组
const paths = [];
pathElements.forEach((pathElement) => {
const pathData = {
_tag: "path",
d: pathElement.getAttribute("d"),
fill: pathElement.getAttribute("fill"),
// 可以根据需要添加更多属性
};
paths.push(pathData);
});
// 构建每个图标的对象
extractedIcons[symbolId] = {
viewBox: viewBox,
paths: paths,
};
});
// 将每个 SVG 数据存储到对象中
Object.assign(svgStrings, extractedIcons);
}
// 构造 TypeScript 文件内容
const fileContent = `export const svgIcon = ${JSON.stringify(
svgStrings,
null,
2
)};\n`;
// 将内容写入 TypeScript 文件
fs.writeFile(outputIconFile, fileContent, "utf8", (err) => {
if (err) {
console.error("Error writing TypeScript file:", err);
return;
}
console.log(`Extracted SVG icons saved to ${outputIconFile}`);
});
} catch (error) {
console.error("Error extracting SVG icons:", error);
} finally {
await browser.close();
}
})();
虽然实现了,但是需要额外指定浏览器配置,所以改成如下(代码注释没有整理):
// const puppeteer = require("puppeteer-core");
const fs = require("fs");
const { JSDOM } = require("jsdom");
const path = require("path");
const https = require("https");
const processArgs = process.argv.slice(2);
// 定义 Iconfont 网址和输出文件名
const iconfontUrl = "https://" + processArgs[0];
const outputIconFile = "../xxApp/src/" + processArgs[1];
(async () => {
// const browser = await puppeteer.launch({
// executablePath: "C:/Program Files/Google/Chrome/chrome.exe", // 你的 Chrome 或 Chromium 可执行文件路径
// headless: true, // 设置为 true 表示无头模式,不会打开浏览器窗口
// });
// const page = await browser.newPage();
try {
// 访问 Iconfont 网址
// await page.goto(iconfontUrl, { waitUntil: "networkidle0" });
// const pageContent = await page.content();
// let pageContent = "";
const pageContent = await new Promise((resolve, reject) => {
let result = "";
https.get(iconfontUrl, (response) => {
if (response.statusCode !== 200) {
reject(`Request failed with status code ${response.statusCode}`);
return;
}
response.on("data", (res) => {
result += res;
});
response.on("end", () => {
resolve(result);
});
response.on("error", (err) =>
console.error("Error request for url:", err)
);
});
});
// 使用正则表达式从页面内容中匹配 SVG 字符串
const svgRegex = /window\._iconfont_svg_string_\d+='([^']+)'/g;
let match;
const svgStrings = {};
// 遍历匹配的结果,提取所有 SVG 字符串
while ((match = svgRegex.exec(pageContent)) !== null) {
const svgContent = match[1];
// let replacedHtml = svgContent.replace(/</g, "<");
// replacedHtml = replacedHtml.replace(/>/g, ">");
const dom = new JSDOM(svgContent);
const document = dom.window.document;
// 定义用于存储 SVG 数据的对象
const extractedIcons = {};
// 遍历每个 SVG 元素
Array.from(document.querySelectorAll("symbol")).forEach((svgElement) => {
const symbolId = svgElement.getAttribute("id");
const viewBox = svgElement.getAttribute("viewBox");
// 获取所有 path 元素
const pathElements = svgElement.querySelectorAll("path");
// 构建 paths 数组
const paths = [];
pathElements.forEach((pathElement) => {
const pathData = {
_tag: "path",
d: pathElement.getAttribute("d"),
fill: pathElement.getAttribute("fill"),
// 可以根据需要添加更多属性
};
paths.push(pathData);
});
// 构建每个图标的对象
extractedIcons[symbolId] = {
viewBox: viewBox,
paths: paths,
};
});
// 将每个 SVG 数据存储到对象中
Object.assign(svgStrings, extractedIcons);
dom.window.close()
}
// 构造 TypeScript 文件内容
const fileContent = `export const svgIcon = ${JSON.stringify(
svgStrings,
null,
2
)};\n`;
// 将内容写入 TypeScript 文件
fs.writeFile(outputIconFile, fileContent, "utf8", (err) => {
if (err) {
console.error("Error writing TypeScript file:", err);
return;
}
console.log(`Extracted SVG icons saved to ${outputIconFile}`);
});
} catch (error) {
console.error("Error extracting SVG icons:", error);
} finally {
// await browser.close();
}
})();
手动 获取Symbol 链接,node 运行文件就可以在对应的icons.ts 自动生成svg数据了
export const svgIcon = {
"icon-fxshanchu": {
"viewBox": "0 0 1024 1024",
"paths": [
{
"_tag": "path",
"d": "M189.124926 206.817739 834.875074 206.817739C824.056355 206.817739 815.037987 197.278738 815.718488 186.375821L766.845228 969.422054C767.420593 960.203599 774.673955 953.37931 784.03501 953.37931L239.96499 953.37931C249.232543 953.37931 256.586205 960.312638 257.154772 969.422054L208.281512 186.375821C208.961624 197.272664 199.982115 206.817739 189.124926 206.817739ZM186.671228 973.821228C188.422497 1001.879852 211.883661 1024 239.96499 1024L784.03501 1024C811.990051 1024 835.582287 1001.80337 837.328772 973.821228L886.202033 190.774996C888.065218 160.922854 864.68894 136.197049 834.875074 136.197049L189.124926 136.197049C159.269853 136.197049 135.939407 160.996952 137.797967 190.774996L186.671228 973.821228ZM971.034483 206.817739C990.535839 206.817739 1006.344828 191.00875 1006.344828 171.507394 1006.344828 152.00602 990.535839 136.197049 971.034483 136.197049L52.965517 136.197049C33.464161 136.197049 17.655172 152.00602 17.655172 171.507394 17.655172 191.00875 33.464161 206.817739 52.965517 206.817739L971.034483 206.817739ZM358.849148 206.817739 665.150852 206.817739C694.015417 206.817739 717.323123 183.246901 717.323123 154.533323L717.323123 52.284416C717.323123 23.465207 693.830144 0 665.150852 0L358.849148 0C329.984583 0 306.676877 23.570838 306.676877 52.284416L306.676877 154.533323C306.676877 183.352514 330.169856 206.817739 358.849148 206.817739ZM377.297567 52.284416C377.297567 62.397193 369.165877 70.62069 358.849148 70.62069L665.150852 70.62069C654.846093 70.62069 646.702433 62.486652 646.702433 52.284416L646.702433 154.533323C646.702433 144.420529 654.834123 136.197049 665.150852 136.197049L358.849148 136.197049C369.153907 136.197049 377.297567 144.331087 377.297567 154.533323L377.297567 52.284416ZM595.6986 835.467988C595.6986 854.969344 611.507571 870.778333 631.008945 870.778333 650.510301 870.778333 666.319289 854.969344 666.319289 835.467988L666.319289 324.729062C666.319289 305.227705 650.510301 289.418717 631.008945 289.418717 611.507571 289.418717 595.6986 305.227705 595.6986 324.729062L595.6986 835.467988ZM428.3014 324.729062C428.3014 305.227705 412.492429 289.418717 392.991055 289.418717 373.489699 289.418717 357.680711 305.227705 357.680711 324.729062L357.680711 835.467988C357.680711 854.969344 373.489699 870.778333 392.991055 870.778333 412.492429 870.778333 428.3014 854.969344 428.3014 835.467988L428.3014 324.729062Z",
"fill": "#389BFF"
}
]
},
"icon-fxtianjia": {
"viewBox": "0 0 1024 1024",
"paths": [
{
"_tag": "path",
"d": "M953.37931 512C953.37931 268.232939 755.767084 70.62069 512 70.62069 268.232934 70.62069 70.62069 268.232939 70.62069 512 70.62069 755.767061 268.232934 953.37931 512 953.37931 755.767084 953.37931 953.37931 755.767061 953.37931 512ZM547.310345 476.689655 547.310345 264.858364C547.310345 245.21731 531.501374 229.517241 512 229.517241 492.362681 229.517241 476.689655 245.340001 476.689655 264.858364L476.689655 476.689655 264.858359 476.689655C245.217315 476.689655 229.517241 492.498635 229.517241 512 229.517241 531.637326 245.340001 547.310345 264.858359 547.310345L476.689655 547.310345 476.689655 759.141636C476.689655 778.78269 492.498626 794.482759 512 794.482759 531.637319 794.482759 547.310345 778.659999 547.310345 759.141636L547.310345 547.310345 759.141694 547.310345C778.78272 547.310345 794.482759 531.501365 794.482759 512 794.482759 492.362674 778.660017 476.689655 759.141694 476.689655L547.310345 476.689655ZM0 512C0 229.230209 229.230204 0 512 0 794.769832 0 1024 229.230209 1024 512 1024 794.769791 794.769832 1024 512 1024 229.230204 1024 0 794.769791 0 512Z",
"fill": "#389BFF"
}
]
},
"icon-fxsousuo": {
"viewBox": "0 0 1024 1024",
"paths": [
{
"_tag": "path",
"d": "M456.32 176a312.32 312.32 0 1 1-312.32 312.32 312.32 312.32 0 0 1 312.32-312.32m0-64A376.32 376.32 0 1 0 832 488.32a376.32 376.32 0 0 0-375.68-376.32z",
"fill": "#2C2C2C"
},
{
"_tag": "path",
"d": "M709.76 709.76a32 32 0 0 0-22.4 54.4l181.12 181.12a32 32 0 0 0 45.44-45.44l-181.12-181.12a32 32 0 0 0-22.4-9.6z",
"fill": "#2C2C2C"
}
]
}
};
写的时候踩了个坑,直接赋值取用document.querySelectorAll("symbol")只能获取一个空对象
贴代码可以直接用,package.json 创建命令行: "update:icon": "node ./src/xxx/updateIconFont.js //at.alicdn.com/t/c/xxxxx.js output路径"