跳转到主要内容

静态资源

DIY 站点,从静态资源开始定制

本 CMS 的静态资源均位于 public/ 下。本节介绍其目录结构,以及可直接使用和需要替换的资源。

静态资源结构

目录树public/
├── emojis/                 评论表情
├── fonts/                  字体
├── icons/                  文章正文用的技术图标
├── imgs/                   图片
├── skills/                 关于页的技能图标
├── favicon.ico
├── manifest.webmanifest
└── robots.txt

CDN 解析机制

本项目支持将静态资源托管于 CDN 上,节省主站带宽并可配置缓存。

本章节只介绍在不配置 CDN 时如何自定义静态资源。配置 CDN 的文档请参照 CDN 配置 文档,除了上云需做额外处理,其他都跟本章节一致。

不配置 CDN 时,这些静态资源和 Nuxt 打包的 CSS 和 JS 都走站点自己的域名。配置 CDN 时,在 site.config.ts 里填上 _cdnUrl 之后,生产环境会把它们换成 CDN 域名下的地址,本地开发不受影响。

emojis

emojis 目前有三组表情,分别是 Heo 表情、猫猫虫和猫咪,用在评论区的表情面板,服务端渲染邮件时也用同一份映射。

图片按组放在 public/emojis/ 下,映射表是 app/assets/emojis.json,顶层 key 对应一组表情的目录,每条形如:

JSON"Heo-Sticker": {
  "heo-3d眼镜": "/emojis/heo-sticker/3d眼镜.png"
}

若要换成自己的表情,请把图片放进 public/emojis/ 下新建的目录,在 emojis.json 里加一层同名的顶层 key 和条目,再到 shared/emoji-categories.ts 的 EMOJI_CATEGORIES 里加一条:dataKey 跟 emojis.json 的顶层 key 对齐,prefix 既是 key 的前缀也是占位符的前缀。

例如,张洪 Heo 发布了 3D 版本的 Heo-Sticker 表情,个人博客可免费使用。下载并解压表情包后,在 public/emojis/ 下新建 heosticker3d 目录,再将表情图片放入其中。

修改 app/assets/emojis.json:

JSON{
  "Heo-3D": {  
    "heo3d-爱心眼": "/emojis/heosticker3d/爱心眼.png",  
    "heo3d-安睡": "/emojis/heosticker3d/安睡.png",  
    "heo3d-傲娇": "/emojis/heosticker3d/傲娇.png",  
    "heo3d-抱心": "/emojis/heosticker3d/抱心.png",  
    "heo3d-抱熊": "/emojis/heosticker3d/抱熊.png"
  }  
}

然后修改 shared/emoji-categories.ts 的 EMOJI_CATEGORIES 常量:

TypeScriptexport const EMOJI_CATEGORIES: EmojiCategoryMeta[] = [
  { dataKey: "Heo-Sticker", label: "Heo表情", prefix: "heo-" },
  { dataKey: "capoo", label: "猫猫虫", prefix: "猫猫虫-" },
  { dataKey: "Cat", label: "猫咪", prefix: "cat-" },
  { dataKey: "Heo-3D", label: "Heo表情3D", prefix: "heo3d-" },  
];

结果:

emojis 位于 public/ 文件夹下,因此可以部署到 CDN。public/ 内的所有资源均无需手动处理 CDN 接入逻辑,是否配置 CDN 都由 ImQi1 CMS 自动适配。

其实我有想过统一,因为它确实是设计上的缺陷,但是面对我想要的门槛还是妥协了。在快速开始里面其实我就说了,我想提高这个项目被人使用的门槛,所以很多地方我都没有复用或采用自动扫描,而是分散在项目中,包括这处。同时,我认为这样可以加快你对此项目的理解,比如你按照上述步骤成功新增了你喜欢的自定义表情,那你就相当于探索了一部分的 public、shared,而它们只是你全面认识此项目的开始。

能随身所欲 DIY 此项目的前提就是你要对本项目的每一处代码都要了解。基于我写的代码,你能 DIY 出具有你自己理解和审美的网站,才是我想看到的。

fonts

