哀家敲代码就是一把梭!
哀家敲代码就是一把梭!
前言
以个人的实际经历为例,分享一下当不会技术却需要研读源码时,可能会有所帮助的技巧。希望各位写代码都是一把梭,拿起键盘就是干!

搞事
这几天搞的大事就是自己把现在博客用的indigo主题自己折腾了一下,参考raytaylorism主题加了一个读书页面。raytaylorism主题确实有很多我非常中意的特性,但是依我个人的审美观还是觉得indigo主题更加美观,所以写了一篇文章分析了一下indigo主题没有的功能,自己研究研究源码改一下,就是这篇:indigo主题尚待完善的功能。我最想要的就是读书这个板块了,这个板块稍微改一下就能把看过的电影或番剧,听过的音乐都记上去,并不是要装文艺,但是有些东西如果忘了真的可惜

研究代码的第一步是使用它
要了解代码的工作方式,就应该先使用它。我把我的主题切换成raytaylorism主题,发现想要改变如上图读书页面中的内容,只需要改变source/_data/reading.json中的内容就行了,json大概是这种结构,不用多解释,看到就一目了然的结构
{
"define": {
"readed": "已读",
"reading": "在读",
"wanted": "想读"
},
"contents": {
"readed": [{
"title": "众妙之门:网站UI设计之道",
"cover": "https://img3.doubanio.com/lpic/s23139051.jpg",
"review": "推荐非UI人士了解UI阅读。",
"score": "7",
"doubanLink": "http://book.douban.com/subject/20281463/"
}, {
"title": "JavaScript模式",
"cover": "https://img1.doubanio.com/lpic/s11337059.jpg",
"review": "书很薄,但内容相当实用。",
"score": "8.5",
"doubanLink": "http://book.douban.com/subject/11506062/"
}, {
"title": "JavaScript语言精粹",
"cover": "https://img3.doubanio.com/lpic/s27993864.jpg",
"review": "这是一本前端人员的基础书,强烈推荐阅读,而且越早看受益越多!",
"score": "9.5",
"doubanLink": "http://book.douban.com/subject/11874748/"
}],
"reading": [{
"title": "网络游戏核心技术与实战",
"cover": "https://img1.doubanio.com/lpic/s27881888.jpg",
"review": "",
"score": null,
"doubanLink": "http://book.douban.com/subject/25850090/"
}],
"wanted": [{
"title": "计算机程序的构造和解释",
"cover": "https://img5.doubanio.com/lpic/s1113106.jpg",
"review": "",
"score": null,
"doubanLink": "http://book.douban.com/subject/1148282/"
}]
}
}
粗看源码
但是单从使用的角度无法明白具体的实现方式。就算知道了这个页面由这个json文件控制,但是为什么是这个json文件,而且数据是怎么被抓取并生成静态页面的,并不知道,所以接下来要看源码了
全局查找,定位要看的源码
源码中很多文件,我这里只需要了解读书页面,不需要理解所有的源码,所以需要定位哪一个部分才是需要看的源码
不管看什么代码,如果不知道要看什么部分,全局查找多半能定位到需要看的代码。这里我的具体做法如下:
-
在火狐浏览器中,鼠标停留在某一本书上,点击右键->查看元素。如图,可以看到,这个元素的class是book-item col s12 m6

-
在Atmo编辑器中全局查找关键字:book-item col s12 m6,如图,定位到reading.ejs这个文件,毫无疑问,看着名字就知道这个文件就是生成读书页面的文件

