安装Hexo
npm install hexo-cli -g
hexo init
npm install hexo-renderer-pug hexo-renderer-stylus --save
npm install hexo-deployer-git --save安装Solitude
git clone -b main https://github.com/everfu/hexo-theme-solitude.git themes/solitude在博客根目录运行bash命令,将主题的配置文件复制到根目录,以便方便配置主题。
{% tabs copy [index] %}
cp -rf ./themes/solitude/_config.yml ./_config.solitude.ymlcopy .\themes\solitude\_config.yml .\_config.solitude.yml{% endtabs %}
配套插件
Solitude外挂标签
npm install hexo-solitude-tag文章生成短链接
npm install hexo-abbrlink --save_config.yml找到#url修改以下:
# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
url: https://www.jinjun.top
#permalink: :year/:month/:day/:title/
#permalink_defaults:
permalink: posts/:abbrlink.html
# 文章链接转:https://github.com/rozbo/hexo-abbrlink
abbrlink:
alg: crc16 #support crc16(default) and crc32
rep: hex #support dec(default) and hex
pretty_urls:
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
trailing_html: true # Set to false to remove trailing '.html' from permalinks本地搜索
npm install hexo-generator-search --savealgolia搜索
npm install hexo-algoliasearch --save申请Id/API地址:https://www.algolia.com/
_congif.yml添加配置内容:
# algolia搜索: https://github.com/LouisBarranqueiro/hexo-algoliasearch
algolia:
appId: "Z7A3XW4R2I"
apiKey: "12db1ad54372045549ef465881c17e743"
adminApiKey: "40321c7c207e7f73b63a19aa24c4761b"
chunkSize: 5000
indexName: "my-hexo-blog"
fields:
- content:strip:truncate,0,500
- excerpt:strip
- gallery
- permalink
- photos
- slug
- tags
- titleRss
npm install hexo-generator-feed --saveSitemap
npm install hexo-generator-sitemap --save_congig.yml添加配置内容:
# https://github.com/hexojs/hexo-generator-sitemap
sitemap:
path: sitemap.xml
tags: true
categories: trueBaiduSitemap
npm install hexo-generator-baidu-sitemap --save_congig.yml 添加配置内容
baidusitemap:
path: baidusitemap.xmlhexo-indexnow
Bing搜索引擎,IndexNow插件
npm install hexo-indexnow --save_config.yml 添加配置内容
hexo_indexnow:
count: latest # 数字或者 "latest"(=1)
txt_name: indexnow.txt # 链接文件名
apikey: xxxxxx # 你的 apikey
server: bing # indexnow 服务器,可选值有:bing、yandex、indexnow
deploy:
- type: indexnow_url_submitter字数统计
npm install hexo-wordcount --save安全转跳插件
npm install hexo-safego --save_config.yml 添加配置内容:
# hexo-safego安全跳转插件
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
enable: true # 是否启用 hexo-safego 插件
enable_base64_encode: true # 是否启用 Base64 编码链接
enable_target_blank: true # 是否在跳转链接中添加 target="_blank"
url_param_name: 'u' # URL 参数名,用于生成跳转链接
html_file_name: 'go.html' # 跳转页面文件名
ignore_attrs: # 需要忽略的链接属性列表
- 'data-fancybox'
apply_containers: # 容器 ID 列表,如果为空则匹配整个 body
- '#article-container'
domain_whitelist: # 域名白名单列表,包含白名单中的域名的链接将被忽略
- 'jinjun.top'
apply_pages: # 生效页面路径列表,只有在这些页面上才会对链接进行处理
- '/posts/'
avatar: /img/siteicon/manifest-icon-192.maskable.png # 头像图片链接
title: "钧言极客" # 标题
subtitle: "安全中心" # 副标题
darkmode: true # 是否启用夜间模式
debug: false # 是否启用调试模式,开启后会输出详细的调试信息Gulp
npm install gulp compress gulp-clean-css gulp-html-minifier-terser gulp-htmlclean gulp-terser --save-dev在博客根目录新建 gulpfile.js 文件
var gulp = require('gulp');
var cleanCSS = require('gulp-clean-css');
var htmlmin = require('gulp-html-minifier-terser');
var htmlclean = require('gulp-htmlclean');
var terser = require('gulp-terser');
// 压缩js
gulp.task('compress', () =>
gulp.src(['./public/**/*.js', '!./public/**/*.min.js'])
.pipe(terser())
.pipe(gulp.dest('./public'))
)
//压缩css
gulp.task('minify-css', () => {
return gulp.src(['./public/**/*.css'])
.pipe(cleanCSS({
compatibility: 'ie11'
}))
.pipe(gulp.dest('./public'));
});
//压缩html
gulp.task('minify-html', () => {
return gulp.src('./public/**/*.html')
.pipe(htmlclean())
.pipe(htmlmin({
removeComments: true, //清除html注释
collapseWhitespace: true, //压缩html
collapseBooleanAttributes: true,
//省略布尔属性的值,例如:<input checked="true"/> ==> <input />
removeEmptyAttributes: true,
//删除所有空格作属性值,例如:<input id="" /> ==> <input />
removeScriptTypeAttributes: true,
//删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true,
//删除<style>和<link>的 type="text/css"
minifyJS: true, //压缩页面 JS
minifyCSS: true, //压缩页面 CSS
minifyURLs: true //压缩页面URL
}))
.pipe(gulp.dest('./public'))
});
// 运行gulp命令时依次执行以下任务
gulp.task('default', gulp.parallel(
'compress', 'minify-css', 'minify-html'
))Swpp
npm install hexo-swpp swpp-backends --save在博客根目录新建 sw-rules.js 文件:
module.exports.config = {
/** @type {?ServiceWorkerConfig|boolean} */
serviceWorker: {
escape: 0,
cacheName: 'SolitudeCache',
debug: false,
},
register: {
onsuccess: undefined,
onerror: () =>
console.error(
'Service Worker 注册失败!可能是由于您的浏览器不支持该功能!'
),
builder: (root, framework, pluginConfig) => {
const { onerror, onsuccess } = pluginConfig.register;
return `
<script>
(() => {
const sw = navigator.serviceWorker;
const error = ${onerror && onerror.toString()};
if (!sw?.register('${new URL(root).pathname}sw.js')
${onsuccess ? `?.then(${onsuccess.toString()})` : ""}
?.catch(error)
) error()
})()
</script>`;
},
},
/** @type {?DomConfig|boolean} */
dom: {
/** @type {?VoidFunction} */
onsuccess: () => {
caches
.match(location.href)
.then((res) => {
if (res)
res.json().then((json) => {
utils &&
utils.snackbarShow(
`已刷新缓存,更新为${json.global + '.' + json.local
}版本最新内容`,
false,
2000
);
});
else console.info('未找到缓存');
})
.catch((error) => console.error('缓存匹配出错', error));
},
},
/** @type {?VersionJsonConfig|boolean} */
json: {
/** @type {number} */
maxHtml: 15,
/** @type {number} */
charLimit: 1024,
/** @type {string[]} */
merge: [],
exclude: {
/** @type {RegExp[]} */
localhost: [],
/** @type {RegExp[]} */
other: [],
},
},
/** @type {?ExternalMonitorConfig|boolean} */
external: {
/** @type {number} */
timeout: 5000,
/** 拉取文件时地并发限制 */
concurrencyLimit: 100,
/** @type {({head: string, tail: string}|function(string):string[])[]} */
js: [],
/** @type {RegExp[]} */
stable: [
/^https:\/\/npm\.elemecdn\.com\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
/^https:\/\/cdn\.cbd\.int\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
/^https:\/\/cdn\.jsdelivr\.net\/npm\/[^/@]+\@[^/@]+\/[^/]+\/[^/]+$/,
],
replacer: (srcUrl) => {
if (srcUrl.startsWith('https://cdn.jsdelivr.net/npm/')) {
const pathname = new URL(srcUrl).pathname;
return [
srcUrl,
`https://cdn.cbd.int/${pathname}`,
`https://npm.elemecdn.com/${pathname}`,
`https://fastly.jsdelivr.net/npm/${pathname}`,
];
} else {
return srcUrl;
}
},
},
};
module.exports.cacheRules = {
simple: {
clean: true,
search: false,
match: (url, $eject) =>
url.host === $eject.domain && ['/404.html'].includes(url.pathname),
},
cdn: {
clean: true,
match: (url) =>
[
'cdn.cbd.int',
'lf26-cdn-tos.bytecdntp.com',
'lf6-cdn-tos.bytecdntp.com',
'lf3-cdn-tos.bytecdntp.com',
'lf9-cdn-tos.bytecdntp.com',
'cdn.staticfile.org',
'npm.elemecdn.com',
].includes(url.host) &&
url.pathname.match(/\.(js|css|woff2|woff|ttf|cur)$/),
},
};
module.exports.getSpareUrls = (srcUrl) => {
if (srcUrl.startsWith('https://npm.elemecdn.com')) {
return {
timeout: 3000,
list: [
srcUrl,
`https://fastly.jsdelivr.net/${new URL(srcUrl).pathname}`,
],
};
}
};
module.exports.ejectValues = (hexo, rules) => {
return {
domain: {
prefix: 'const',
value: new URL(hexo.config.url).host,
},
};
};
module.exports.skipRequest = (request) => request.url.startsWith("https://i0.hdslb.com") ||
request.url.startsWith('https://meting.qjqq.cn') ||
request.url.startsWith('https://api.i-meto.com');
评论