找回密码
 立即注册
首页 业界区 业界 vuepress-reco搭建与部署指南

vuepress-reco搭建与部署指南

赫连如冰 5 天前
个人博客:槿苏的知识铺
一、前言

  在技术飞速发展的今天,高效地编写、维护和呈现文档已成为开发者不可或缺的能力。无论是开源项目、团队协作还是个人知识沉淀,一套结构清晰、体验优雅的文档系统都能显著提升信息的传递效率。而vuepress-reco作为vuepress的现代化主题,它既继承了vuepress的markdown 友好性和静态站点的高性能,又通过丰富的主题功能和开箱即用的配置,借助vuepress的插件生态,为技术文档注入了更多可能,让开发者能够专注于内容创作,而非繁琐的配置。本文将基于vuepress-reco 2.x版本,系统性地介绍如何从零搭建一套文档系统。
二、搭建流程

1、环境准备
  1. node version >= 18
  2. # 安装脚手架工具
  3. npm install @vuepress-reco/theme-cli -g
复制代码
2、使用脚手架创建项目
  1. theme-cli init
复制代码
  执行之后会出现以下内容,依次输入
  1. ? Whether to create a new directory? Yes # 是否创建目录 输入 Y
  2. ? What's the name of new directory? blog-vuepress-reco-demo # 项目目录名称
  3. ? What's the title of your project? blog-demo # 标题(如果准备创建2.x版本,此项无效,可不填写)
  4. ? What's the description of your project? blog-demo by vuepress-reco 2.x # 描述(如果准备创建2.x版本,此项无效,可不填写)
  5. ? What's the author's name? demo # 作者(如果准备创建2.x版本,此项无效,可不填写)
  6. ? What style do you want your home page to be?(The 2.x version is the beta version) # 选择2.x
  7.   blog style for 1.x
  8.   doc style for 1.x
  9. > 2.x
复制代码
  选择之后稍作等待项目就创建成功了,使用vscode打开该项目,执行npm install安装依赖,安装完成之后运行npm run dev,打开控制台输出的访问链接即可看到页面效果。
1.png

三、文档配置

1、项目结构
  1. blog-vuepress-reco-demo
  2. ├─ docs #该目录下存放编写的文档
  3. │  └─ theme-reco
  4. │     ├─ api.md
  5. │     ├─ plugin.md
  6. │     ├─ theme.md
  7. │     └─ README.md
  8. ├─ blogs #该目录下存放编写的博客文章
  9. │     ├─ category1
  10. │     │  ├─ 2018
  11. │     │  │  └─ 121501.md
  12. │     │  └─ 2019
  13. │     │     └─ 092101.md
  14. │     ├─ category2
  15. │     │  ├─ 2016
  16. │     │  │  └─ 121501.md
  17. │     │  └─ 2017
  18. │     │     └─ 092101.md
  19. │     └─ other
  20. │        └─ guide.md
  21. ├─ series # vuepress-reco 2.x新增,使用脚手架创建无此目录,可手动创建,与docs目录作用类似
  22. ├─ .vuepress         #存放项目配置文件与静态资源
  23. │   ├─ config.ts    #配置文件
  24. │   └─ public       #该目录下存放网页中所需的静态资源
  25. │     ├─ bg.svg           #首页背景大图
  26. │     ├─ head.png   #头像
  27. │     └─ logo.png   #网站logo
  28. ├─ package.json      #依赖管理文件
  29. └─ README.md         #博客首页的内容
复制代码
2、打包工具

  该主题模版内置了vite和webpack,默认使用vite,此处我们也选择vite,所以可以执行以下命令将webpack打包工具卸载
  1. npm uninstall @vuepress/bundler-webpack
  2. # 同理,如果选择webpack,可执行以下命令卸载vite
  3. npm uninstall @vuepress/bundler-vite
复制代码
3、主题配置

  主题配置请根据vuepress-reco官方文档进行配置,本文所述仅限参考,且不做过多赘述。
(1)首页
  主题的默认首页是根目录下的README.md文件生成,配置内容请自行参考官方文档。在某些场景下,文档的首页并不一定是文档根目录的README.md文件,这时我们可以在Frontmatter中设置home: true来置顶首页,并通过theme.home来指定首页路径。
  1. # another-home-path.md
  2. ---
  3. title: 指定首页
  4. home: true
  5. ---
复制代码
  1. // .vuepress/config.ts
  2. import { defineUserConfig } from "vuepress";
  3. import { recoTheme } from "vuepress-theme-reco";
  4. export default defineUserConfig({
  5.   theme: recoTheme({
  6.     home: "/another-home-path",
  7.   }),
  8. });
