最初我以为博客主题只有一种使用方式:克隆仓库、改配置、写文章。后来才发现,同一份代码还可以发布成 npm 包,让其他人在自己的 Astro 项目里安装使用。
这两种模式共享同一套源码,但运行环境完全不同。
两种模式的分界
flowchart TB Source[主题源码] Source --> A[源码模式:项目直接持有 src/] Source --> B[npm 模式:用户项目安装 shirones] A --> A1[配置在 src/config] B --> B1[配置覆盖在用户项目] B --> B2[内容在 shirones/content]
源码模式下,项目拥有所有文件,想改哪里就改哪里。npm 模式下,主题代码在 node_modules 里,用户的配置和内容必须放在包外的位置。
同一个改动,在两种模式下都成立,才算真正完成。
配置不能假设自己在哪
源码模式里,读取 src/config/siteConfig.ts 看起来理所当然。到了 npm 模式,这个路径可能属于主题包,而不是用户项目。
因此配置读取需要遵循「用户覆盖优先」的规则,而不是直接读主题目录里的默认值。
const userConfig = readUserConfig("site");const finalConfig = userConfig ? mergeWithDefaults(userConfig) : defaults;构建配置需要重新生成
Astro 的集成机制允许主题在启动时重建 astro.config.mjs,把必需的插件、路由和资源注入用户项目。这意味着配置文件不是静态的,而是会根据模式动态生成。
发布前必须检查依赖边界
最容易出问题的地方,是「本地能构建,安装后失败」。原因通常是某个包写在了 devDependencies,但运行时需要它。
项目专门有一条检查命令,用来发现这种情况:
pnpm check:package-manifest它会在发布前扫描源码里的 import,确认每个运行时依赖都出现在正确的位置。
| 依赖类型 | 用途 | 是否随包安装 |
|---|---|---|
| dependencies | 运行时必需 | 是 |
| peerDependencies | 由用户项目提供 | 否 |
| devDependencies | 仅主题仓库开发使用 | 否 |
文档也是交付物
npm 模式最容易让用户困惑的,不是代码,而是「我的配置应该放哪」「内容目录在哪」「为什么改了没生效」。这些问题需要在文档里给出明确答案,而不是让用户读源码。
双模式最累的部分是什么?
不是写两套代码,而是每次改动都要问:这个改动在另一种模式下还成立吗?路径、配置、资源归属,任何一项假设错了,都会在发布后才暴露。
小结
从主题到 npm 包,增加的是一层交付责任。源码模式可以只对自己负责,npm 模式必须对陌生环境负责。
也正因为如此,双模式反而逼着我把路径、配置和依赖边界想清楚。能经得起别人安装的代码,通常也会让自己的项目更干净。
本站技术手记
连载中分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 2 天
部分内容可能已过时