本文系我的(pdai)原創文章,轉載請著明出處,博客搭建效果請參考:[Java 全棧知識體系](https://www.pdai.tech)html
博客/文檔搭建前言vue
博客/文檔基礎搭建react
文檔搭建插件和配置webpack
第二部分 - 博客/文檔的自動編譯nginx
第三部分 - 博客/文檔的自動部署github
搭建博客有不少選擇,平臺性的好比: 知名的CSDN, 博客園, 知乎,簡書等;本身搭建好比 Hexo, Gitbook, Docisify等等。我有一顆不安分的心,每種我都用過...可是最後的最後我仍是選擇了將博客逐移至本身搭建的vuepress。 @pdai
搭建博客有不少選擇,平臺性的好比: 知名的CSDN, 博客園, 知乎,簡書等;本身搭建好比 Hexo, Gitbook, Docisify等等。
如下系統由我獨立設計,開發和運維(總計四萬多行代碼吧), 這裏只展現博客文檔部分。如下圖片是我在以前博客園寫文章截圖的:
等等。
以前用搭建過基於K8S的完整的平臺,寫了系列的文章總結。用的工具就是用的 Docisify。
效果以下:
支持自定義樣式,自定義js權限,這代表自由控制程度會很高(這點看CSDN就略保守了);可是網站長期沒有更新,主頁樣式感受停留在十年前;客戶端程序,略有點low;
效果以下:
具體能夠看我寫的這篇:【博客園配置】博客園自定義配置有哪些騷操做
相似博客/文檔工具比對vuepress能夠看出其優點:如下內容摘自: Vuepress官網
VuePress 能作的事情,Nuxt 理論上確實可以勝任,但 Nuxt 是爲構建應用程序而生的,而 VuePress 則專一在之內容爲中心的靜態網站上,同時提供了一些爲技術文檔定製的開箱即用的特性。
這兩個項目一樣都是基於 Vue,然而它們都是徹底的運行時驅動,所以對 SEO 不夠友好。若是你並不關注 SEO,同時也不想安裝大量依賴,它們仍然是很是好的選擇!
Hexo 一直驅動着 Vue 的文檔 —— 事實上,在把咱們的主站從 Hexo 遷移到 VuePress 以前,咱們可能還有很長的路要走。Hexo 最大的問題在於他的主題系統太過於靜態以及過分地依賴純字符串,而咱們十分但願可以好好地利用 Vue 來處理咱們的佈局和交互,同時,Hexo 的 Markdown 渲染的配置也不是最靈活的。
咱們的子項目文檔一直都在使用 GitBook。GitBook 最大的問題在於當文件不少時,每次編輯後的從新加載時間長得使人沒法忍受。它的默認主題導航結構也比較有限制性,而且,主題系統也不是 Vue 驅動的。GitBook 背後的團隊現在也更專一於將其打造爲一個商業產品而不是開源工具。
VuePress 由兩部分組成:第一部分是一個極簡靜態網站生成器,它包含由 Vue 驅動的主題系統
和插件 API
,另外一個部分是爲書寫技術文檔而優化的默認主題
,它的誕生初衷是爲了支持 Vue 及其子項目的文檔需求。
每個由 VuePress 生成的頁面都帶有預渲染好的 HTML,也所以具備很是好的加載性能和搜索引擎優化(SEO)。同時,一旦頁面被加載,Vue 將接管這些靜態內容,並將其轉換成一個完整的單頁應用(SPA),其餘的頁面則會只在用戶瀏覽到的時候才按需加載。
事實上,一個 VuePress 網站是一個由 Vue、Vue Router 和 webpack 驅動的單頁應用。若是你之前使用過 Vue 的話,當你在開發一個自定義主題的時候,你會感覺到很是熟悉的開發體驗,你甚至可使用 Vue DevTools 去調試你的自定義主題。
在構建時,咱們會爲應用建立一個服務端渲染(SSR)的版本,而後經過虛擬訪問每一條路徑來渲染對應的HTML。這種作法的靈感來源於 Nuxt 的 nuxt generate
命令,以及其餘的一些項目,好比 Gatsby。
其總體的插件架構案例: Vuepress 插件架構案例
文檔的搭建比較簡單,主要記錄流程,有些步驟你在閱讀的時候若是以爲不須要, 能夠直接略過。
先卸載已安裝的homebrew,命令以下:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
而後從新安裝:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
經過該方法直接獲取最新的homebrew,出現預期效果。注:上述能夠修復chown: /usr/local: Operation not permitted
這個問題。
若是以爲慢,須要更換 Brew 鏡像源, 請看考: 更換 Brew 鏡像源
Vuepress對Node版本要求: Node.js 版本 >= 8.6。
若有須要,請參考這兩篇文章:
yarn global add vuepress
# 目錄 mkdir tech-arch-doc cd tech-arch-doc # 初始化 yarn init -y # 或者 npm init -y # 放markdown的文件夾 mkdir md # package.json, 裏面放的內容看後文 touch package.json # 放vuepress相關 mkdir .vuepress cd .vuepress # 建立config.js, 裏面放的內容看後文 touch config.js # 放圖片和CNAME mkdir public # 放樣式的 mkdir styles # 在裏面建立放圖片 cd public mkdir _images
最後的結構大概是這樣:(其它灰色的文件夾是編譯出來的)
--- home: true heroImage: /_images/index-read.gif actionText: 快速開始 → actionLink: /md/java/basic/java-basic-oop.md features: - title: 夯實基礎 details: 不積跬步無以致千里, 仰望星空還需腳踏實地 - title: 構建體系 details: 告別碎片化學習,幫助你構築你本身的知識體系 - title: 全棧開發 details: 以Java開發爲背景,全棧開發,DevOps footer: © 2017-present pdai ---
module.exports = { port: "3000", dest: "docs", ga: "UA-xxxxx-1", base: "/", markdown: { lineNumbers: true, externalLinks: { target: '_blank', rel: 'noopener noreferrer' } }, locales: { "/": { lang: "zh-CN", title: "Java 全棧知識體系", description: "包含: Java 基礎, Java 部分源碼, JVM, Spring, Spring Boot, Spring Cloud, 數據庫原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分佈式, 中間件, 開發工具, Git, IDE, 源碼閱讀,讀書筆記, 開源項目..." } }, head: [ // ico ["link", {rel: "icon", href: `/favicon.ico`}], // meta ["meta", {name: "robots", content: "all"}], ["meta", {name: "author", content: "pdai"}], ["meta", {name: "keywords", content: "Java 全棧知識體系, java體系, java知識體系, java框架,java詳解,java學習路線,java spring, java面試, 知識體系, java技術體系, java編程, java編程指南,java開發體系, java開發,java教程,java,java數據結構, 算法, 開發基礎"}], ["meta", {name: "apple-mobile-web-app-capable", content: "yes"}] ], plugins: [ ], themeConfig: { // repo: "realpdai/tech-arch-doc", docsRepo: "realpdai/tech-arch-doc", // logo: "/logo.png", editLinks: true, sidebarDepth:0, locales: { "/": { label: "簡體中文", selectText: "Languages", editLinkText: "在 GitHub 上編輯此頁", lastUpdated: "上次更新", nav: [ ], sidebar: { } } } } };
進入項目目錄
{ "name": "tech-arch-doc", "version": "0.0.1", "private": true, "scripts": { "dev": "vuepress dev", "build": "vuepress build" }, "devDependencies": { "vuepress": "^1.0.2" } }
vuepress dev
初步效果:
默認狀況下,文件將會被生成在 .vuepress/dist,固然,你也能夠經過 .vuepress/config.js 中的 dest 字段來修改,生成的文件能夠部署到任意的靜態文件服務器上
請參考官網 https://vuepress.vuejs.org/zh...
vuepress build
這裏主要介紹文檔搭建除了默認加載的配置和插件以外,新增長的插件和配置。
注意不少網上的例子仍是基於老的版本的,甚至我用vuepress的時候,官網尚未更新過來。
最佳配置請參考: 這裏: (其它官網的配置都沒有更新)
.custom-page-class{ /* 自定義的樣式 */ } // markdown blockquote blockquote font-size 1rem color #2c3e50; border-left .5rem solid #42b983 background-color #f3f5f7 margin 1rem 0 padding 1rem 0 1rem 1rem & > p margin 0 // markdown h2 h2 font-size 1.65rem padding-bottom 1rem border-bottom 1px solid $borderColor
// 內容的寬度 $contentWidth = 100% // 顏色 $accentColor = #3eaf7c $textColor = #2c3e50 $borderColor = #eaecef $codeBgColor = #282c34
文章很長,添加右下角一鍵返回頂部按鈕,官網提供了 back-to-top 插件.
安裝
yarn add -D @vuepress/plugin-back-to-top@next # OR npm install -D @vuepress/plugin-back-to-top@next
使用
module.exports = { plugins: ['@vuepress/back-to-top'] }
插件使用你還能夠參考:插件官網
圖片縮放可使用@vuepress/plugin-medium-zoom插件,它基於medium-zoom 插件。
yarn add -D @vuepress/plugin-medium-zoom@next # OR npm install -D @vuepress/plugin-medium-zoom@next
簡單使用:
module.exports = { plugins: ['@vuepress/medium-zoom'] }
自定義選項:
module.exports = { plugins: { '@vuepress/medium-zoom': { selector: 'img.zoom-custom-imgs', // medium-zoom options here // See: https://github.com/francoischalifour/medium-zoom#options options: { margin: 16 } } } }
效果能夠點擊本文中的圖片查看, 具體使用你能夠參考: 插件官網。
代碼託管平臺聽從 OAuth 2 spec 提供了 OAuth API。Vssue 利用平臺提供的 OAuth API,使得用戶能夠登陸並發表評論。那麼有哪些評論插件可使用?這裏使用Vssue,它比較新,可能知道的人還很少。@pdai
Vssue , Gitalk 和 Gitment,爲什麼選擇Vssue:
下面是 Vssue 的簡要工做過程:
用戶在平臺的受權頁面容許 Vssue 接入後,平臺會帶有 code
或 token
重定向回 Vssue 的頁面(若是是 code
,Vssue 則會根據 code
向平臺請求 token
)。
Vssue 獲取 token
後,會將 token
存儲在 localstorage 中,因而用戶就成功使用平臺的賬號「登陸」到了 Vssue。
接下來, Vssue 就能夠獲取用戶的基本信息、獲取當前頁面的評論,用戶也能夠發表評論了。
添加以下配置:具體參考Vssue 官網教程
plugins: { '@vssue/vuepress-plugin-vssue': { // 設置 `platform` 而不是 `api` platform: 'github', // 其餘的 Vssue 配置 owner: 'OWNER_OF_REPO', repo: 'NAME_OF_REPO', clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', }, },
效果以下:
:::warning 注意:
導出頁面只在我本地開放,線上功能我暫時關閉了。
:::
本身寫了文檔PDF的導出功能(Page, Group, Current是我導出功能裏的代號
): Page = Group1+...GroupN, Group = Current1+...CurrentN
以SpringBoot部分章節導出爲例,導出效果以下:
你是否是常看到別人的項目中加了<img src="https://img.shields.io/badge/...;>這種標籤?這種標籤主要基於svg,主要有兩種:
添加後效果(狀態爲自動獲取):
<img src="https://travis-ci.com/realpdai/tech-arch-doc.svg?branch=master">
<img src="https://img.shields.io/github/license/realpdai/tech-arch-doc">
<img src="https://img.shields.io/badge/...;>
注意百度統計添加, 考慮在每一個頁面點擊時做記錄,在enhanceApp.js中攔截router:
export default ({router}) => { router.beforeEach((to, from, next) => { // @pdai: 對每一個頁面點擊添加百度統計 if(typeof _hmt!='undefined'){ if (to.path) { _hmt.push(['_trackPageview', to.fullPath]); } } // continue next(); }) };
百度統計裏某個頁面效果以下:
複製你網站時,禁用複製或者添加版權信息等。
安裝
npm install vuepress-plugin-copyright
配置
// .vuepress/config.js module.exports = { plugins: [ [ 'copyright', { noCopy: true, // 選中的文字將沒法被複制 minLength: 100, // 若是長度超過 100 個字符 }, ], ], }
效果, 拷貝本頁面會自動添加:
著做權歸 xxxx 全部。 連接:https://www.pdai.tech/md/about/blog/blog-build-vuepress.html
更多請參考插件:vuepress-plugin-sitemap
這裏給個連接供參考,我這邊本身添加的meta信息沒有用它。
主要用於向百度站點自動推送,有助於SEO。
安裝
npm install -D vuepress-plugin-baidu-autopush
添加配置
module.exports = { plugins: [ 'vuepress-plugin-baidu-autopush' ] };
更多請參考插件:vuepress-plugin-baidu-autopush
主要用於生成站點的Sitemap,有助於SEO。
安裝
npm install vuepress-plugin-sitemap
配置
// .vuepress/config.js module.exports = { plugins: { 'sitemap': { hostname: 'https://www.pdai.tech' }, } }
更多請參考插件:vuepress-plugin-sitemap
在代碼區,添加一個拷貝按鈕,用來拷貝代碼。
安裝
npm install vuepress-plugin-code-copy
配置
module.exports = { plugins: [['vuepress-plugin-code-copy', true]] }
更多請參考插件:vuepress-plugin-code-copy
請參考 awesome-vuepress
module.exports = { port: "3000", dest: "docs", ga: "UA-xxxxxxxxxxx-1", base: "/", markdown: { lineNumbers: true, externalLinks: { target: '_blank', rel: 'noopener noreferrer' } }, locales: { "/": { lang: "zh-CN", title: "Java 全棧知識體系", description: "包含: Java 基礎, Java 部分源碼, JVM, Spring, Spring Boot, Spring Cloud, 數據庫原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分佈式, 中間件, 開發工具, Git, IDE, 源碼閱讀,讀書筆記, 開源項目..." } }, head: [ // ico ["link", {rel: "icon", href: `/favicon.ico`}], // meta ["meta", {name: "robots", content: "all"}], ["meta", {name: "author", content: "pdai"}], ["meta", {name: "keywords", content: "Java 全棧知識體系, java體系, java知識體系, java框架,java詳解,java學習路線,java spring, java面試, 知識體系, java技術體系, java編程, java編程指南,java開發體系, java開發,java教程,java,java數據結構, 算法, 開發基礎"}], ["meta", {name: "apple-mobile-web-app-capable", content: "yes"}], // baidu statstic ["script", {src: "https://hm.baidu.com/hm.js?xxxxxxxxxxx"}] ], plugins: [ ['@vuepress/back-to-top', true], ['@vuepress/medium-zoom', { selector: 'img', // See: https://github.com/francoischalifour/medium-zoom#options options: { margin: 16 } }], // see: https://vssue.js.org/guide/vuepress.html#usage ['@vssue/vuepress-plugin-vssue', { // set `platform` rather than `api` platform: 'github', // all other options of Vssue are allowed owner: 'realpdai', repo: 'tech-arch-doc-comments', clientId: 'xxxxxxxxxxx', clientSecret: 'xxxxxxxxxxxxxxxxxxxxxx', }], // see: https://vuepress.github.io/zh/plugins/copyright/#%E5%AE%89%E8%A3%85 ['copyright', { noCopy: false, // 容許複製內容 minLength: 100, // 若是長度超過 100 個字符 authorName: "https://www.pdai.tech", // clipboardComponent: "請註明文章出處, [Java 全棧知識體系](https://www.pdai.tech)" }], // see: https://github.com/ekoeryanto/vuepress-plugin-sitemap ['sitemap', { hostname: 'https://www.pdai.tech' }], // see: https://github.com/IOriens/vuepress-plugin-baidu-autopush ['vuepress-plugin-baidu-autopush', { }], // see: https://github.com/znicholasbrown/vuepress-plugin-code-copy [['vuepress-plugin-code-copy', true]] // ... ], themeConfig: { //repo: "realpdai/tech-arch-doc", docsRepo: "realpdai/tech-arch-doc", //logo: "/logo.png", editLinks: true, sidebarDepth:0, locales: { "/": { label: "簡體中文", selectText: "Languages", editLinkText: "在 GitHub 上編輯此頁", lastUpdated: "上次更新", nav: [ { text: '關於', link: '/md/about/me/about-me.md' } ], sidebar: { "/md/about/": genSidebar4About() } } } } }; // About page function genSidebar4About(){ return [ { title: "關於", collapsable: false, sidebarDepth: 0, children: [ "me/about-me.md", "me/about-content.md", "me/about-content-style.md", "me/about-arch.md", "me/about-motivation.md" ] }, { title: "關於 - 本文檔的搭建", collapsable: false, sidebarDepth: 0, children: [ "blog/blog-build-vuepress.md", "blog/blog-build-ci.md", "blog/blog-build-cd.md", "blog/blog-build-ssl.md" ] } ]; }
{ "name": "tech-arch-doc", "version": "2.0.1", "private": true, "scripts": { "dev": "vuepress dev", "build": "vuepress build" }, "devDependencies": { "@vuepress/plugin-back-to-top": "^1.0.3", "@vuepress/plugin-medium-zoom": "^1.0.4", "vuepress": "^1.0.2" }, "dependencies": { "@vssue/api-github-v3": "^1.1.2", "@vssue/vuepress-plugin-vssue": "^1.2.0", "vuepress-plugin-baidu-autopush": "^1.0.1", "vuepress-plugin-code-copy": "^1.0.4-alpha", "vuepress-plugin-copyright": "^1.0.2", "vuepress-plugin-sitemap": "^2.3.0" } }
export default ({router}) => { router.beforeEach((to, from, next) => { // @pdai: 對每一個頁面點擊添加百度統計 if(typeof _hmt!='undefined'){ if (to.path) { _hmt.push(['_trackPageview', to.fullPath]); } } // continue next(); }) };
.custom-page-class{ /* 自定義的樣式 */ } // markdown blockquote blockquote font-size 1rem color #2c3e50; border-left .5rem solid #42b983 background-color #f3f5f7 margin 1rem 0 padding 1rem 0 1rem 1rem & > p margin 0 // markdown h1 h1 font-size 2rem padding-bottom 1rem border-bottom 1px solid $borderColor // markdown h2 h2 font-size 1.65rem border-bottom 0px solid $borderColor // custom block for tip .custom-block .custom-block-title font-weight 600 margin-bottom -0.4rem &.tip, &.warning, &.danger padding .1rem 1.5rem border-left-width .5rem border-left-style solid margin 1rem 0 &.tip background-color #dfefff border-color #428eb9 // logo .navbar .logo height $navbarHeight - 1.6rem min-width $navbarHeight - 1.6rem margin-right 0rem vertical-align top
// 內容的寬度 $contentWidth = 100% // 顏色 $accentColor = #3eaf7c $textColor = #2c3e50 $borderColor = #eaecef $codeBgColor = #282c34
文檔託管在Github,有幾種選擇: Github自帶的Github Actions,或者插件Travis CI, 或者插件Circle CI。@pdai
注意: Travis CI有個坑爹的地方要注意: 它有travis.com和travis.org兩個網站,一個是對公有項目,一個是對私有項目;而後,github是能夠在公有和私有項目中切換的,因而在切換後,一些配置可能沒法正確設置。
進入 https://github.com/marketplac...
注意: 這裏只是簡單作編譯操做,您能夠將編譯的結果(靜態的html文件)強制推送至當前倉庫專門放編譯後文件的分支;也能夠在本身的服務器上安裝travis-cli,在travis.com(注意不是travis.org)生成證書信息(自動生成相關環境變量),來進行自動化部署。
這裏上述兩種方案都沒有采用,是由於:
language: node_js sudo: false node_js: - "12" cache: yarn: true directories: - node_modules branches: only: - master env: global: - GITHUB_REPO: github.com/realpdai/tech-arch-doc.git before_install: - export TZ=Asia/Shanghai script: - vuepress build
本文主要介紹 當前文檔是如何在我本身的服務器自動編譯部署的。@pdai
以前購買了一個低配的阿里雲虛擬機,系統是CentOS 7.x。
curl -sL https://rpm.nodesource.com/setup_10.x | bash -
yum install -y nodejs
其它方式能夠參考此文 https://blog.csdn.net/bbwangj...
以前服務器上搭建過gitlab-ee,jenkins,httpd等,因爲我本身的代碼託管已經切換至github的私有倉庫,因此如今須要清理下;不須要清理的,請略過。
https://blog.csdn.net/huhuhue...
https://www.cnblogs.com/richa...
https://www.centos.bz/2018/01...
https://www.cnblogs.com/jepso...
https://www.cnblogs.com/alvin...
https://blog.csdn.net/benchem...
經過webhook觸發編譯並reload nginx
本文主要記錄 本文檔的域名,HTTPS,備案。 @pdai
文檔的域名,HTTPS,備案 這三個步驟不能反,由於存在依賴關係。
30分鐘以內就審覈完成
這個詳情頁面在備案的時候須要拍照上傳。
80/443端口經過域名直接訪問是須要備案的,在18年的時候我搭建過的我的網站是不要備案的。
期間須要手機經過阿里雲人臉認證,並上傳 身份證,域名和證書拍照等。
注意備案初審由阿里雲代理的,要求: 我的網站必須命名爲xxxx的我的博客
或者xxx的我的主頁
,不然備案不經過。申請的週期大概最可能是20天,申請完了以後工信部會發短信到登記到手機號,以後到8小時就可使用了。
那麼搭建這樣的網站須要多少服務器資源呢,阿里雲坑的地方是新用戶首年都便宜,後面續費就貴了。
推薦選擇1CPU,1-2G內存便可;1Core-1GB一年價格287多,選擇五年也就642多;後期若有需求,能夠在線
增長配置
:::tip
後續: 我將阿里到服務器降級到了1U 1GB,可是使用Vuepress build 編譯靜態頁面時內存須要700MB,這將致使內存不夠。我這邊考慮使用swap方式,置換一些內存資源放置swap磁盤。
:::
參考文章以下: https://blog.csdn.net/u010457...
編譯前
編譯中 (內存不夠會置換至swap區)