前言
solitude主题的配置项可以自定义外部调用的地址,但是一直用别人的加速,就怕有一天出现问题导致还需要重新替换
所以打算弄成本地话,本教程基于在 Solitude 上优雅的使用 CDN 加速静态资源文件修改
教程
本教程适用的版本为v3.0.20,若有不同,请自行修改脚本代码
首先就是在根目录创建一个名为plugins.js
的文件,然后将如下代码放进去,其中的isNPM
和foderName
根据实际情况修改
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| #!/usr/bin/env node
const isNPM = false; const foderName = 'plugins';
const fs = require('fs'); const fsPromises = require('fs/promises'); const path = require('path'); const https = require('https');
const THEME_DIR = isNPM ? path.join(__dirname, 'node_modules', 'hexo-theme-solitude') : path.join(__dirname, 'themes', 'solitude'); const PLUGIN_FILE = path.join(THEME_DIR, 'plugins.yml'); const OUTPUT_DIR = path.join(__dirname, foderName);
function parsePluginsYml(text) { const res = {}; let cur = null; text.split(/\r?\n/).forEach(l => { const ln = l.split('#')[0].trimEnd(); if (!ln) return; const sec = ln.match(/^([a-zA-Z0-9_\-]+):\s*$/); if (sec) { cur = sec[1]; res[cur] = {}; return; } const kv = ln.match(/^ ([a-zA-Z0-9_\-]+):\s*(.*)$/); if (kv && cur) { res[cur][kv[1]] = kv[2].trim(); } }); return res; }
async function mkdirp(d) { try { await fsPromises.mkdir(d, { recursive: true }); } catch (e) { if (e.code !== 'EEXIST') throw e; } }
function fetch(url, dest) { return new Promise((resolve, reject) => { const request = https.get(url, (response) => { if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) { response.destroy(); return fetch(response.headers.location, dest).then(resolve, reject); }
if (response.statusCode !== 200) { response.destroy(); return reject(new Error(`${response.statusCode} ${url}`)); }
const fileStream = fs.createWriteStream(dest); response.pipe(fileStream);
fileStream.on('finish', () => { fileStream.close(resolve); });
fileStream.on('error', (err) => { fs.unlink(dest, () => reject(err)); }); }).on('error', (err) => { reject(err); }); }); }
function minFile(f) { return f.replace(/(?<!\.min)\.(js|css)$/i, '.min.$1'); }
function stripDistSegments(f) { return f.replace(/(^|\/)dist\//g, '$1'); }
(async () => { try { const pluginsText = await fsPromises.readFile(PLUGIN_FILE, 'utf8'); const plugins = parsePluginsYml(pluginsText); await mkdirp(OUTPUT_DIR);
for (const [key, def] of Object.entries(plugins)) { if (!def.name || !def.file || !def.version) { console.warn(`[SKIP] ${key} 缺少 name/file/version`); continue; }
const { name, file, version, other_name } = def; const dirName = `${other_name || name}@${version}`;
const cdnFilePath = minFile(stripDistSegments(file)); const url = `https://cdnjs.cloudflare.com/ajax/libs/${other_name || name}/${version}/${cdnFilePath}`; const dest = path.join(OUTPUT_DIR, dirName, stripDistSegments(file)); try { await fsPromises.access(dest); console.log(`[SKIP] ${key}`); continue; } catch (e) { if (e.code !== 'ENOENT') { console.error(`[ERROR] ${key} 访问文件失败: ${e.message}`); continue; } }
console.log(`[DOWN] ${key} → ${dest}`); try { await mkdirp(path.dirname(dest)); await fetch(url, dest); console.log(`[OK] ${key}`); } catch (e) { console.error(`[FAIL] ${key}: ${e.message}`); } } console.log('全部完成!'); } catch (error) { console.error(`脚本执行失败: ${error.message}`); } })();
|
然后就是运行此脚本,在终端输入node plugins.js
即可下载文件到plugins文件夹中
最后就是修改调用方式了
找到_config.solitude.yml
中的CDN类,将third_party
改成custom
然后将custom_format
改成/plugins/${cdnjs_name}@${version}/${min_cdnjs_file}
即可。
有些朋友就会发现控制台会报缺少字体文件,这时候我们需要手动下载这两个字体文件并且放到plugins\font-awesome@6.7.2\webfonts
文件夹中
字体文件:fa-solid-900.woff2和fa-brands-400.woff2
最后一键三连即可。