惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
L
LangChain Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
T
Tailwind CSS Blog
T
The Blog of Author Tim Ferriss
U
Unit 42
B
Blog
N
Netflix TechBlog - Medium
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
O
OpenAI News
M
MIT News - Artificial intelligence
D
DataBreaches.Net
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
LINUX DO - 热门话题
C
CERT Recently Published Vulnerability Notes
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News and Events Feed by Topic
Vercel News
Vercel News
T
Tenable Blog
Security Latest
Security Latest
C
Check Point Blog
云风的 BLOG
云风的 BLOG
PCI Perspectives
PCI Perspectives
月光博客
月光博客
TaoSecurity Blog
TaoSecurity Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Project Zero
Project Zero
雷峰网
雷峰网
IT之家
IT之家
H
Hacker News: Front Page
Microsoft Security Blog
Microsoft Security Blog
B
Blog RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Last Week in AI
Last Week in AI
G
Google Developers Blog
Forbes - Security
Forbes - Security
The Register - Security
The Register - Security
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Martin Fowler
Martin Fowler
K
Kaspersky official blog
P
Proofpoint News Feed
T
Threatpost
Google Online Security Blog
Google Online Security Blog
Microsoft Azure Blog
Microsoft Azure Blog

秋实-Allenyou 的小窝

【笔记】人工智能与模式识别 复习笔记 - 秋实-Allenyou 的小窝 【教程】使用 Keyd 将 Copilot 键映射为可用的组合键并修复触摸板防误触失效问题 机械革命无界 15X 的 Arch Linux 开荒指南 我在用什么?(2026 版) - 秋实-Allenyou 的小窝 关于 Next.js SSG 生成 RSS Feed 文件的另一思路 从零开始的 NixOS 体验 - 秋实-Allenyou 的小窝 2025:迷茫中转向 - 秋实-Allenyou 的小窝 我在用什么?(2025 版) - 秋实-Allenyou 的小窝 【杂谈】关于 AIGC 的一些思考 - 秋实-Allenyou 的小窝 【记录】一种在主机通过 Docker 容器名解析容器 IP 的方法 【记录】如何在 Next.js 中优雅的调用 Matomo 统计 从信号与系统角度看 OI/XCPC 中的傅里叶变换运用 - 秋实-Allenyou 的小窝 【杂谈】答《博客作者呀,我想采访你这 9 个问题!》 - 秋实-Allenyou 的小窝 使用 Golang 重写 gh-proxy - 秋实-Allenyou 的小窝 FurryCTF 2024 寒假赛 调试窗口 题解 2024:“我”的大学生活 - 秋实-Allenyou 的小窝 【游记】CCPC 2024 重庆站尾杀记 - 秋实-Allenyou 的小窝 【游记】ICPC 2024 亚洲区域赛南京站打铁记 - 秋实-Allenyou 的小窝 【杂谈】这次 Furrygooo 结束后我的一些体验 - 秋实-Allenyou 的小窝 【教程】使用阿里云 OSS + CDN 加速 Gravatar 【记录】 一次罗技鼠标驱动冲突问题的排查经历 - 秋实-Allenyou 的小窝 【教程】如何用 Git 快速搭建简单的 CI - 秋实-Allenyou 的小窝 我的DN42 Peering信息 - 秋实-Allenyou 的小窝 【进度】博客重构计划 - 秋实-Allenyou 的小窝 这是一个正经的2023总结 - 秋实-Allenyou 的小窝 【题解】Luogu P9769 [HUSTFC 2023] 简单的加法乘法计算题 2023新年谜题总结 - 秋实-Allenyou 的小窝 【教程】浅谈Linux服务器的一些基础安全技巧 - 秋实-Allenyou 的小窝 Goodbye, 2022~ - 秋实-Allenyou 的小窝 【教程】使用 Docker 开服,优雅地隔离不同版本JDK - 秋实-Allenyou 的小窝 【旧文补档】2020年终总结 & 2021新年计划 - 秋实-Allenyou 的小窝 【旧文补档】写个脚本监控你的VPS SolusVM面板适用 - 秋实-Allenyou 的小窝 【旧文补档】建立自己的私人网盘!在CentOS VPS上安装NextCloud - 秋实-Allenyou 的小窝 【旧文补档】2019,再见!2020,你好! - 秋实-Allenyou 的小窝 【旧文补档】新一代USB来袭,一起捋一捋USB的“前世今生” - 秋实-Allenyou 的小窝 【旧文补档】矩阵学习笔记 - 秋实-Allenyou 的小窝
【记录】我是如何用 Next.js 重构我的博客的 - 秋实-Allenyou 的小窝
2024-03-09 · via 秋实-Allenyou 的小窝

前段时间完成了博客的重构,在这里记录一些重构过程中的经验(?)

技术选型

静态 vs 动态

从 2019 年开始,我的博客一直使用 Wordpress/Typecho 等基于 PHP 的 CMS 构建。

动态生成站点内容的好处是显而易见的,比如使用体验良好的管理后台、自带的评论系统、更快的更新站点速度等。此外,相比于需要自行在本地搭建开发环境的 Hexo 等静态博客系统,动态 CMS 更加”开箱即用“的设置也极大降低了搭建博客的门槛。

