摘要:在我轉前端以來,一直想要實現(xiàn)一個愿望自己搭建一個可以自動解析文檔的個人站今天終于實現(xiàn)啦,先貼上我的地址確認需求其實一個最簡單的個人站,就是許多的頁面,你只要可以用寫出來就可以,然后掛到上。
在我轉前端以來,一直想要實現(xiàn)一個愿望:
“自己搭建一個可以自動解析Markdown文檔的個人站”
今天終于實現(xiàn)啦,先貼上我的blog地址
確認需求其實一個最簡單的個人站,就是許多的HTML頁面,你只要可以用HTML寫出來就可以,然后掛到Github pages上。但這并不是我想要的。
也有許多的人會選擇用Vuepress,Hexo,Wordpress,Jekyll等等這樣的博客框架來搭建自己的博客,我也都嘗試過,有很多的主題可以給你選擇,你甚至可以自己寫一個主題或者修改其他人的主題讓你的博客變得獨一無二,但這也不是我想要的。
那,我想要的是什么呢?
用Markdown語法書寫博客,支持代碼高亮。
博客所有頁面都是自定義樣式。
Markdown的YAML開頭支持自定義字段,便于在頁面上展示。
在寫博客的同時支持頁面更新,實時看到效果。
其他博客基本的功能。
其實上面很多的博客系統(tǒng),或者靜態(tài)博客生成器,都可以滿足上面大部分的條件,我沒有使用的原因主要是以下幾點:
我很難把控整個流程,如果我在其他人的主題頁面想要增加一些功能,很吃力。
對博客的配置,都會有預料之外的效果。
一些主題也不完善,總是少了自己需要的功能,并且對于Markdown一些基本的功能的支持,也參差不齊。
頁面的構造和樣式的調整,自由度不夠。
分析需求看到這些需求,其實重點不在于你要用什么框架來寫。vue也好react也好甚至Jquery或者原生的JS,都可以。
重點在于你如何處理Markdown文件,把它轉換成你需要的對象,并且在你的頁面中,可以通過路由來控制頁面的內容的切換。
簡而言之,就是兩點:
博客數(shù)據(jù)
頁面路由
當你可以解決這兩個問題,那就解決了所有的問題,因為剩下的就是擼頁面了,天高任你飛,和太陽肩并肩。
數(shù)據(jù)的獲取或許也可以換一個小標題,怎樣拿到Markdown里面的數(shù)據(jù),并且在頁面上讀取數(shù)據(jù)呢?
需要這個數(shù)據(jù)是因為考慮到,在首頁你可能需要展示所有的頁面分類,和所有的Tags,甚至所有的文章的標題和內容,因為你需要做一個博客的檢索?
我把以上提到的所有的博客框架的源碼看了一遍,想看看對他們是怎么處理這個問題的。
然后在我首先在React-static的元am里面,找到了這個:Jdown
這是一個解析Markdown的包,甚至一開始我都是用這個來解析我的Markdown文件中的YAML標簽的內容,并且我還和包的作者DanWebb聊了很多關于搭建個人站的問題。
直到我項目的最后才發(fā)現(xiàn),這個包使用起來會有一些問題,對于一些過長的中文,可能他會解析失敗,我也找不到規(guī)律,對于我來說,要去閱讀他的源碼來定位問題,需要太多的時間,然后我想找一個替代的包,來實現(xiàn)同樣的功能。
然后我就找到了gray-matter
我用這個包成功的把Markdown文件的YAML頭解析為一個JSON對象。我是怎么做的呢?
在項目(打包/編譯)的JS中:
遍歷一個固定目錄(也就是我所有md文件存放的目錄),獲取到所有的以md結尾的文件對象。
對每個文件的YAML頭信息進行轉換,拿到JSON對象。
對JSON對象的內容進行解析,例如取出所有的tag存放到同一個數(shù)組中(你也可以放在頁面上來做這件事)
把所有的頁面的JSON對象放在一個數(shù)組里,用nodeJS的fs模塊寫入到一個data.js的文件中(這個你可以自己定義目錄)
至此,所有頁面獲取數(shù)據(jù)的過程就結束了。
在頁面上使用的時候,就只需要引入這個data.js的文件然后就可以拿到頁面的數(shù)據(jù)啦~
頁面路由是我們實現(xiàn)這個博客系統(tǒng)的關鍵,因為在上一步,我們只是拿到了YAML的信息,但是我們并沒有拿到這個文檔內容,就算我們拿到了內容,也需要我們把他解析為HTML之后,才可以展示出來,那現(xiàn)在怎么做呢?
其實用過webpack的人都知道,webpack有一個loader,我們就是用到markdown的loader來做這樣一件事情,loader就像是一個翻譯工具,把源文件的內容處理之后,返回新的結果,甚至可以多重翻譯之后再返回。那我們就需要用Markdown的loader.
那我們可以在路由中設置,把component設置成對應的md文件,這時候Webpack就會使用loader來解析這個md文件,變成我們需要的HTML頁面,同時我們也可以在解析的過程中,加入自定義的語法,增強和自定義我們的markdown。
在router文件中的設置類似于下面這樣
{ path: "/post/2018-05-20-first", component: () => import("../posts/2018-05-20-first.md") }
你以為就這樣簡單的結束了嗎?
太天真了少年,因為webpack是不支持import的動態(tài)參數(shù)的,也就是說,頁面跑起來之后,想要通過YAML的信息,來拼接出router的值,是不可行的,就算你可以拿到文件名。
我們總不能寫一篇文章,就往這個router里面加入一條記錄吧?
這一步也困擾了我很久,通過資料的搜集和查看其它人的源碼,我在Vuepress的源碼中找到了答案。尤大大是怎么做的呢?
有興趣的朋友可以閱讀一下Vuepress的源碼,關鍵文件的路徑是~/lib/prepare/codegen.js
代碼貼出來(關鍵的信息我已經(jīng)打上了注釋):
exports.genRoutesFile = async function ({ siteData: { pages }, sourceDir, pageFiles }) { function genRoute ({ path: pagePath, key: componentName }, index) { const file = pageFiles[index] const filePath = path.resolve(sourceDir, file) // 這一段實際上就是你的路由信息 let code = ` { name: ${JSON.stringify(componentName)}, path: ${JSON.stringify(pagePath)}, component: ThemeLayout, beforeEnter: (to, from, next) => { import(${JSON.stringify(filePath)}).then(comp => { Vue.component(${JSON.stringify(componentName)}, comp.default) next() }) } }` const dncodedPath = decodeURIComponent(pagePath) if (dncodedPath !== pagePath) { code += `, { path: ${JSON.stringify(dncodedPath)}, redirect: ${JSON.stringify(pagePath)} }` } if (//$/.test(pagePath)) { code += `, { path: ${JSON.stringify(pagePath + "index.html")}, redirect: ${JSON.stringify(pagePath)} }` } return code } const notFoundRoute = `, { path: "*", component: ThemeNotFound }` return ( // 這里你可以放入很多其他的需要在路由文件里面引入的信息 `import ThemeLayout from "@themeLayout" ` + `import ThemeNotFound from "@themeNotFound" ` + `import { injectMixins } from "@app/util" ` + `import rootMixins from "@app/root-mixins" ` + `injectMixins(ThemeLayout, rootMixins) ` + `injectMixins(ThemeNotFound, rootMixins) ` + `export const routes = [${pages.map(genRoute).join(",")}${notFoundRoute} ]` ) }
這個文件在做什么呢?既然import不支持動態(tài)的參數(shù),那我們就直接生成一個router文件,然后使用這個router來配置我們的路由不就可以了嗎?
在自己的代碼里面,把這一步加入到解析markdown的YAML信息這個步驟里,這樣我在拿到了頁面基本信息的同時,也進行了路由的配置。
完成圖經(jīng)過一些頁面的設計,終于完成啦,這里也貼一下blog的源碼,歡迎大家star
貼一波圖:
首頁:
Contact 頁面:
Tags 頁面:
Post頁面:
寫在最后這個blog系統(tǒng),也零零碎碎花了接近一個月的時間,終于是告一段落了,當然這篇文章里面會有許多我沒有提到的部分,比如怎么部署到域名下啊,怎么打包編譯發(fā)布到github pages,怎么實現(xiàn)一些頁面的效果。
為什么我沒有寫這些呢?因為這些都有許多現(xiàn)成的答案啦。
最后新人求一波關注啦~關于這個blog系統(tǒng),如果你有任何不清楚的地方,可以留下你的評論,或者與我聯(lián)系~
轉載請注明出處。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/52677.html
摘要:更新日志更新完成靜態(tài)頁面原型修復使用的正確姿勢更新添加靜態(tài)頁面更新添加使用方法請戳我主要作用就是在你開發(fā)環(huán)節(jié)在后端同學還未開發(fā)完成的情況下,提供一個。 底下評論說是標題黨,或者是光扔個github地址上來的同學我就不說什么了。你們有看看倉庫的提交記錄么?我還沒有吃撐到開個倉庫去騙star.我的出發(fā)點就是每天更新一部分代碼,教大家用我所提到的技術棧搭建一個blog,我的出發(fā)點就是這么簡單...
摘要:前端的所使用的技術棧后端這個小項目才開始,使用已經(jīng)搭建好了前端開發(fā)環(huán)境及相應的的配置。接下來我會帶著大家一起完成整個簡書的開發(fā)工作。 這是一個開源的個人項目。 前端的所使用的技術棧: typescriptes6vue2vue-cliwebpack2axiosangular4angular-cli 后端: nodejsmongoDBejs 這個小項目才開始,使用vue-cli已經(jīng)搭建好了...
摘要:終極解決方案所以我們要統(tǒng)一環(huán)境,直接使用渲染我們的組件,文檔可以參照音樂標題歌手專輯時長省去一些細節(jié)注意需要放在中,的透傳也不要忘了,這樣我們在外部想使用的一些屬性和事件才比較方便。 背景介紹 最近在做vue高仿網(wǎng)易云音樂的項目,在做的過程中發(fā)現(xiàn)音樂表格這個組件會被非常多的地方復用,而且需求比較復雜的和靈活。 預覽地址 源碼地址 圖片預覽 歌單詳情 showImg(https://se...
閱讀 1698·2021-11-22 14:45
閱讀 1206·2021-11-17 09:33
閱讀 3403·2021-09-02 09:48
閱讀 1059·2019-08-30 15:54
閱讀 2817·2019-08-30 15:53
閱讀 2621·2019-08-30 12:54
閱讀 2310·2019-08-29 12:37
閱讀 2479·2019-08-26 13:58