复制代码
(2)插件
  更多插件请前往vuepress插件市场探索
  1. // .vuepress/config.ts
  2. import { defineUserConfig } from "vuepress";
  3. import { recoTheme } from "vuepress-theme-reco";
  4. import { mediumZoomPlugin } from "@vuepress/plugin-medium-zoom";
  5. export default defineUserConfig({
  6.   plugins: [
  7.     // 图片放大插件
  8.     mediumZoomPlugin({
  9.       selector: "img",
  10.     }),
  11.   ],
  12. });
复制代码
(3)其他配置
  1. // .vuepress/config.ts
  2. import { defineUserConfig } from "vuepress";
  3. import { recoTheme } from "vuepress-theme-reco";
  4. export default defineUserConfig({
  5.   // 打包文件路径
  6.   dest: "./dist",
  7.   // 运行端口号
  8.   port: 3011,
  9.   // 语言
  10.   locales: {
  11.     "/": {
  12.       lang: "zh-CN",
  13.     },
  14.   },
  15.   // html head头部配置
  16.   head: [
  17.     ["link", { rel: "icon", href: "/favicon.ico" }],
  18.     [
  19.       "meta",
  20.       {
  21.         name: "viewport",
  22.         content: "width=device-width,initial-scale=1,user-scalable=no",
  23.       },
  24.     ],
  25.     ["meta", { name: "keywords", content: "" }], // 搜索引擎关键字
  26.     ["meta", { name: "author", content: "" }], // 作者
  27.     ["meta", { name: "robots", content: "all" }],
  28.   ],
  29. });
复制代码
(4)自动化配置
  vuepress-reco为了节约用户的时间成本,特地添加了自动设置分类、自动设置系列的功能

  • 自动设置分类
    1. import { defineUserConfig } from "vuepress";
    2. import { recoTheme } from "vuepress-theme-reco";
    3. export default defineUserConfig({
    4.   theme: recoTheme({
    5.     // 自动设置分类
    6.     autoSetBlogCategories: true,
    7.     // 自动将分类和标签添加至头部导航条
    8.     autoAddCategoryToNavbar: {
    9.       location: 1, // 插入位置,默认 0
    10.       showIcon: true, // 展示图标,默认 false
    11.     },
    12.     // 当 autoAddCategoryToNavbar 为 true 时,则全部取默认值
    13.     autoAddCategoryToNavbar: true,
    14.   }),
    15. });
    复制代码
      当开启自动分类时,需要注意的是,由于该功能自动为blogs文件夹下的博客设置分类,也就是将该文件所在文件夹的名称设置为该文件的frontmatter的categories的值。假如您的blogs文件夹下并不是只有一级目录,而是多级目录,那么此功能将会把分类名称设置为多级目录的路径名称。例如:
    1. blogs
    2. └─ category1
    3.     └─ 2018
    4.         └─121501.md
    复制代码
    那么,分类名称将设置为category1/2018。

  • 自动设置系列
      为了节约用户的时间成本,主题可以自动将 series 文件夹下的文档,按照文件夹嵌套关系生成系列的配置。
    1. import { defineUserConfig } from "vuepress";
    2. import { recoTheme } from "vuepress-theme-reco";
    3. export default defineUserConfig({
    4.   theme: recoTheme({
    5.     // 自动设置系列
    6.     autoSetSeries: true,
    7.   }),
    8. });
    复制代码
(5)自定义增强配置
  从自动设置系列得到的启发,自己定义函数,将docs下的文档按照series配置的规则生产相应的配置,这样就不需要自己手动配置docs文件夹下的配置。
  1. // util.ts
  2. import * as fs from "fs";
  3. import * as path from "path";
  4. /**
  5. * 获取目录下的子目录
  6. *
  7. * @param dir 指定目录
  8. * @returns 子目录名称数组
  9. */
  10. const nextDirectories = (dir: string): string[] => {
  11.   const files = fs.readdirSync(dir, { withFileTypes: true });
  12.   const directories = files
  13.     .filter((dirent) => dirent.isDirectory())
  14.     .map((dirent) => dirent.name);
  15.   return directories;
  16. };
  17. /**
  18. * 将多个字符串变量拼接
  19. *
  20. * @param separator
  21. * @param args
  22. * @returns
  23. */
  24. const stringJoin = (separator: string, ...args: string[]): string => {
  25.   return args
  26.     .map((arg) => (arg.startsWith(separator) ? arg.slice(1) : arg))
  27.     .filter((arg) => arg)
  28.     .join(separator);
  29. };
  30. export { stringJoin, nextDirectories };