public/fonts/font.css 里有两部分。正文是 Noto Serif SC,101 个 @font-face 按 unicode-range 分片;代码是 JetBrainsMono,分 ASCII、Symbols、Rest 三片,取自 JetBrainsMono Nerd Font。ASCII 那片在 src 里先找本机装的同名字体,找不到才回落到打包的 woff2,Symbols 与 Rest 两片则直接用打包的 woff2,其中 Symbols 覆盖箭头、货币和数学、技术符号。

两个字体变量在 app/assets/css/main.css 里,--font-serif 给正文,--font-mono 给代码。font.css 本身是在 nuxt.config.ts 的 app.head 里引入的。

以把代码字体换成 0xProtoNerdFontMono 为例(附 Nerd 字体下载地址:https://www.nerdfonts.com/font-downloads ):

删除 JetBrains Mono 的三个字体,把 0xProtoNerdFontMono 放进 public/fonts/:

建议使用 woff2 字体。与 ttf 相比,woff2 占用空间更小,现代浏览器也普遍支持。本例为便于演示使用 ttf。

然后在 public/fonts/font.css 中删除 JetBrainsMono 的三段定义,替换为以下定义:

CSS@font-face {
  font-display: swap;
  font-family: "0xProtoNerdFontMono";
  font-style: normal;
  font-weight: 400;
  src: url(0xProtoNerdFontMono-Regular.ttf) format("truetype");
}

再改 app/assets/css/main.css 里的字体变量:

CSS  --font-mono: "JetBrainsMono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";  
  --font-mono: "0xProtoNerdFontMono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";  

结果:

icons

public/icons/ 下 24 个 SVG 分两种用途。16 个给代码块用,代码块带了文件名时按扩展名取图标,没有扩展名就按语言,挂在左上角文件名前面,映射在 app/composables/useMarkdownContent.ts 的 iconMap 里。另外 8 个是正文链接的品牌图标,Github、Gitee、百度、Google、腾讯、微信、Mozilla 和 npm,在 app/components/markdown/MarkdownBody.vue 里按 .markdown-link-icon--名字 这个类名做 mask 渲染。

imgs

imgs 文件夹存放多类图片资源,具体用途如下:

文件名引用方用途
program.webp / game.webp / music.webp / photo.webp / reading.webp / travel.webpapp/pages/about.vue关于页 - 兴趣爱好六个翻转卡片配图(编程 / 游戏 / 音乐 / 摄影 / 阅读 / 旅行)
jixi.webp / ysu.webp / shenyang.webpapp/pages/about.vue关于页 - 「游山玩水」三张城市 / 校园配图(鸡西 / 燕山大学 / 沈阳)
enfj.svgapp/pages/about.vue关于页 - MBTI 主人公 ENFJ 头像
shenyang.webpapp/pages/index.vue首页 - 主题切换预览的「layout」主题配图(与 about 共用同一文件)
links-cover.pngapp/pages/links.vue友链页 - 页顶封面图
message-cover.png / nopic.pngapp/pages/messages.vue留言页 - 页顶封面图 + 无头像 / 无封面占位图
avatar.webpsite.config.ts (site.avatarPath)全站默认头像
imqi1.svgsite.config.ts (seo.ogImage) + public/manifest.webmanifest站点 logo(OG 图、PWA 图标通用矢量图)
miniprogram.jpgsite.config.ts (pages.homeLinks[].qrcode)联系方式 - 微信小程序二维码
foreverblog.png / travelling.png / boyouquan.png / blogfinder.png / storeweb.pngsite.config.ts (pages.links.blogOrganizations)友链 - 五个友链站点图标(十年之约 / 开往 / 博友圈 / Blogfinder / 个站商店)
imqi1-144.pngnuxt.config.ts (apple-touch-icon)Apple Touch Icon 180×180
frontend-screenshot1.png / frontend-screenshot2.pngpublic/manifest.webmanifestPWA 应用截图(桌面 1280×720 / 移动 510×820)

其他文件(夹)

skills 图标仅用于关于页面的【技能 / 技术栈】模块。

favicon.ico 是浏览器标签页标题左侧的小图标,请替换为自己的图标,并保持文件名一致。

manifest.webmanifest 是 PWA 所需的清单,将在 PWA 章节中详细介绍修改方法。

robots.txt 规定搜索引擎爬虫抓取站点时应遵守的协议,请将其中的域名替换为站点自身域名。