文章摘要
青桔 GPT 4
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
投诉

安装Hexo

1
2
3
4
npm install hexo-cli -g
hexo init
npm install hexo-deployer-git --save
npm install hexo-renderer-pug hexo-renderer-stylus --save

安装Solitude

1
git clone -b main https://github.com/everfu/hexo-theme-solitude.git themes/solitude

在博客根目录运行以下命令,将主题的配置文件复制到根目录,以便更好地配置主题。

1
cp -rf ./themes/solitude/_config.yml ./_config.solitude.yml
1
copy .\themes\solitude\_config.yml .\_config.solitude.yml

修改 _config.yml

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site
title: 青桔气球
subtitle: 分享网络安全与科技生活
description: 欢迎来到青桔气球,这是一个专注于网络安全和科技生活分享的网站。在青桔气球上,您可以找到关于WordPress、Hexo、Typecho等平台的详细教程。
keywords: 青桔气球,青桔博客,青桔,qjqq,网络安全,技术教程,科技新闻,科技趋势,数字安全,数字化生活,隐私保护
author: 青桔
language: zh-CN # 语言
timezone: 'Asia/Shanghai' # 时区

# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
url: https://blog.qjqq.cn
permalink: posts/:abbrlink.html
permalink_defaults:
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

# Directory
source_dir: source # 源文件目录
public_dir: public # 生成文件目录
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link:
enable: true # Open external links in new tab
field: site # Apply to the whole site
exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
syntax_highlighter: highlight.js
highlight:
line_number: true
auto_detect: false
tab_replace: ''
wrap: true
hljs: false
prismjs:
preprocess: true
line_number: true
tab_replace: ''

# Home page setting
# path: Root path for your blogs index page. (default = '')
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
path: ''
per_page: 10
order_by: -date

# Category & Tag
default_category: uncategorized
category_map:
tag_map:

# Metadata elements
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
meta_generator: true

# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss
## updated_option supports 'mtime', 'date', 'empty'
updated_option: 'mtime'

# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# Include / Exclude file(s)
## include:/exclude: options only apply to the 'source/' folder
include:
exclude:
ignore:

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: solitude


deploy:
type: git
repo: xx@xx.xx.xx:/home/pear/blog.git
branch: master



# 文章链接转数字或字母:https://github.com/rozbo/hexo-abbrlink
abbrlink:
alg: crc16 #算法: crc16(default) and crc32
rep: hex #进制: dec(default) and hex: dec #输出进制:十进制和十六进制,默认为10进制。丨dec为十进制,hex为十六进制


# https://github.com/hexojs/hexo-generator-sitemap
sitemap:
path: sitemap.xml
rel: false
tags: true
categories: true


# https://github.com/coneycode/hexo-generator-baidu-sitemap
baidusitemap:
path: baidusitemap.xml

# https://github.com/hexojs/hexo-generator-feed
#Feed Atom
feed:
enable: true
type: atom
path: atom.xml
limit: 20
content:

swpp:
# 是否启用插件
enable: true
# 是否在发布前自动执行脚本
# auto_exec: true
# 构建时拉取版本文件的警告等级,缺省为 1(该功能仅在 swpp-backends 版本号 >= 2.1.2 时可用)
# 0 - 表示不允许出现 404 情况;1 - 表示允许服务器返回 404 状态码;2 - 表示允许任何 404(包括 DNS 解析失败等)
# warn_level: 1
# 检查版本的 URL,不能以 '/' 结尾
# npm_url: 'https://npm.lemonso.com'

markdown:
preset: 'default' # 使用的 MD 语法,默认使用的 GFM
render:
html: true # 渲染 html
xhtmlOut: false
langPrefix: 'language-' # 在代码块的类名中添加前缀(指定语言时)。
breaks: true
linkify: true # 如果你写了一个链接而不是 [name](link) 方式,会自动识别为链接并渲染。
typographer: true # 将替换常见的印刷元素。
quotes: '“”‘’' # 替换文章张的 "" '' 号
enable_rules:
disable_rules:
plugins: # 使用插件
anchors:
level: 2 # 渲染标题的级别(h1,h2,h3)
collisionSuffix: ''
permalink: true
permalinkClass: 'headerlink'
permalinkSide: 'left'
permalinkSymbol: ''
case: 0
separator: '-'
images: # 图片的一些编译
lazyload: true # 是否需要渲染 lazyload
prepend_root: false
post_asset: false
inline: false

安装插件

配置文章链接转数字或字母

1
npm install hexo-abbrlink --save

_config.yml添加配置项:

1
2
3
4
# 文章链接转数字或字母:https://github.com/rozbo/hexo-abbrlink
abbrlink:
alg: crc16 #算法: crc16(default) and crc32
rep: hex #进制: dec(default) and hex: dec #输出进制:十进制和十六进制,默认为10进制。丨dec为十进制,hex为十六进制

本地搜索依赖

1
npm install hexo-generator-search --save

Rss

1
npm install hexo-generator-feed --save

字数统计

1
npm install hexo-wordcount --save

Gulp

1
npm install gulp compress gulp-clean-css gulp-html-minifier-terser gulp-htmlclean gulp-terser --save-dev

根目录新建 gulpfile.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
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

1
npm install hexo-swpp swpp-backends --save

根目录新建 sw-rules.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
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
137
138
139
140
141
142
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');