备份迁移ghost博客到hexo

最近hexo很火, 于是乎打算弄一个玩玩. 配合gh-pages, 因为是纯静态的博客服务, 所以还不用担心服务器被攻击的问题.
hero提供了ghost的migrate插件, 所以迁移起来比较容易.

初体验

1
2
3
npm i hexo-cli -g
hexo init
npm i

tip: 怕慢可挂梯或用cnpm

我的hexo版本是3.1.1, 不同的版本配置有稍许差异

然后配置_config.yml文件的deploy部分:

1
2
3
4
5
# Deployment
## Docs: http://hexo.io/docs/deployment.html
deploy:
type: git
repo: https://github.com/wssgcg1213/wssgcg1213.github.io.git

generate and 发布:

1
hexo g && hexo deploy

访问http://wssgcg1213.github.io

迁移ghost

访问ghost后台里的lab: export.

得到一个json文件

安装

1
npm i hexo-migrator-ghost --save

导入

导入之前需要修改 ./scaffolds/post.md 的模板内容为

1
2
3
4
title: {{ title }}
date: {{ date }}
tags: {{ tags }}
---

否则会报错

1
2
hexo migrate ghost source.json
hexo clean && hexo g && hexo deploy

绑定域名+https

github.io可以绑定cname记录, 但是这样无法使用https, 于是选择使用自己的VPS进行反代.

nginx配置如下, 反代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 443 ssl;
server_name blog.zeroling.com;

ssl on;
ssl_certificate ssl/all.zeroling.com.crt;
ssl_certificate_key ssl/all.zeroling.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers CHACHA20:GCM:ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!DH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
ssl_prefer_server_ciphers on;
location ~ {
proxy_pass http://wssgcg1213.github.io;
}
}

访问: https://blog.zeroling.com/

完事, 创建新文章的方法是hexo new "new post title", 更多命令可以直接输hero查看.

为了方便, 可以在package.json添加

1
2
3
"scripts": {
"deploy": "hexo clean && hexo g && hexo deploy"
}

然后就可以直接使用npm run deploy来一键发布了.

2015年的年终总结

cover-image

是的,总要怎样有的没的为过去的一年做个纪念,证明好好地过了这一年而不是REP 365

谈起2003年或者200几年,感觉还停留在「哦那是几年前而已嘛」,然而仔细一算,喔那已经是十几年前的事情了。没想到自己也会过来感慨时间,真是没想到。大学生活也过去一大半了,曾经想做的还有不想做的也大都通通都做了,要是仔细想想还真是带点成就感。

说起来这一年对我来说最大的事情就是,确定了自己这几年的大方向。我一直说,最远只能盘算到未来三年,现在看来三年都有点远,三年前我还在准备高考吧,能想到现在就怪了。但是事情总是隐隐约约的串起来的,不可否认高中的折腾经历为自己现在的努力方向做了很多铺垫。

三月份出于试试+跟风的心态投了不少简历,也许没几个大二的会在这个时候去投简历吧,对我一直想做个「与众不同」的人,当然那个时候是抱着纯玩的态度的,也算是能确定自己的水平定位吧。其实我还是挺相信无心插柳柳成荫的故事的,得到不少公司的回应也是喜出望外。

我其实很难做选择,作为一个天秤的性格一直是这样,但是在关键事件上总能做不后悔的选择大概也是人品问题吧~

选择阿里巴巴不仅仅是因为它的名气,当然还有地理位置(回家哈哈哈)的关系,我相信自己在大公司会有一个很快的进步,不管是技术方面还是其他方面,开拓视野很重要。

两个月的实习说短也不短,也许是自己太要强感觉没把关系搞得Perfect,但是至少认识了很多很nice的同事,很多很铁的朋友,更重要的是获得了很多经验,这种东西靠BB靠看书是得不到的,实践得真知,这也是新人跟老鸟的最大区别了。

前端是个新兴职业,当然我不会在这上面吊死。坦诚的讲,我觉得不能画一个框框把自己限制起来。我觉得我一直以来的理想是做别人做不到的事,后端也好前端也好,跳出框,跳出心理舒适区很重要。

现实的讲,程序员(开发者)工资高是事实,加班严重是事实。如果说一个普通本科毕业的应届生正常毕业工资是5、6K的话,一线城市程序员的工资能普遍达到14、15K。理智地想想,投入跟付出应该是正相关才对。自认为做一个普通的程序员很容易,做一个能被普通程序员称为「大神」的程序员就太少了。我一直在追随一些「大神」,研究他们的成果,之所以他们成为「大神」是因为他们能在别人守着套路用jQuery的时候想出双向绑定,想出组件化的架构方式等等等等,对就是「与众不同」又「很有道理,解决问题」。你想过三年之后自己会成为大神吗?没有,那很好,成了一半。

学习能力会是很重要的一点。公司给你开的工资,很大一部分是看中学习能力。应届生,啥都不会,凭什么开1W+一个月给你免费吃喝,当然是为了等你牛逼了能不忘根。很庆幸至少在这方面我觉得还是不认输的,不过什么时候能治了这懒癌也算是谢天谢地。年初的时候就说的看angular,看react。到了九月份,才真正的认真学了,然后这一年里ng,RN的井喷也算是自己的一个笑话了。

ShenJS,渝JS,大会参加了一坨,真的值回那票价吗。自己还是得做个反思。不是为了对什么的狂热,不是为了凑热闹。是为了什么时候能自己站在上面分享自己有多牛逼。在这之前,先得把业内研究的东西360°看个透吧。很遗憾自己应该是还没到那个程度,但是怂什么,就是搞。