但是相对的,Wordpress/Typecho 等动态 CMS 的问题也很明显:每次打开页面都需要访问数据库带来的较高 TTFB、与 PHP 深度耦合导致无法使用 React/Vue 等相对更”现代“的前端技术栈……虽然使用 Redis/Memcached 缓存 + 静态资源 CDN 的方案可以缓解,但静态 CMS 方案在 TTFB 上的优势依旧是显而易见的。

考虑到我的服务器基本都是 2C2G 这种入门配置,还是用静态方案吧(

前端:React or Vue?

目前主流的前端框架主要有 React 和 Vue 两大派(其他后起之秀我不了解,这次显然没法用),两个框架提供的特性、性能都大差不差,所以选择哪一个主要取决于上层框架。

在这点上,同样是面向 SSR 的上层框架,基于 React 的 Next.js 拥有远好于基于 Vue 的 Nuxt.js 的生态,出各种问题都能更好地找到资料。

最后权衡一下,选择了 React & Next.js 的前端方案。

CSS:Tailwind CSS 真香

首先声明,我对前端设计一窍不通

因为没有正统学习过前端 HTML + CSS + JS 技术栈,我一直都是以”现用现学“的方法补习这些基础知识。但是同样地,现在让我自己用传统的 CSS/SCSS 去构建博客的前端样式显然会堆成屎山。此外,CSS 优化这个老生常谈的问题显然能直接让我原地爆炸

好在有 Tailwind CSS。

你说得对,但是 Tailwind CSS 是由 Tailwind Labs 自主研发的一款全新 Utilities-first CSS 框架。

正经点说,Tailwind CSS 把原有的众多 CSS 规则全部拆成了 class 的形式,使用时不需要写 CSS,只要直接写 class 就行,每条 className 对应一条简单的规则,比如 p-4 对应 padding: 1rem 规则,在最终构建时 Tailwind CSS Compiler 将扫描代码,提取所有用到的规则名称并且合并为一个 CSS 文件。

更多详情请前往官网

后端:Not Hexo

虽然 Hexo 的 Warehouse 后端用的人很多,但是我这里没有用这个。

一方面是我的博客去除了分类/标签,而 Hexo 有这个,略显麻烦;另一方面我太菜没搞明白文档

所以我写了个简单的后端,使用 frontmatter 库在 .md 文件头写标题、日期之类的 Metadata,通过扫描文件建立临时 CMS。

源代码在 src/libs/content.ts 里面。

技术笔记

图片 Lazyload & 灯箱

这里图片的 Lazyload 优化使用了 Sukka 大佬的实现,代码在这里

同时,我在 <LazyloadImage /> 组件中附加了 medium-zoom 库,添加了图片点击放大的效果。

为了让 Lazyload 和 medium-zoom 的 Ref 不冲突,我将原本官方的 RefCallback 改成了这样:

const myref: RefCallback<HTMLImageElement> = (node) => {
	imageElRef.current = node;
	const zoom = getZoom();
	if (node) {
		zoom.attach(node);
	} else {
		zoom.detach();
	}
};

扩展 Markdown 解析

参照 Sukka 大佬的思路,我在博客构建时通过 markdown-it 库对 Markdown 内容进行解析渲染为 HTML,并通过 htmr 库将生成的 HTML 解析为 React 节点树插入页面。在此过程中,我通过 htmr 库的 transform 参数控制了 HTML 标签的解析方式,将 a 标签解析为自定义的 <AllenyouLink /> 组件,从而实现内外链区分跳转(博客内链在当前页面无刷新跳转,外链使用 _blank 参数在新页面打开),同时将 img 标签解析为 <LazyloadImage /> 组件实现 Lazyload。

同时,由于 Markdown 原生支持内嵌 HTML,在 Markdown 源文件中插入的 HTML 代码会被原样保留。因此,综合考虑后,我对 div 标签的解析做了修改,替换为自定义的 <AllenyouDiv /> 组件。

在此组件中,我添加了属性 component。当 component 为空或不在预先设定的列表中时,将原样解析为 div 标签。若 component 值在预定义的列表中时,将解析为自定义的 React 组件。

目前已经实现的组件有:

  • Bilibili: 嵌入 Bilibili 视频播放器

相关组件在 src/components/MarkdownExtend 下存放。

// src/components/AllenyouDiv.tsx
export default function AllenyouDiv(
	props: JSX.IntrinsicElements["div"] & {
		component?: string;
		children?: React.ReactNode;
	}
) {
	if (props === undefined || !props.hasOwnProperty("component")) {
		return <div>{props.children}</div>;
	}
	if (!customComponents.hasOwnProperty(props.component!)) {
		return <FallbackComponent {...props}>{props.children}</FallbackComponent>;
	}
	const Target = customComponents[props.component!];
	if (props.children === undefined || props.children === null) {
		return <Target {...props} />;
	} else {
		return <Target {...props}>{props.children}</Target>;
	}
}

博客的 CI 构建

在博客的构建上,我选择在本地构建,通过 npm 的 postbuild 钩子将构建好的网站提交到服务器上的 Git 仓库,并在服务器上使用 Git Hook 搭建简单的 CI 实现自动将网站部署到 NGINX 网站目录下,并将静态文件上传到 OSS,刷新 CDN 缓存。

详情请参见这篇文章

未完待续