1. VuePress
1.1 简介
VuePress 是 Vue
驱动的静态网站生成器。
简洁至上
以 Markdown
为中心的项目结构,以最少的配置帮助你专注于写作。
Vue 驱动
享受 Vue + webpack
的开发体验,可以在 Markdown
中使用 Vue
组件,又可以使用 Vue
来开发自定义主题。
高性能
VuePress
会为每个页面预渲染生成静态的 HTML
,同时,每个页面被加载的时候,将作为 SPA
运行。
1.2 效果
首页:
评论:
效果详情请看:https://biaochenxuying.github.io/blog/ 。
1.3 简单使用
像数 1, 2, 3 一样容易
# 安装 yarn global add vuepress # 或者:npm install -g vuepress # 创建项目目录 mkdir vuepress-starter && cd vuepress-starter # 新建一个 markdown 文件 echo '# Hello VuePress!' > README.md # 开始写作 vuepress dev . # 构建静态文件 vuepress build .
1.4 目录结构
VuePress 遵循 “约定优于配置” 的原则,推荐的目录结构如下:
├── docs │ ├── .vuepress (可选的) │ │ ├── components (可选的) │ │ ├── theme (可选的) │ │ │ └── Layout.vue │ │ ├── public (可选的) │ │ ├── styles (可选的) │ │ │ ├── index.styl │ │ │ └── palette.styl │ │ ├── templates (可选的, 谨慎配置) │ │ │ ├── dev.html │ │ │ └── ssr.html │ │ ├── config.js (可选的) │ │ └── enhanceApp.js (可选的) │ │ │ ├── README.md │ ├── guide │ │ └── README.md │ └── config.md │ └── package.json
注意:请留意目录名的大写。
docs/.vuepress
: 用于存放全局的配置、组件、静态资源等。docs/.vuepress/components
: 该目录中的Vue
组件将会被自动注册为全局组件。docs/.vuepress/theme
: 用于存放本地主题。docs/.vuepress/styles
: 用于存放样式相关的文件。docs/.vuepress/styles/index.styl
: 将会被自动应用的全局样式文件,会生成在最终的CSS
文件结尾,具有比默认样式更高的优先级。docs/.vuepress/styles/palette.styl
: 用于重写默认颜色常量,或者设置新的stylus
颜色常量。docs/.vuepress/public
: 静态资源目录。docs/.vuepress/templates
: 存储HTML
模板文件。docs/.vuepress/templates/dev.html
: 用于开发环境的HTML
模板文件。docs/.vuepress/templates/ssr.html
: 构建时基于Vue SSR
的HTML
模板文件。docs/.vuepress/config.js
: 配置文件的入口文件,也可以是YML
或toml
。docs/.vuepress/enhanceApp.js
: 客户端应用的增强。
注意:
- 当你想要去自定义
templates/ssr.html
或templates/dev.html
时,最好基于 默认的模板文件 来修改,否则可能会导致构建出错。 - 还有就是笔者的
templates/ssr.html
和templates/dev.html
是有添加如下这一行代码的:
<meta id="referrer" name="referrer" content="never" />
因为笔者的图片都是存在简书上的,所以为了可以访问第三方图床的图片,才添加了这句代码,如果你的图片是存在本地的,去掉这句代码即可,至于具体原因请看笔者写的文章:前端解决第三方图片防盗链的办法 - html referrer 访问图片资源403问题 。
- 笔者的目录也是按官方推荐的来的,如下:
1.5 评论
评论功能用了 GitTalk。
1.5.1 申请一个 OAuth App
具体实践如下:
- 首先登录你的 GitHub 账号,然后点击进入Settings。
- 点击 OAuth Apps , Register a new application 或者 New OAuth App 。
- 输入信息。
- 应用信息说明:
Client ID
&&Client Secret
创建成功有 Client ID
和 Client Secret
,保存下来,后面我们会用到。
- 创建评论组件
Vuepress
默认 .vuepress / components
文件夹下的组件会全局注册,因此我们创建一个 comment 组件。
gittalk.css 请点击 这里 <template> <div class="gitalk-container"> <div id="gitalk-container"></div> </div> </template> <script> export default { name: 'comment', data() { return {}; }, mounted() { let body = document.querySelector('.gitalk-container'); let script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js'; body.appendChild(script); script.onload = () => { const commentConfig = { clientID: '你的clientID', clientSecret: '你的clientSecret', repo: '你的仓库名称', owner: '你的用户名', // 这里接受一个数组,可以添加多个管理员,可以是你自己 admin: ['管理用户名'], // id 用于当前页面的唯一标识,一般来讲 pathname 足够了, // 但是如果你的 pathname 超过 50 个字符,GitHub 将不会成功创建 issue,此情况可以考虑给每个页面生成 hash 值的方法. id: location.pathname, distractionFreeMode: false, }; const gitalk = new Gitalk(commentConfig); gitalk.render('gitalk-container'); }; }, }; </script> <style> @import '../css/gittalk.css'; </style>
- 使用评论组件
理论上,我们在每个 markdown
文件里直接加入这个组件即可,但是每次都添加有点麻烦,还是让 node
来帮我们吧
根目录创建 build
文件夹, 创建三个文件 addComponents.js
, delComponents.js
, findMarkdown.js
, 分别代码如下:
// addComponents.js const fs = require("fs"); const findMarkdown = require("./findMarkdown"); const rootDir = "./docs"; findMarkdown(rootDir, writeComponents); function writeComponents(dir) { if (!/README/.test(dir)) { fs.appendFile(dir, `\n \n <comment/> \n `, err => { if (err) throw err; console.log(`add components to ${dir}`); }); } }
// delComponents.js const fs = require("fs"); const findMarkdown = require("./findMarkdown"); const rootDir = "./docs"; findMarkdown(rootDir, delComponents); function delComponents(dir) { fs.readFile(dir, "utf-8", (err, content) => { if (err) throw err; fs.writeFile( dir, content.replace(/\n \n <comment\/> \n /g, ""), err => { if (err) throw err; console.log(`del components from ${dir}`); } ); }); }
// findMarkdown.js const fs = require("fs"); function findMarkdown(dir, callback) { fs.readdir(dir, function(err, files) { if (err) throw err; files.forEach(fileName => { let innerDir = `${dir}/${fileName}`; if (fileName.indexOf(".") !== 0) { fs.stat(innerDir, function(err, stat) { if (stat.isDirectory()) { findMarkdown(innerDir, callback); } else { // 跳过readme 文件,当然你也可以自行修改 if (/\.md$/.test(fileName) && !/README/.test(fileName)) callback(innerDir); } }); } }); }); } module.exports = findMarkdown;
修改 package.json
的 scripts
, 先为每个 md
文件添加组件,然后打包,最后再一一删除 markdown
中的 comment
组件。
"build": "node ./builds/addComponents.js && vuepress build docs && node ./builds/delComponents.js",
笔者的项目里面是把添加了二条命令的,比如 npm run dev:md
和 npm run build:md
才是有评论组件的。
"scripts": { "dev": "vuepress dev docs", "dev:md": "node ./builds/addComponents.js && vuepress dev docs && node ./builds/delComponents.js", "docs:dev": "vuepress dev docs", "build": "vuepress build docs", "build:md": "node ./builds/addComponents.js && vuepress build docs && node ./builds/delComponents.js", "docs:build": "vuepress build docs", "delay": "bash delay.sh", "test": "echo \"Error: no test specified\" && exit 1" },
想要怎样的打包命令,自己修改就行。
- 注意:如果你的文章的评论要和
github
的issues
的同步的话,还要在issues
的label
里添加相应的pathname
和gitalk
,其中pathname
就是评论组件里面的location.pathname
。
比如我的:
1.6 部署到 Github pages
当我们将文档写好后就到了我们最关心的地方了,怎么将打包后的代码推送到远程仓库的 gh-pages
分支上。
- 创建一个deploy.sh
touch deploy.sh
- 编写脚本
#!/usr/bin/env sh # 确保脚本抛出遇到的错误 set -e # 生成静态文件 npm run docs:build # 进入生成的文件夹 cd docs/.vuepress/dist # 如果是发布到自定义域名 # echo 'www.example.com' > CNAME git init git add -A git commit -m 'deploy' # 如果发布到 https://<USERNAME>.github.io # git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master # 如果发布到 https://<USERNAME>.github.io/<REPO> # git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pages cd -
- 设置
package.json
{ "scripts": { "deploy": "bash deploy.sh" }, }
- 发布
npm run deploy // 即可自动构建部署到 github 上。
- 访问自己的域名,比如笔者的:https://biaochenxuying.github.io/blog/ 。
详情移步 vuepress 官网vuepress.vuejs.org。