还在用Hexo吗?来试试Gatsby搭建一个网站吧!

还在用Hexo吗?来试试Gatsby搭建一个网站吧!
LeK还在用Hexo吗?来试试Gatsby搭建一个网站吧!
Gatsby 是一个基于 React 的、免费开源的、用于搭建静态站点的框架。
前言
最近发现了一个好看的个人主页模板,是用Gatsby搭建的,之前没听说过这个框架,也没有React经验,所以踩了很多坑,为了加一个不蒜子功能整了两天才整明白……但是gatsby的官方文档我觉得写得是很好的,最终结果也是令我比较满意的,所以跟着我的脚步避开这些坑开始愉快的Gatsby体验吧!
最终结果可以去我的个人网站看下:http://www.lekshome.top/
开源地址:https://github.com/LeKZzzz/lekshome
1. 配置
我的环境如下:
- Ubuntu 20.04
- Node.js v20.9.0
- Gatsby-CLI 5.13.3
-
Node.js(Gatsby v5需要Node.js v18 或更高版本,但低于 v21)
1
2
3sudo apt-get install curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
nvm install 20.9.0Git
这部分网上很多,就不演示了
Gatsby CLI
1
npm install -g gatsby-cli
可以运行
gatsby --version
检查版本是否正确
网站模板
这部分我用的是 https://github.com/bchiang7/v4 的网站模板,接下来也会以此为演示。
clone模板
可以先创建一个独立文件夹然后再clone
1
2
3
4mkdir website
cd website
git clone https://github.com/bchiang7/v4.git
cd v4下载必要模块
请先删除yarn.lock文件
1
2
3rm yarn.lock
npm install gatsby-plugin-robots-txt@1.6.14
npm install
配置socket.io的端口环境变量
端口可以自行设定,但是请确保这个端口在防火墙是放开的
https://www.reddit.com/r/gatsbyjs/comments/krifvb/gatsby_randomize_socketio_port_breaking_vagrant/
1
2
3
4
5
6vim ~/.bashrc
文件末尾添加
export INTERNAL_STATUS_PORT=1234
source ~/.bashrc验证是否可以正常启动
1
gatsby develop --host=0.0.0.0
出现这些输出同时可以在浏览器中可以访问则说明环境配置正确
2. DIY网站
基本配置
gatsby-config.js
这里可以修改你的网站title、网站描述、siteUrl等
src/config.js
这里可以修改你的邮箱、社交媒体账号、添加nav导航的元素等
static/resume.pdf
可以将这个文件替换为你的简历
src/images/me.jpg
可以将这个文件替换为你的个人照片
src/components/sections/about.js
在这个文件中可以修改个人介绍
src/components/sections/contact.js
在这个文件中可以修改邮件联系文本
src/components/sections/hero.js
在这个文件中可以修改开屏介绍文本
logo配置
默认logo是英文字母B,如果我们需要改成我们自己的首字母则需要花费一点功夫。
首先需要去figma绘制一个首字母的文本,我的设置如下:
然后导出为svg
修改src/components/icons/loader.js
用刚刚导出的svg的path标签的d属性修改loader.js文件中path标签的d属性,然后修改g标签中的transform属性,transform属性需要根据实际结果手动调整为合适数值
修改src/components/icons/logo.js
将修改过后的src/components/icons/loader.js文件中的
<g>
标签及其子标签复制替换src/components/icons/logo.js中的<path>
标签及其子标签修改src/images/logo.png
这个是标签栏上的logo,可以参考他原有的图片,将代码生成的logo截图再裁剪得到
由于手头没有修图软件,我是用PPT裁剪的huh:)
footer配置(不蒜子)
footer文本
这部分可以根据个人喜好进行修改,我的修改如下
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Icon } from '@components/icons';
import { socialMedia } from '@config';
const StyledFooter = styled.footer`
${({ theme }) => theme.mixins.flexCenter};
flex-direction: column;
height: auto;
min-height: 70px;
padding: 15px;
text-align: center;
`;
const StyledSocialLinks = styled.div`
display: none;
@media (max-width: 768px) {
display: block;
width: 100%;
max-width: 270px;
margin: 0 auto 10px;
color: var(--light-slate);
}
ul {
${({ theme }) => theme.mixins.flexBetween};
padding: 0;
margin: 0;
list-style: none;
a {
padding: 10px;
svg {
width: 20px;
height: 20px;
}
}
}
`;
const StyledCredit = styled.div`
color: var(--light-slate);
font-family: var(--font-mono);
font-size: var(--fz-xxs);
line-height: 1;
a {
padding: 10px;
}
.github-stats {
margin-top: 10px;
& > span {
display: inline-flex;
align-items: center;
margin: 0 7px;
}
svg {
display: inline-block;
margin-right: 5px;
width: 14px;
height: 14px;
}
}
`;
const StyledSecond = styled.div`
color: var(--light-slate);
font-family: var(--font-mono);
font-size: var(--fz-xxs);
line-height: 1;
a {
padding: 10px;
}
a:hover{
cursor:default;
}
.github-stats {
margin-top: 10px;
& > span {
display: inline-flex;
align-items: center;
margin: 0 7px;
}
svg {
display: inline-block;
margin-right: 5px;
width: 14px;
height: 14px;
}
}
`;
const Footer = () => {
const [githubInfo, setGitHubInfo] = useState({
stars: null,
forks: null,
});
const [githubInfo2, setGitHubInfo2] = useState({
stars: 0,
forks: 0,
});
useEffect(() => {
const fetchGitHubData = async () => {
try {
await Promise.all([
fetch('https://api.github.com/repos/bchiang7/v4')
.then(response => response.json())
.then(data => {
setGitHubInfo({
stars: data.stargazers_count,
forks: data.forks_count,
});
}),
fetch('https://api.github.com/repos/LeKZzzz/lekshome')
.then(response => response.json())
.then(data => {
setGitHubInfo2({
stars: data.stargazers_count,
forks: data.forks_count,
});
})
]);
} catch (e) {
console.error('获取 GitHub 仓库信息时出错:', e);
}
};
fetchGitHubData();
// buusanzi
const script = document.createElement('script');
script.async = true;
script.src = "https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js";
document.head.appendChild(script);
}, []);
return (
<StyledFooter>
<StyledSocialLinks>
<ul>
{socialMedia &&
socialMedia.map(({ name, url }, i) => (
<li key={i}>
<a href={url} aria-label={name}>
<Icon name={name} />
</a>
</li>
))}
</ul>
</StyledSocialLinks>
<StyledCredit tabindex="-1">
<a href="https://github.com/bchiang7/v4">
<div>Built by Brittany Chiang |</div>
{githubInfo.stars && githubInfo.forks && (
<div className="github-stats">
<span>
<Icon name="Star" />
<span>{githubInfo.stars.toLocaleString()}</span>
</span>
<span>
<Icon name="Fork" />
<span>{githubInfo.forks.toLocaleString()}</span>
</span>
</div>
)}
</a>
<a href="https://github.com/LeKZzzz/lekshome">
<div>| Customized by LeK</div>
{githubInfo.stars && githubInfo.forks && (
<div className="github-stats">
<span>
<Icon name="Star" />
<span>{githubInfo2.stars.toLocaleString()}</span>
</span>
<span>
<Icon name="Fork" />
<span>{githubInfo2.forks.toLocaleString()}</span>
</span>
</div>
)}
</a>
</StyledCredit>
<StyledSecond tabindex="-1">
<a>
<div>
Last update on 2024/08/15 |
</div>
</a>
<a>
<div>
| Total visits <span id="busuanzi_value_site_pv"></span> times
</div>
</a>
</StyledSecond>
<StyledCredit tabindex="-1">
<div align="center"><a href="https://beian.miit.gov.cn/" target="_blank">粤ICP备2022018241号</a></div>
</StyledCredit>
</StyledFooter>
);
};
Footer.propTypes = {
githubInfo: PropTypes.object,
};
export default Footer;不蒜子
我应该是国内第一个在这个模板里集成不蒜子的,这个功能折磨了我三天,不蒜子的一般使用方法是使用一个
<script>
标签,但是由于这个模板完全右js构建,所以普通的方法是无法正确访问不蒜子的;而且由于网页元素是js动态写入的,所以不能通过导入的方式导入不蒜子;我发现只能从useEffect入手,然后仔细看了代码发现模板原有的star和fork获取是没有展示出来的,于是又多了个要改的地方……为此我还专门提了个issue,提完的下午发现是NODE_ENV没有正确配置而提前return了,导致后面的代码都没有执行……export NODE_ENV之后再运行,结果gatsby报错无法正常启动……最后还是选择把这个环境判断给注释掉,后面footer就能正常使用了。但是后面还遇到了异步问题,就不多赘述了。唉,花了三天时间来找问题和debug。
工作经历配置
修改content/jobs中的文件夹
每个工作经历要新建一个文件夹
进入文件夹,添加index.md文件
配置index.md文件,如下例
1
2
3
4
5
6
7
8---
date: '2024-07-10'
title: 'Software Development Intern'
company: 'CSAIR'
location: 'Guangzhou, China'
range: 'July - August 2024'
url: 'https://www.csairgroup.cn/cn/'
---- date:决定jobs展示时的先后顺序
- title:职位
- company:公司
- location:工作地点
- range:工作开始时间和结束时间
- url:公司官网链接
个人作品配置
修改content/featured文件夹
这个文件夹是关于个人作品最上方展示Featured Project的,添加方式为在featured文件夹中新建文件夹再新建一个index.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18---
date: '1'
title: 'Wholz'
cover: './wholz.png'
github: 'https://github.com/LeKZzzz/wholz'
external: 'https://github.com/LeKZzzz/wholz'
tech:
- Java
- Python
- HTML
- CSS
- Vue
- Unity3D
- MySQL
---
Using VR virtual reality as a carrier, an immersive learning environment is created. Teaching videos are combined with 3D models to realize the visualization of mind map nodes. Users can interact with the LLM to realize real-time question and answer, making the learning content more vivid and intuitive.- date:决定展示顺序,越小优先级越高
- title:project的名字
- cover:project图片
- github:指向github地址
- external:跳转链接
- cta:使用cta则使用“learn more”按钮来跳转链接
- tech:标签
修改content/projects文件夹
以原有文章为例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16---
date: '2019-11-12'
title: 'Moms Demand Action Mobile App'
github: ''
external: 'https://www.upstatement.com/work/moms-demand-action/'
ios: 'https://apps.apple.com/us/app/demand-action/id1475502876'
android: 'https://play.google.com/store/apps/details?id=com.momsdemandaction.app'
tech:
- NativeScript Vue
- iOS
- Android
company: 'Upstatement'
showInProjects: false
---
简介- date:时间
- title:标题
- github:指向github的链接
- external:跳转链接
- ios:appstore链接
- android:google play链接
- tech:标签
- company:公司
- showInProjects:是否在网站首页展示,否则只有/archive里才能看见
改成中文后不知道为什么一行只有一个project,所以我的网站删去了这部分内容,只保留了archive的跳转
icon配置
- src/components/icons中添加新icon的js文件
- 仿照已有icon的js文件,将新icon的svg写入新文件
- src/components/icons/icon.js中添加新的Icon组件和映射
- 在src/components/icons/index.js中添加新的组件
- 在src/config.js中添加新的social图标和链接
写在最后
环境问题真是消耗了我很长时间,因为我本是没有接触过react的,所以很多地方都得现查,写这篇博客也是希望读者能少踩我踩过的坑。
模板作者Brittany Chiang着重提到“ All I ask of you all is to not claim this effort as your own.”,所以请不要使用这个模板而声称是自己原创,这种行为只会消耗开源作者的热情,所以请保持在footer链接到Brittany Chiang的开源仓库。
推荐阅读