团队,其实我还是不喜欢带头吆喝吧,做一个头头还真是个烦心事。Web这伙人这一年我还是没能带好,至少是像自己希望的那样。也许是方式方法不对,正常逻辑就是长江后浪推前浪才对是吧,该放开手让他们做的。

言而总之,开心就好。

加油!新年快乐

2015年12月28日

使用C++模块为Nodejs添彩助力

cover-image

前言

了解node的开发者清楚, node不是一门语言, 而是一个平台. 多亏了libuv屏蔽了操作系统层面的差异, 优秀的js语言特性(有些人不以为然, 不评论)能让node做很多事情. 我们知道node擅长的部分是异步IO, 这里还是要感谢libuv, 但是不擅长的是CPU密集型操作, 这作为解释型脚本语言的弱项, 静态语言则反之表现出色.

Node的C/C++模块

在朴老师的深浅node中指出, node with c++ module的fab数列计算数列与c语言不相上下, 当然C/C++作为node这一平台的补充是完全没有问题的, 但是这里朴老师明显是有误导读者的嫌疑(“感觉”node的计算速度比得上c). C/C++模块的另一大用处是可以获得系统的完全操作权限, 使用C的第三方lib, 完成js不能完成的任务, 例如线程层面的Sleep, 以及扩展node支持不好的crypto模块等等. 但是使用C/C++模块的时候, 要认识到我们其实是绕开了js/libuv提供的一些便利, 所以在开发的时候, 需要特别注意平台兼容性, 内存管理等等.

准备

之前给腾讯的微校开发CET无准考证查询功能, 由于api使用了加密手段, 导致调用起来比较麻烦, 得知其加密手法为CFB模式下64位的DES, 稍微查了一下node手册的crypto模块, 没有发现node对这个方法的支持, 而且考虑到js对加解密计算的弱项, 便打算借助C/C++模块配合openssl实现. 我们使用node-gyp工具进行模块的交叉编译, 由于nodejs4.0以上使用了新的C++ Compiler11标准, 所以需要更新到gcc >=4.8才能对第三方C/C++模块进行编译, centos安装devtoolset3, ubuntu使用ppa源升级, 我在上一篇文章提到了如何升级.

NAN模块

由于node各个版本使用的V8版本差异, 所以编写C/C++模块的时候语法差异比较大, 这里我们使用nan这个包抹平这些差异, nan提供了一个包含很多抹平差异宏定义实现的nan.h文件, 所以我们只要了解NAN这一套就可以了.

1
npm i nan --save

然后新建一个binding.gyp文件.

1
2
3
4
5
6
7
8
9
10
11
{
"targets": [
{
"target_name": "cetdecoder-main",
"sources": [ "cetdecoder-main.cc" ],
"include_dirs": [
"<!(node -e \"require('nan')\")"
]
}

]
}

C/C++

先创建一个cc文件, 来看看里面的内容

cet.cc

这里添加了几个函数, 它的参数类型是

Nan::FunctionCallbackInfo& info```, 然后Init方法里的`exports`方法把这两个函数以"decodeTicket"和"encodeRequest"作为方法名暴露给node.
1

这里可以看到, 从`char*`建立一个v8中String类型对象的方法是: `Nan::New("string").ToLocalChecked()`, 相同的初始化函数是`Nan::New<v8::FunctionTemplate>(func)->GetFunction()`.  

最后的`NODE_MODULE`宏完成整个对象的暴露, 这一句与`Init`方法相当于node中的

``` javascript
module.exports = {
  foo: bar
}

再来看具体方法内的操作方法, 这里我们要关心的是如何将js中也就是V8的数据类型转化成c/c++的数据类型.

func

这个函数的需求是传入一个Buffer, 对Buffer中的二进制数据进行位解码操作后返回对应的Buffer.

这里比较惭愧, 我翻了手册好几遍都没找到如何转化Buffer对象的方法(粗粗看了一下, doc的位置在node_modules/nan/doc), 为了方便, 我这里就传入一个数组, 例如[0x41, 0x6d, 0x44, ...], 然后返回另一个数组.

当然我也没有找到如何转化数组的方法, 但是我找到了一个args.Length()的方法, 于是借助js的apply, 再在C中使用一个循环就ok了. 这里具体的获取某一个参数方法为info[i]->NumberValue(), 查V8手册可知返回值是一个double类型, 这里我们根据需要转化成char类型的一个数组.

接下来是返回的数组的创建.

1
2
3
4
5
v8::Local<v8::Array> retArr = Nan::New<v8::Array>(len);
for (i = 0; i < len; i++) {
Nan::Set(retArr, i, Nan::New(ret[i]));
}
info.GetReturnValue().Set(retArr);

编译

1
node-gyp configure
node-gyp build

也可以使用一句话build

1
node-gyp configure build

生成的.node文件位于./build/Release, 可在node中直接require

可以在package.json中加入"gypfile": true让其自动编译

需要注意的地方

其实这里我并没有使用NAN的example, nan的标准创建函数方法是使用NAN_METHOD宏.我建议参照NAN官方写法为了升级方便.

后记

因为做的比较急, 对V8的了解还不够深刻, 我甚至没有C++基础(只有很少的C), 例如Scope等概念还不是很清楚. 所以C/C++模块的开发对大部分前端工程师来说, 还真是一个技术活.

这里是我的一个粗浅记录, 如果有什么不恰当的欢迎指出.

发表于我的博客Zero’s Corner.