复制代码
  1. /**
  2. * 将某个目录下的文件返回SeriesConfigArray的结构
  3. *
  4. * @param rootPath 项目根目录
  5. * @param dir 目录
  6. *        ├─ index.md
  7. *        ├─ one
  8. *        │  ├─a.md
  9. *        │  ├─b.md
  10. *        │  └─ three
  11. *        │     └─ e.md
  12. *        └─ two
  13. *           ├─ c.md
  14. *           └─ d.md
  15. * @returns ["index",{"text":"one","children":["one/a","one/b",{"text":"three","children":["one/three/e"]}]},{"text":"two","children":["two/c","two/d"]}]
  16. */
  17. const createSeriesConfigArray = (
  18.   rootPath: string,
  19.   dir: string,
  20.   basePath: string = ""
  21. ): any[] => {
  22.   try {
  23.     const fullDir = path.join(rootPath, dir, basePath);
  24.     const files = fs.readdirSync(fullDir, { withFileTypes: true });
  25.     const results: any[] = [];
  26.     files.forEach((dirent) => {
  27.       if (dirent.isFile() && dirent.name.endsWith(".md")) {
  28.         // 处理.md文件
  29.         const name = stringJoin("/", basePath, path.parse(dirent.name).name);
  30.         results.push(name);
  31.       } else if (dirent.isDirectory()) {
  32.         const childDir = stringJoin("/", basePath, dirent.name);
  33.         // 递归处理子目录
  34.         const children = createSeriesConfigArray(rootPath, dir, childDir);
  35.         if (children.length > 0) {
  36.           results.push({
  37.             text: dirent.name,
  38.             children: children,
  39.           });
  40.         }
  41.       }
  42.     });
  43.     return results;
  44.   } catch (err) {
  45.     console.error("Error:", err);
  46.     throw err; // 或者根据需要处理错误
  47.   }
  48. };
复制代码
  1. // series.ts
  2. import path from "path";
  3. import { nextDirectories, stringJoin } from "./utils";
  4. const rootPath = path.dirname(__dirname);
  5. // 获取docs下的子目录
  6. const docsName = "docs";
  7. const directories = nextDirectories(path.join(rootPath, docsName));
  8. // 生成series
  9. const series: any = {};
  10. directories.forEach((dirName) => {
  11.   const path = "/" + stringJoin("/", docsName, dirName);
  12.   series[path + "/"] = createSeriesConfigArray(rootPath, path);
  13. });
  14. export default series;
复制代码
  1. .vuepress/config.ts
  2. import { defineUserConfig } from "vuepress";
  3. import { recoTheme } from "vuepress-theme-reco";
  4. import series from "./series";
  5. export default defineUserConfig({
  6.   theme: recoTheme({
  7.     // docs下的文档
  8.     series: series,
  9.   }),
  10. });
复制代码
四、在线部署

1、搭建Github Pages

  国内外知名代码托管平台,如:Github、Gitlab、Gitee(Pages服务已下线) 都有提供Pages服务,也就是可以托管您的静态资源,以此来搭建一个静态网站,这里我们选用Github进行搭建Pages服务,仅限参考,一切以官方文档为准。
Github Pages的站点类型有以下两种:

  • 个人或组织站点(User or Organization sites):对于个人或组织站点,每个GitHub用户或组织只能有一个站点,它通常使用[username].github.io或[organizationname].github.io的格式,这是GitHub Pages的默认站点,通常用于个人网站、博客等。
  • 项目站点(Project sites):对于项目站点,每个GitHub仓库可以有一个关联的GitHub Pages站点,这意味着对于每个项目,您可以创建一个独立的GitHub Pages站点,无需限制。
  此处我们选择创建个人或组织站点:
  1、在Github 顶部菜单栏点击+,然后New repository新建仓库,输入项目的相关信息,然后Create repository创建仓库,需要注意的是,如果您的用户或组织名称包含大写字母,您必须小写字母。如图:
2.png

  2、设置Github Pages,访问 [username].github.io 以查看新网站,如果配置了自己的域名,可以使用自己域名进行访问。GitHub Pages将查找index.html、index.md或README.md文件,作为站点的入口文件。 请注意,对站点的更改在推送到 GitHub 后,最长可能需要 10 分钟才会发布。
3.png

2、部署项目

  在项目目录下,创建内容如下的deploy.sh文件
  1. #!/usr/bin/env sh
  2. # 确保脚本抛出遇到的错误
  3. set -e
  4. # 编译生成静态文件
  5. npm run build
  6. # 进入编译生成的文件夹
  7. cd ./dist
  8. # 如果是发布到自定义域名
  9. # echo '自定义域名' > CNAME
  10. git init
  11. git add -A
  12. git commit -m 'deploy'
  13. # 需要修改为您自己的GitHub Pages仓库地址
  14. git remote add origin git@github.com:[username]/[username].github.io.git
  15. git push -f origin master
  16. cd -
  17. rm -rf ./dist
复制代码
在项目目录下打开命令行窗口,根据自己的电脑环境执行对应的命令。
  1. # Linux环境下
  2. bash deploy.sh
  3. # Windows环境下
  4. deploy.sh
复制代码
执行完成,稍作等待后访问GitHub Pages站点链接即可查看发布效果。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册