基于Node.js和Npm部署Astro博客系统
Astro 作为一款高性能的静态站点生成器,凭借“零 JS 运行时”的特性,既能打造加载飞快的博客页面,又能兼顾开发灵活性,成为很多开发者搭建个人博客的首选。本文将从零开始,手把手教你基于 Node.js 和 npm 完成 Astro 博客的环境配置、项目部署与功能开发,内容覆盖基础搭建、文章管理、SEO 优化等核心环节,步骤清晰可直接落地,帮助你快速拥有一个属于自己的轻量化博客站点。
环境准备
1.检查服务器上node和npm的版本情况
node -vnpm -v若出现node和npm对应的版本号,请忽略第2、3、4、5步,若无相关信息,请继续执行第2、3、4、5步。
2.前置准备(可选)
更新系统软件包列表,首先执行更新命令,确保系统软件源是最新的,避免安装过程中出现依赖问题:
apt update && apt upgrade -y如果在执行上述命令时出现 openssh-server 软件包的配置界面(核心是处理 sshd_config 配置文件的版本冲突(系统提供了新配置文件,若当前已安装的配置文件被本地修改过,按本教程操作即可),若没有修改过,请按需选择,当然,也可以和本教程操作保持一致):
① install the package maintainer's version
安装软件包维护者提供的新版本配置文件,无需保留本地修改(如本地配置是临时测试内容)
② keep the local version currently installed
保留当前已安装的本地修改版本,需要保留自定义的 SSH 配置(如修改过端口、禁用密码登录等)
③ show the differences between the versions
显示新旧配置文件的差异,需要先查看修改内容,再决定如何处理
④ show a side-by-side difference between versions
以分栏对比的方式显示差异,更直观地查看新旧配置的具体变化
⑤ show a 3-way merge between available versions
显示三方合并的差异(本地版本、旧版本、新版本),存在多版本配置时,用于复杂的配置合并参考
⑥ do a 3-way merge between available versions
执行三方合并并生成新配置,需要整合本地修改与新版本配置的内容
⑦ start a new shell to examine the situation
启动新 Shell 环境,手动检查配置文件,需要临时查看 / 编辑配置文件后再做决定
推荐操作:
① 优先选择 (第3条) show the differences between the versions查看修改内容,确认本地配置的重要性;
② 若本地配置包含关键自定义(如端口、安全策略),选择 (第2条) keep the local version currently installed;
③ 若本地配置无特殊需求,选择 (第1条) install the package maintainer's version以使用官方最新配置。
3.重启系统(可选)
如果执行了第2步操作,我们这里可以选择重启系统(使第2步中更新 / 升级的软件包完全生效),该操作为安全重启,所有进程都会正常退出(耐心等待一会儿即可):
reboot4.安装 Node.js 和 npm (可选)
我们可通过 apt install 直接安装,执行以下命令即可完成基础安装,同时安装 nodejs 和 npm,npm 会作为 nodejs 的配套工具一同部署:
apt install nodejs npm -y若在执行该命令的过程中没有出现任何异常情况,则可以正常进行下一步操作。
5.验证 Node.js 和 npm (可选)
操作与第1步一样,检查服务器上node和npm的版本情况:
node -v
npm -v若出现node和npm对应的版本号,则表示Node.js 和 npm安装成功。若无相关信息,检查报错提示,然后再返回第2、3、4、5步,重新执行。
6.升级 Node.js 的版本(可选)
根据 Astro 官方要求,在部署Astro时 Node.js 的版本如果不满足 Node.js ≥ 18.17.0 或 ≥ 20.3.0 ,后续可能会无法部署或出现相关的错误提示,我们就必须先升级 Node.js 的版本。
① 先卸载当前低版本的 Node.js 和 npm,避免冲突:
apt remove --purge nodejs npm -yapt autoremove -y② 安装 nvm 工具:
apt install curl -y
# 若curl未安装,先安装curlcurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 下载并执行nvm官方安装脚本(兼容 bash/zsh 终端),此过程需要耐心等待几分钟③ 生效 nvm 环境
source ~/.bashrc
# 无需重启服务器④ 安装符合要求的 Node.js 版本
nvm ls-remote
# 查看可安装的 Node.js 版本nvm install 20
# 安装 Node.js 20.x LTS 版本(满足 Astro 所有要求,稳定可靠)nvm use 20
# 切换到已安装的 20.x 版本(自动设为默认版本)⑤ 验证 Node.js 和 npm 版本
操作与第1、5步一样,检查服务器上node和npm的版本情况:
node -v
npm -v① Node.js 版本应输出 v20.x.x,如 v20.19.6
② npm 版本应输出 v10.x.x,随 Node.js 20.x 自带
7.清理冗余的软件包(可选)
若按本教程操作升级后,系统会残留旧版本软件包(如旧内核、旧依赖),可依次执行以下命名,清理释放磁盘空间:
apt autoremove -y
# 清理缓存和无用依赖apt cleanapt remove --purge linux-image-5.15.0-119-generic linux-headers-5.15.0-119-generic -y
# 删除旧内核,仅保留当前和最新内核Astro的部署
1.Astro项目初始化
执行以下命令,创建一个全新的 Astro 项目:
npm create astro@latest在弹出来的命令行终端输入“y”回车,系统就会自动进入项目目录选择命令行终端
2.Astro项目目录选择
进入项目目录选择时,系统会询问我们要将 Astro 项目创建在哪个目录下,终端默认生成了一个随机目录名 ./dreary-doppler(./ 表示当前目录下,即 /自定义路径 /Astro/dreary-doppler) :
① 若接受默认目录名:直接按下回车键确认,脚手架会在当前目录下创建 dreary-doppler 文件夹作为项目根目录(推荐)
② 若想自定义目录名:输入你想要的目录名称(如 ./yjvc-astro-site,建议小写字母 + 连字符,无特殊字符),再按回车键确认(例如想在当前目录直接创建项目,可输入 ./,但不推荐,容易与现有文件混淆)
3.Astro项目模板选择
How would you like to start your new project? 询问你想要使用哪种模板启动项目,提供了 4 种可选模板,通过圆点(●/○)标识选中状态,若接受官方推荐的基础模板(默认选中项),直接按下回车键确认,无需额外操作。若想切换其他模板:使用上下方向键(↑/↓)移动光标,将对应模板前的圆点切换为 ●(表示选中),再按回车键确认:
① A basic, helpful starter project (recommended):
基础实用启动模板(官方推荐,默认已选中),包含简单首页、组件示例、基础配置,适合新手入门或快速搭建项目框架
② Use blog template:
博客模板,自带文章列表、详情页、分类归档等博客核心功能,适合搭建个人博客
③ Use docs (Starlight) template:
文档模板(基于 Starlight),适合搭建技术文档、帮助中心等结构化文档站点
④ Use minimal (empty) template:
极简空模板,仅包含 Astro 核心配置文件,无多余代码,适合有经验的开发者自定义开发
根据自己的需求进行选择,然后回车确认即可。
4.手动补装项目依赖(解决超时问题,可选)
在执行第3步 Astro 项目的模板选择时,如果出现了依赖安装超时提示,但项目核心骨架已搭建完成的情况,我们可以进行手动补装项目依赖处理,由于自动安装依赖超时,需手动执行 npm install 完成依赖安装:
cd dreary-doppler
# 先进入dreary-doppler文件目录内npm config set registry https://registry.npmmirror.com/
# 切换国内淘宝镜像(可选,大幅提升下载速度)npm install
# 手动安装项目依赖Astro的启动
1.持久化运行
① 先安装 screen(若未安装):
sudo apt update && sudo apt install screen -y② 创建并进入一个新的 Astro 会话:
screen -S astro2.使用默认端口 4321 访问
npm run dev -- --host 0.0.0.0运行成功后浏览器地址输入:http://<服务器IP地址>:4321,即可访问基于 Astro 的博客框架服务了。
Astro的使用
1.Astro的项目结构目录是什么样的?
用 VSCode 或服务器终端的" tree -L 2 "或任何编辑器打开 /Astro 目录文件夹,你会看到这样的结构:
└── dreary-doppler
├── astro.config.mjs # Astro配置文件
├── node_modules
├── package.json # 项目依赖
├── package-lock.json
├── public # 静态资源(图片、字体、favicon)
├── README.md
├── src
└── tsconfig.json展开 /Astro/dreary-doppler/src 目录文件夹,你会看到这样的结构:
├── src
│ ├── assets
│ ├── components # 可复用组件(按钮、卡片等)
│ ├── consts.ts
│ ├── content # 你的Markdown文章存这里
│ ├── content.config.ts
│ ├── layouts # 布局模板(头部、底部等)
│ ├── pages # 路由页面,文件名就是URL
│ └── styles展开 /Astro/dreary-doppler/src/pages 目录文件夹,你会看到这样的结构:
├── pages
│ ├── about.astro # 关于页面
│ ├── blog # 文章详情页
│ ├── index.astro # 网站首页
│ └── rss.xml.js “Astro的使用” 该部分参考来源
2.在 Astro 中新建第1篇文章
打开 /Astro /dreary-doppler /src /content /blog 文件夹,里面默认已经有几篇示例文章了。每篇文章都是一个 .md 或 .mdx 文件,开头有个Frontmatter(就是三个短横线包起来的那部分):
---
title: '我的第1篇文章'
description: '这是一篇测试文章'
pubDate: 'Dec 25 2025'
heroImage: '/blog-placeholder.jpg'
tags: ['Astro', '刘郎']
---
这里开始写正文...Astro会自动识别这些信息,你在页面里就能用 post.data.title 这样调用。而且它有类型校验,如果你写错字段名,构建时会报错,这点对强迫症很友好。
3.首页布局
展示最新文章:Blog模板已经帮你搭好了首页框架,但我们要稍微调整一下,让它更实用。打开 src/ pages /index.astro ,你会看到类似这样的代码:
---
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
// 获取所有博客文章,按日期排序,取最新10篇
const allPosts = (await getCollection('blog'))
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf())
.slice(0, 10);
---
<BaseLayout>
<h1>欢迎来到刘郎博客</h1>
<ul>
{allPosts.map((post) => (
<li>
<a href={`/blog/${post.slug}/`}>{post.data.title}</a>
<time>{post.data.pubDate.toDateString()}</time>
</li>
))}
</ul>
</BaseLayout>① 用 getCollection('blog') 获取所有文章
② 按发布日期倒序排列(最新的在前面)
③ 用 slice(0, 10) 只取前10篇
④ 循环渲染成列表
⑤ 日期排序时要用 .valueOf(),不然会按字符串排序,结果就乱了
4.文章列表页
带分页功能:创建 src/ pages/ blog/ index.astro (如果模板里没有的话),实现一个完整的文章列表:
---
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
const allPosts = (await getCollection('blog'))
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
const pageSize = 10;
const currentPage = 1;
const totalPages = Math.ceil(allPosts.length / pageSize);
const posts = allPosts.slice(0, pageSize);
---
<BaseLayout title="文章列表">
<h1>所有文章</h1>
<div class="post-list">
{posts.map((post) => (
<article>
<h2><a href={`/blog/${post.slug}/`}>{post.data.title}</a></h2>
<p>{post.data.description}</p>
<time>{post.data.pubDate.toLocaleDateString('zh-CN')}</time>
<div class="tags">
{post.data.tags?.map(tag => <span>#{tag}</span>)}
</div>
</article>
))}
</div>
{totalPages > 1 && (
<div class="pagination">
<span>第 {currentPage} / {totalPages} 页</span>
</div>
)}
</BaseLayout>① 这里简化了分页逻辑,实际项目中你可以用Astro的 paginate() 函数自动生成分页。但对于文章数量不多的博客(<100篇),单页展示也够用。
② 建议加个阅读时长估算(按字数÷400字/分钟计算)
③ 建议文章摘要截断(取前150字+省略号)
④ 建议添加缩略图(用 heroImage 字段)
5.文章详情页
这是最关键的部分,用动态路由实现。如果Blog模板里有 src/ pages/ blog/ [...slug].astro,直接编辑它;没有就新建一个:
---
import { getCollection } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.astro';
// 生成所有文章的静态路径
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<BlogPost {...post.data}>
<Content />
</BlogPost>① getStaticPaths() 在构建时运行,为每篇文章生成静态HTML
② post.render() 把Markdown转成HTML组件
③
④ 代码高亮不生效:需要安装Shiki插件(Blog模板已自带)
⑤ Markdown样式不好看:推荐装 @tailwindcss/typography 插件
⑥ 图片路径错误:图片放 public/ 文件夹,引用时写 /images/xxx.jpg
⑦ 如果你想加目录导航(TOC),可以用社区插件 remark-toc,在 astro.config.mjs 里配置:
import { defineConfig } from 'astro/config';
import remarkToc from 'remark-toc';
export default defineConfig({
markdown: {
remarkPlugins: [remarkToc],
},
});6.标签分类
标签分类系统,让内容更有序,创建 src/ pages/ tags/ [tag].astro,实现标签筛选功能:
---
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
export async function getStaticPaths() {
const allPosts = await getCollection('blog');
// 收集所有唯一标签
const allTags = [...new Set(allPosts.flatMap(post => post.data.tags || []))];
// 为每个标签生成一个页面
return allTags.map(tag => ({
params: { tag },
props: {
posts: allPosts.filter(post =>
post.data.tags?.includes(tag)
).sort((a, b) =>
b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
),
},
}));
}
const { tag } = Astro.params;
const { posts } = Astro.props;
---
<BaseLayout title={`标签: ${tag}`}>
<h1>#{tag} 相关文章 ({posts.length})</h1>
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.slug}/`}>{post.data.title}</a>
</li>
))}
</ul>
</BaseLayout>① 这样每个标签都会生成一个独立页面,比如 /tags/astro、/tags/教程 等
② 做一个标签云页面(src/ pages/ tags/ index.astro ),展示所有标签和文章数量,字体大小根据文章数量动态变化,很酷炫
7.RSS订阅
① 安装RSS插件:
npx astro add rss② 创建 src/pages/rss.xml.js:
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
export async function GET(context) {
const posts = await getCollection('blog');
return rss({
title: '刘郎的博客',
description: '知足常乐,不念过往,只慕余生,愿三餐烟火暖,四季皆安然。',
site: context.site,
items: posts.map((post) => ({
title: post.data.title,
pubDate: post.data.pubDate,
description: post.data.description,
link: `/blog/${post.slug}/`,
})),
});
}部署后,你的RSS订阅地址就是 https://你的域名.com/rss.xml。虽然现在用RSS的人不多了,但博客加个这个还是挺专业的。
8.SEO优化
做SEO优化目的:让别人能找到你的博客。搭好博客不是终点,你还得让别人找得到对吧?这就是SEO(搜索引擎优化)的意义。好消息是,Astro在SEO方面天生有优势——静态HTML、快速加载、语义化标签,这些都是搜索引擎喜欢的。配置Meta标签:告诉搜索引擎你的内容是什么,打开 src/ layouts/ BaseLayout.astro (或者你的基础布局文件),在
标签里加上这些:---
interface Props {
title: string;
description?: string;
image?: string;
}
const { title, description = '刘郎博客', image = '/og-image.jpg' } = Astro.props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
---
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title} | 刘郎博客</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonicalURL} />
<!-- Open Graph (分享) -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.site)} />
<meta property="og:url" content={canonicalURL} />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={new URL(image, Astro.site)} />
</head>这样每个页面都有完整的Meta信息,分享到微信、Twitter时也会显示漂亮的卡片。
9.生成Sitemap
npx astro add sitemap然后在 astro.config.mjs 里配置你的域名:
export default defineConfig({
site: 'https://自定义域名',
integrations: [sitemap()],
});部署后,sitemap会自动生成在 https://自定义域名/sitemap-index.xml。去Google Search Console提交这个地址,过几天你的文章就能被搜到了。
10.图片优化
---
import { Image } from 'astro:assets';
import myImage from '../assets/photo.jpg';
---
<Image src={myImage} alt="描述文字" />① 自动转换成现代格式(WebP/AVIF)
② 自动生成多尺寸响应式图片
③ 自动懒加载
11.字体优化
如果你用 Google Fonts 或自定义字体,记得加上 font-display: swap,避免字体加载阻塞渲染。
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}12.代码块语法高亮
在 astro.config.mjs 里配置代码高亮主题:
export default defineConfig({
markdown: {
shikiConfig: {
theme: 'github-dark', // 或者 'dracula', 'nord' 等
},
},
});Blog模板一般自带 Shiki ,如果还是不行,试试重装依赖:
rm -rf node_modules && npm install四款建站工具特性对比表
以下四款建站工具: Astro 、 Halo 、 Hexo 、 Hugo 各有拿手之处,到底哪款才是你的菜?这份横向对比表帮你做出选择:
除了Astro,Hexo、Hugo、Halo三款工具的Linux服务器 搭建/部署 流程(精简版)如下:
1.Halo的部署
部署方式:手动/JAR包部署
1.更新软件包索引
apt update -y2.安装 OpenJDK 17(Debian/Ubuntu 系统,CentOS 替换为 yum)
apt install -y openjdk-17-jdk openjdk-17-jre3.验证 Java 版本(需输出 17.x.x)
java -version4.下载 Halo 2.17.0 稳定版(当前目录:/自定义路径/halo)
wget https://dl.halo.run/release/halo-2.17.0.jar -O halo.jar5.验证文件是否下载成功
ls -l halo.jar6.前台启动 Halo,终端会输出运行日志
java -jar halo.jar7.持久化运行:安装 screen(若未安装,临时测试,可选)
apt install -y screen8.持久化运行:创建名为 halo 的会话(临时测试,可选)
screen -S halo9.持久化运行:在会话内启动 Halo (临时测试,可选)
java -jar halo.jar10.创建带 8886 端口(自定义端口)的 systemd 服务文件:
cat > /etc/systemd/system/halo.service << EOF
[Unit]
Description=Halo Blog Service
After=network.target network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/自定义路径/halo
# 强制绑定所有网卡,确保外网可访问
ExecStart=/usr/bin/java -Xmx512M -jar halo.jar --server.port=8886 --server.address=0.0.0.0
Restart=on-failure
RestartSec=3
StandardOutput=append:/自定义路径/halo/halo-service.log
StandardError=append:/自定义路径/halo/halo-service.log
[Install]
WantedBy=multi-user.target
EOF11.重新加载 systemd 配置,使新服务文件生效
systemctl daemon-reload12.设置开机自启并立即启动 Halo 服务
systemctl enable --now halo13.查看 Halo 服务运行状态(确认 active (running))
systemctl status halo14.浏览器访问并初始化系统信息(这里已经可以成功访问了)
http://服务器IP:8886/console/一键清理halo相关资源
systemctl stop halo && systemctl disable halo && rm -f /etc/systemd/system/halo.service && systemctl daemon-reload && ps aux | grep -E "halo\.jar|--server\.port=8886" | grep -v grep | awk '{print $2}' | xargs -r kill -9 && rm -rf /自定义路径/halo && rm -rf ~/.halo ~/.halo22.Hexo的部署
部署方式:本地服务直启 + Git 插件部署
1.清空目录(如果有无关文件,谨慎执行!)
rm -rf *2.初始化 Hexo 项目
hexo init . 3.安装初始化后项目所需的依赖(这一步会补全 Hexo 核心文件)
npm install 4.生成静态文件到 public 目录(每次更新内容之后都要执行一次)
hexo generate 5.先安装 screen(若未安装)
sudo apt update && sudo apt install screen -y 6.持久化运行,创建并进入一个新的 hexo 会话
screen -S hexo 7.启动本地服务,默认端口 4000 ,这里已经可以访问 Hexo 服务了
hexo server 8.指定 8885 端口启动
hexo server -p 8885 9.安装部署插件
npm install hexo-deployer-git --save 10.清空缓存和旧静态文件
hexo clean 11.部署(需先配置 _config.yml 的 deploy 项)
hexo deploy 12.生成+部署(每次更新内容之后都要执行一次)
hexo g -dHexo的清理
清理 Node.js 和 Npm 部署的项目(这里以Hexo项目为例)
1.删除项目文件夹
2.查看项目文件夹或项目文件是否还存在(若存在,删除即可)
ls -l Hexo/rm -rf Hexo/3.查看全局安装的 Hexo 包
npm list -g hexo-cli4.卸载全局安装的 Hexo 包
npm uninstall -g hexo-cli5.清理 npm 缓存
npm cache clean --force6.检查 hexo 命令是否还存在(若提示 "command not found" 则已卸载成功)
hexo -v7.检查 Nginx 配置中是否还有 Hexo 相关内容(无输出则配置已清理)
grep -r "Hexo" /www/server/nginx/conf/3.Hugo的部署
部署方式:基于Hugo系统包+本地构建+Screen部署
1.安装 Hugo(root 用户下可省略 sudo,也可以保留)
apt install hugo -y2.验证 Hugo 安装
hugo version3.初始化 Hugo 站点
hugo new site . --force4.初始化 git 仓库
git init5.添加目录到 Git 安全列表
git config --global --add safe.directory /自定义路径/hugo6.主题安装,这里我就以 Ananke 主题为例(当然你也可以换成其他主题):
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke① 配置 Hugo 使用 Ananke 主题(将主题名称写入核心配置文件 config.toml,让 Hugo 识别并启用该主题)
echo 'theme = "ananke"' >> config.toml② 创建第一篇测试文章
hugo new posts/my-first-post.md③ 降级 Ananke 主题到兼容版本(可选)
进入主题目录:
cd themes/ananke 回退到兼容旧版 Hugo 的稳定版本:
git checkout v2.8.0 回到 Hugo 项目根目录:
cd ../../ ④ 修改文章为发布状态
用编辑器打开文章文件,找到 draft: true 改为 draft: false ,不然站点正常无法显示文章
7.构建静态网站(生成可访问的文件)
hugo8.持久化运行
① 先安装 screen(若未安装):
sudo apt update && sudo apt install screen -y ② 创建并进入一个新的 hugo 会话:
screen -S hugo 9.自定义 8885 端口访问
hugo server --bind 0.0.0.0 --port 8885 --baseURL http://服务器IP:8885 --disableFastRenderHugo的清理
1.清理 Hugo 二进制程序
① 查找 Hugo 二进制文件位置
which hugo ② 删除找到的路径:
rm -rf /Hugo二进制文件位置路径 2.清理残留的 SCREEN 会话
① 列出所有 screen 会话:
screen -ls ② 终止名为 hugo 的 screen 会话:
screen -S hugo -X quit ③ 若上述命令无效,直接通过进程号终止 screen 进程:
kill -9 hugo对应的进程号 3.检查 screen 会话是否残留,如果命令没有输出,说明清理彻底完成。
screen -ls | grep hugo 4.清理僵死的 hugo screen 会话
① 方式1:通过会话ID强制清理(推荐)
screen -wipe 会话ID② 方式2:若方式1无效,清理所有死会话
screen -wipe梦境20251229
余欲宴亲僚,咸欣然应之。乃赴邑中最奢之肆,珍馐罗陈,凡所思者,靡不备焉。饮啖戏乐,悉皆免费,无有穷尽。及宴始,肆告以计时计费之规:不限人数,不限辰光,不限品数,唯以六钱一秒计。
俄而三十分钟,手机忽得短信,示已费一万一千一百一十一钱。余大惊,示之众人,众皆愕然,相顾惊疑:“何宴之奢,半刻而糜万金?”余起询之侍者,对曰:“本店计费,弗论肴品、人数、时长,率六钱一秒,自宴始计之。”余默算之:一万一千一百一十一钱,除以六钱一秒,得一千八百五十一秒有余,折合三十分钟许。
众闻之,皆罢箸辞去。独余怅立,凝视扣费之讯,惘然若失。已而闻身后人低语:“宴之贵也若是,半刻万金,何其侈哉!”众皆出肆,余亦仓皇遁去。甫出肆门,霍然惊寤,起坐于榻。
视室中昏黑,妻孥犹酣眠。余蹑足着履,趋如厕。如厕之际,亟取手机视花呗之额,乃悟前事皆幻梦也。幸哉!

够奢侈啊,话说回来“我做梦都想这么奢侈一把”
一样的 梦境也许反应的正是当下生活的一种折射 那些在现实里被忽略的情绪 未说出口的期许 藏在心底的焦虑 都会在夜深人静时 借着梦境的外壳悄然浮现 它可能是对某段遗憾的温柔补全 是对未来的懵懂预演 也可能只是日复一日琐碎日常的变形重组吧 还有就是 这种记忆 顶多会在脑海中停留几天 然后便消失了 所以我才提笔记录下来呢
哈哈,我最近这两年不知道怎么了,很少做梦,但如果做梦了,在梦中很快就能意识到自己是在做梦,而且大多数时候也可以轻易在梦中叫醒自己;少数几次有那种“鬼压身”的感觉,要很努力才能醒过来
是的 我也不信 毕竟实实在在的发生了 只是做一个简单的记录 我个人还是比较现实和理性的
这种理论我感觉听听就好;就那句话,命嘛,信就有、不信则无
我还专门找Ai和其它解梦的工具来看了一下 大多都是说我财务支配不平衡 计划与现实界线划分问题 哈哈
文章最后那一段是啥情况,好突兀的出现。
梦境写实 你这么一说 感觉还真有点 不过也没事
静态页面确实有吸引人的地方,不知道 astro 和 hexo 哪个好。halo 我目前还放在服务器上,聊聊几篇文章。就是那个数据库看不明白就不想用下去了。
文中有提到astro和hexo建站工具特性对比的表 可以参考一下
搞起来啊,自从用了astro,回不去了~
用Nuxt或Next前后端分离
轻装上阵 确实快了很多 但没有后台界面 挺难受
这个之前看到过 感觉麻烦就懒得折腾了
亲自上手 熟悉了就不会觉得麻烦了
玩hexo的时候,接触过,当时还做了一个主题,还是嫌静态博客麻烦
静态博客确实比较麻烦 每次都需要手动Git代码 不过它快呀