不惧怕陌生的代码,代码都是相通的
笔者是一个基本不会前端技术的人,水平是属于上学校的Web课也就能及个格的那种。.ejs是什么东西我是完全不知道的,Node.js也只是听过名字而已。但是当我打开reading.ejs看到陌生的代码,却能把代码逻辑看懂个大概,因为不管是什么代码都有相似之处
下面是reading.ejs的代码。显然<%......%>中的都是逻辑代码,以var开头可以声明了一个变量, readingData这个变量名一看就知道是reading.json中的数据,tabCount是Tab的数量,其值为3,因为一共3个Tab,分别是“已读”,“在读”,“想读”.第二段和第三段,外层都有for循环,分别用来生成Tab和book-item
无论是什么代码,都有相似点,这里列举一下
- var开头一看就是变量
- 有new关键字知道在创建对象
- if else for switch,逻辑控制语句所有语言都得有
- a.b.c 一看就知道在调用成员
- a.b.c()是在调用函数
- 文件的名字,变量的名字,对象的名字,函数的名字描述了它的作用
<% var readingData = site.data.reading;
var tabCount = Object.keys(readingData.define).length;
%>
<div class="container main-container">
<% if (readingData) { %>
<div class="">
<div class="row">
<ul class="tabs ">
<% for (var key in readingData.define) { %>
<li class="tab col s<%= 12 / tabCount %> ">
<a class="<%= theme.color.tab %>-text " href="#<%= key %>"><%= readingData.define[key] + '(' + readingData.contents[key].length + ')'%></a>
</li>
<% } %>
</ul>
</div>
<% for (var key in readingData.contents) { %>
<div id="<%= key %>" class="row" style="margin-top: 20px;">
<% var bookList = readingData.contents[key]; %>
<% for (var i in bookList) { %>
<div class="book-item col s12 m6">
<div class="card small hoverable">
<div class="card-image waves-effect waves-block waves-light">
<img class="card-cover-image activator" src="<%= bookList[i].cover %>">
</div>
<div class="card-content <%= theme.color.link %>-link-context">
<span class="card-title truncate activator grey-text text-darken-4"><%= bookList[i].title %>
</span>
<p><%= __('reading.score') %>: <%= bookList[i].score || '???' %>
<a class="external-link right" href="<%= bookList[i].doubanLink %>" target="_blank">
<i class="fa fa-external-link"></i>
</a>
</p>
</div>
<div class="card-reveal">
<span class="card-title grey-text text-darken-4"><%= __('reading.comment') %>
<i class="fa fa-times-circle-o right"></i>
</span>
<p><%= bookList[i].review %></p>
</div>
</div>
</div>
<% } %>
</div>
<% } %>
</div>
<%- partial('_partial/plugin/comment', {page_id: 'reading'}) %>
<% } else { %>
<%- partial('_partial/construction') %>
<% } %>
</div>
自己写Demo
当时试着直接把reading.ejs拷到indigo主题中,但是当我执行hexo -g时报一堆错误信息,果然事情不可能这么简单。应该是缺失了一些必要的文件,可是我不了解需要哪些页面才能构成一个页面,要了解这一点,就需要知道Hexo博客主题是怎么构成的,所以到网上找教程做个Demo,这是我找到的一个手把手教程:从零开始制作 Hexo 主题
按照教程走一遍后,大概知道了整个工作方式:
- 除了其子目录下的文件,/layout目录下的文件会生成Html页面
- 通过如下代码导入其他ejs文件(这里导入了header.ejs文件)
<%- partial('_partial/header') %>
- /layout/layout.ejs,通过<%- body %>来引用/layout目录下的ejs文件,/layout目录下的子目录下的ejs文件除外
- /source目录下的文件是Html页面中会用到的css,font,js
- 你的博客/source/_data下的yml文件和json文件中的内容会记录到你的博客/db.json文件中,并在ejs代码中可以引用其中的数据
那么现在我清楚为什么代码会报错了,因为显然读书页面导入了css和js,而这些文件并不能被找到
想知道代码的作用就删除它
显然raytaylorism主题的作者不是在reading.ejs中引入css和js的,上面通过写Demo而得知决定读书页面生成的代码不止是reading.ejs,还有layout.ejs,下面是其代码
<%- partial('_partial/head') %>
<body>
<img src="/weixin_favicon.png" style="position: absolute; left: -9999px; opacity: 0; filter: alpha(opacity=0);">
<%- partial('_partial/header') %>
<main>
<%- body %>
<%- partial('_partial/float') %>
</main>
<%- partial('_partial/footer') %>
<%- partial('_partial/after_footer') %>
</body>
</html>
可以看到layout.ejs中引用了一大堆文件,鬼才想一个一个去看引用文件的代码,我只关心什么代码会影响读书页面。最简单粗暴的弄懂代码的方式就是删除它,于是我依次删掉那些引用文件的代码,发现只有最后一项引用会让读书页面没有css和js。然后看after_footer.ejs,又是一堆引用,方法当然还是删除!删除!删除!
复制,粘贴,拿起键盘就是干!
上一步中已经提取到了所有与读书页面的相关代码,接下来要做的就是把它们插分到indigo主题中,indigo主题中有它自己的layout.ejs,而且头部布局需要在每个掌管页面的ejs中添加代码引用而不是在layout.ejs中直接引用,还有就是需要把引用css和js的代码直接写reading.ejs中。总之,需要稍微改造一把,然后就大功告成啦
感想
这篇文章,对于我来说,叙事部分和方法部分都是有用的。但是对于其他读者,可能叙事部分会看得一脸懵逼,但是希望看文章的人能多少学到一些研读源码时可能会用到的方法,我以后研读源码时也会借鉴自己这次的经验
我认为自己拥有不错的阅读理解能力,不止是在研读代码方面。我能冷静下来阅读并理解晦涩难懂的书,或者是英文文章,我对此感到高兴。并不是炫耀我有多厉害,只是从很多事情中得出的结论。我既能以平常心对待自己的优点,也能以平常心对待自己的缺点
其实这个故事是精简版本,其实我并不能一下子就想到什么时候该怎么做才是对的,有时会因为选择了错误的方法卡在一些地方而产生负面情绪,然而情绪可以调整,方法可以不断去尝试和改变,所以最后还是成功啦
后续
-
我会把我改动后的主题传到github,链接会留在这里
-
手动写json一点都不优雅,写个代码自动生成吧,new一个对象多一本书的方式多么优雅
-
把看过的书、电影、,番剧还有听过的歌都搬到博客上吧
-
其实我在这一个星期再次失去了人生的方向,会研究Hexo博客主题的源码是因为我实在不知道什么才是有意义事情了。这是个大事,没有方向,谈何努力,我必须在下周之前找到人生的方向
补充
后续中的1,2两条已经做到啦,具体看这篇吧,走你
方向是大事