Docsify+GithubPages建站踩坑攻略
布景
上一年年度述职,我感觉构建自己的研发管理知识系统
比较重要,然后想挑选一款免费的管理自己的WIKI的东西
之前用过hugo布置过静态博客,可是这个比较合适单篇的博客,感觉不合适系统化的记录知识,
后边又想到了gitbook,可是其主题太单调了,终究发现了docsify,比较干净清新,颜值尚可,终究就决议运用这个东西记录我的个人系统化WIKI
其实东西是非必须的,最主要的仍是自己要不断地输出内容。
docsify运用+github pages布置
跟着官网的教程根本上能够完结建站加布置
可是有个问题,假如想要使得 https://xxx.github.io/
翻开便是该网站主页
那么文章需求放在xxx.github.io
库房下面,假如是在其他库房B,那么得https://xxx.github.io/B/
才是该站点的主页
踩过的坑
根底运用上,跟着官方的教程走不会出问题,在插件的运用上,仍是需求一些踩坑经验的,我现在主要在运用gitalk时遇到了问题,这里记录一下
0.简略介绍下运用
装备项如下:
clientID: 'Github Application Client ID',
clientSecret: 'Github Application Client Secret',
repo: 'Github repo',
owner: 'Github repo owner',
admin: ['Github repo collaborators, only these guys can initialize github issues'],
distractionFreeMode: false
直接按我的库房来举例说明 https://github.com/noobcoderr/noobcoderr.github.io
clientID和clientSecret生成办法
- github里点击个人头像进入
settings
,然后进入Developer settings
, 进入Oauth APPs
,点击New OAuth App
新建一个Oauth运用 -
APPlication Name
随意填,Homepage Url
和Authorization callback URL
都填https://noobcoderr.github.io/
. 此处假如有个人域名,那么Authorization callback URL
填个人域名 - 完结之后会生成一份
Client ID
和Client secrets
,secrets初次是完好显示的,需求记录好,后续翻开这个页面就不会显示完好的了,只能新建一个
repo、owner、admin、distractionFreeMode的填写
- repo便是填库房名,这里对应我的
noobcoderr.github.io
- owner就填用户名,这里对应我的
noobcoderr
- admin也是填用户名或许安排名,便是允许建立issue的人或许安排,这里是个人库房,所以也只填
['noobcoderr']
- distractionFreeMode 无搅扰形式,默认跟着填false
1.谈论紊乱
现象
1、翻开网站后恣意点开一篇文章,进行谈论,然后点开另一篇文章,此刻谈论区坚持和上一篇文章的共同
2、此刻在该文章下进行谈论,此刻检查长途库房issue,发现谈论依然在上一篇issue里
原因剖析
在开发者形式观察Network形式下履行第一步和第二步,发现 改写当时页面时,会履行三次网络恳求
- 拜访
https://api.github.com/user
获取当时github用户信息 - 拜访以页面标题为
title
,Gitalk
和路由path
为label
为查询条件,查询符合条件的issue
信息,此刻为准确查询 - 恳求
/graphql
接口获取issue
和issue
的谈论信息,查询条件为第二步回来的issue_id
当点击一篇其他文章的时分,也会履行上述的三次网络恳求
- 拜访
https://api.github.com/user
获取当时github用户信息 - 以初次进入页面时的查询条件查询符合条件的issue
- 恳求
/graphql
接口获取issue
和issue
的谈论信息,查询条件为第二步回来的issue
列表里的第一条issue
的issue_id
能够发现,我们进入网站后点击其他文章时的查询issue
条件其实是第一次改写页面时的查询条件,所以后边不论是查询issue
下的谈论,仍是对该文章进行谈论,
终究都会限定在符合第一次查询时的issue
里。
当然最底层的原因猜测或许切换文章时gitalk组件的生命周期未完毕,依然维护的最开端的一篇文章的挑选条件,切换文字时未运用最新的path作为挑选条件 这个需求剖析其源码或许才能具体定位了。
解决办法
切到一篇文章后假如要进行谈论,改写一下当时页面即可,完毕上一次页面的gitalk的生命周期
2.gitalk模块调整不出来
官方的装备是这样的:
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/gitalk/dist/gitalk.css">
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/gitalk.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/gitalk/dist/gitalk.min.js"></script>
<script>
const gitalk = new Gitalk({...})
</script>
看了教程以为css和js都放<head>
里,或许都放<body>
里,可是我当时怎么调终究都没有呈现Gitalk
模块
这块官方教程里css文件和js文件中间用一个空行隔开,应该便是css文件引证要放<head>
里,js引证要放<body>
里,
我前端根底知识较少,所以这块也花了段时间来调整,才把谈论模块调出来。
3.issue初始化创立失败
现象
本地调试时,无法创立issue,在gitalk处点击登录github时,直接回到主页
剖析
这是由于这一步需求运用github登录,会拉起Oauth授权,即你授权给noobcoderr
的谈论Oauth运用,拉起授权时需求提供一个redirect url
,
由所以在本地调试,所以域名为localhost:3000
,这个在github授权完结后进行重定向跳转的时分由于不是公网域名,所以无法辨认。
解决办法
所以在本地就不要调试Gitalk
了,推到长途分支后,在自己的github-pages
页面进行调试
4.部分文章创立的issue都相同
剖析
由于参照docsify官网的装备,没有装备id选项,此刻默认运用的为location.href
作为创立issue
的label
,便是页面的完好url,
可是github
对label
的长度有50的约束,超越50的部分会被截取,只取前50位
而我的域名https://noobcoderr.github.io/#/
就已经占有了31的长度了,而我对不同文章的文件夹的命名又比较长
例如编程语言Python下的最佳实践文章,其完好url为https://noobcoderr.github.io/#/ProgramLanguages/Python/python_best_practice
,其长度为75
当截取为50长度时的结果为https://noobcoderr.github.io/#/ProgramLanguages/Py
,那么Python文件夹下的一切文章的issue都是相同的,由于label超长了,都被截取了
只保存相同的前缀。
解决办法
我看网上有人引荐以下两种,可是通过我的实践,好像都不太行
-
运用
md5(location.href)
, 这样其实也能够,根据完好url的散列值根本不会重复,便是库房里的labels不直观,由于散列值就仅仅一些随机字符串 -
运用
location.pathname
,其实这不合适docsify建立的项目,由于其生成的文章url为host/#/path
中间带一个#
,取location.pathname取到的便是一个/
,那么一切文章的label都相同了 可是运用hugo之类建立的文章好像就没有这个问题,能够运用该值。
通过我的测试,终究运用location.href.split('#')[1]
作为id装备项,能够取到正常的pathname,也能够作为页面的唯一标识
Gitalk的源码简略剖析
作为一个Python服务端,看了看Gitalk的源码,仍是能够看出一些表面的意思的,源码文件为gitalk.jsx
关键的一些源码粘贴如下:
class GitalkComponent extends Component {
state = {
user: null,
issue: null,
comments: [],
localComments: [],
comment: '',
isNoInit: false,
isIniting: true,
isCreating: false,
isOccurError: false,
errorMsg: '',
}
constructor (props) {
super(props)
this.options = Object.assign({}, {
id: window.location.href,
number: -1,
labels: ['Gitalk'],
title: window.document.title,
body: '', // window.location.href + header.meta[description]
url: window.location.href,
}, props.options)
}
}
render () {
const { isIniting, isNoInit, isOccurError, errorMsg, isInputFocused } = this.state
return (
<div className={`gt-container${isInputFocused ? ' gt-input-focused' : ''}`}>
{isIniting && this.initing()}
{!isIniting && (isNoInit ? [] : [this.meta()])}
{isOccurError && <div className="gt-error">{errorMsg}</div>}
{!isIniting && (isNoInit ? [this.noInit()] : [this.header(),this.comments()])}
</div>
)
}
}
module.exports = GitalkComponent
剖析gitalk源码
入口应该为render()
该办法会回来一个gitalkgt-container
容器,这个容器便是包含gitalk的模块,履行流程为
- <第一块> 展现初始化状态,初始化时展现Gitalk 加载中 …
- <第二块> 在初始化完毕的情况下,假如成功则履行
this.meta()
, 该部分获取各种元数据并展现 - <第三块> 在发生错误的时分在
gt-error
模块内展现错误信息 - <第四块> 在初始化完毕的情况下,假如成功则履行
header
办法和comments
办法,不成功则履行this.noInit
办法
meta办法
只做数据展现,不做数据获取,登录时展现谈论数量,以及一些弹出式菜单,如注销,按时间正序/倒序排序,gitalk版本等等,未登录时展现登录按钮等
header和comments办法
展现已有的数据,没有获取数据操作
noInit办法
该办法这个办法会拿到文章对应issue的一切谈论
- 最开端是展现未找到相关的issue进行谈论,请联络用户进行创立
- 假如未登录github的话,展现按钮进行登录,进行Oauth授权,获取用户信息
- 假如当时登录github用户是此库房管理员的话,那么展现创立issue按钮,调用handleIssueCreate办法
-
handleIssueCreate办法: 会调用
createIssue
办法创立issue,创立完结后,会调用getComments
办法获取当时issue的一切谈论 - createIssue办法: 创立issue。在装备的owner用户下的repo库房里,以页面的title为issue的标题,以Gitalk和id为issue的labels,以页面完好的url作为issue的内容,即首条谈论
- getComments办法:获取issue的一切谈论,假如未登录,则调用getCommentsV3办法,假如登录了,则调用graphql的getComments办法
- getCommentsV3办法:获取issue的谈论,首要按照issue_id进行取,假如取到就展现到页面上,假如未取到则安labels进行取
- graphql的getComments办法:获取指定issue_id的一切谈论
- handleLogin办法:会将一切谈论放在浏览器的本地存储里
-
handleIssueCreate办法: 会调用
从源码可见GitalkComponent
维护了很多数据,每次进入新页面都会调用render()办法,可是上一次的数据有没有被整理我不太清楚,理论上应该会被整理,
可是上面说到的谈论紊乱确实是感觉有缓存,这点需求后边咨询一下搞前端的同事确认下。
学习到的javascript知识
- 三元表达式 bool ? A : B ,假如bool为真,则履行A,bool为假,则履行B
- && 高级用法:用于履行句子 bool && func(), 假如bool为真,则履行后边的句子
- .jsx文件为React结构对javascript的扩展