ubuntu初始化并搭建Shadowsocks攻略

之前在用的VPS上周末到期了,于是继续买了个digital ocean(以下简称DO)的乞丐版。简单介绍下DO,DO是VPS供应商界的后起之秀,在这之前,linode一直处理霸主地位,死贵死贵的。但DO可以按小时计费,相当于月费除以30天,一点没抬价。这对于只想试验某个功能的人来说,简直是福利,试验完了,把VPS删了就不再计费了。不过我这拿来当梯子其实是有点浪费的囧,后续考虑换回搬瓦工~
对了,搬瓦工可以一键安装shadowsocks和openVPN,不过咱还是热衷于折腾不是~

好了,进入正题。
由于这是我第四个VPS了,每次初始化一个ubuntu并搭建梯子服务,总要花点时间找命令,想想还是整理一下比较好,方便下次使用。
刚刚建立VPS后,root用户ssh登录,然后开始命令行之旅~
注:本攻略需具备一丢丢vi操作基础- -

初始化ubuntu

1. apt-get是ubuntu的包管理工具,第一步当然是更新镜像:

1
apt-get update

2. 设置locale, 此时执行:

1
locale

会有两个警告:

1
2
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory

先安装一个工具包:

1
apt-get -y install language-pack-zh-hans

然后再检查一下:

1
locale

就没有警告了

3. 通常linux不使用root用户进行日常操作,以免权限太高,导致一些不可逆的误操作,所以新建一个相对低权限的用户, 以stone为例:

1
adduser stone

然后按照提示,一步步填写信息
注:以下提到的stone用户,你要需要替换为自己的用户名~

4. 给刚新建的用户设置权限,否则无法使用sudo, 用vi编辑权限sudoer文件:

1
sudo vi /etc/sudoers

找到 root ALL=(ALL:ALL) ALL
在下面添加一行:stone ALL=(ALL) ALL
保存,这样stone这个用户就可以sudo了

5. 切换到新用户:

1
su stone

6. 安装git和zsh:

1
sudo apt-get -y install git zsh

7. zsh是最好用的shell,通过安装oh-my-zsh来配置zsh:

1
sudo sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

这里可能curl命令会不存在,需要安装一下:

1
sudo apt-get install curl

然后,再继续安装oh-my-zsh.
执行完毕后,如果你发现一个大大的logo:

1
2
3
4
5
6
__ __
____ / /_ ____ ___ __ __ ____ _____/ /_
/ __ \/ __ \ / __ `__ \/ / / / /_ / / ___/ __ \
/ /_/ / / / / / / / / / / /_/ / / /_(__ ) / / /
\____/_/ /_/ /_/ /_/ /_/\__, / /___/____/_/ /_/
/____/ ....is now installed!

同时,命令行提示符变成一个右箭头和一条波浪线了,就说明安装成功了!

8. 设置zsh为stone用户的默认shell:

这里最好先看一下zsh在哪里:

1
which zsh

如果得到的是/usr/bin/zsh, 那么接下来就执行 chsh -s /usr/bin/zsh
如果得到的是/bin/zsh, 那么接下来就执行 chsh -s /bin/zsh
这里我也奇怪,之前一直用池建强老师给出的chsh -s /bin/zsh都没问题的,后来在搬瓦工的ubuntu14.04上居然变了

9. 设置stone用户免密登陆,创建.ssh/authorized_keys 文件并编辑:

1
mkdir ~/.ssh && vi ~/.ssh/authorized_keys

把你本机的公钥粘贴进去,保存退出。
本地 重新使用ssh登录:

1
ssh stone@<你的VP IP>

如果不需要密码直接登录进去,就说明成功了!
ps: 本机 生成秘钥命令: ssh-keygen -t rsa -C "<your_email@youremail.com>" 一路回车,然后本机通过cat .ssh/id_rsa.pub 查看公钥。

10. 创建远程主机别名,以快速登录, 在 本机 创建文件并编辑:

1
vi .ssh/config

写入:

1
2
3
Host do
Hostname xx.xx.xx.xx
User stone

注: Host字段的值,就是个别名,可以自定义奥
保存,本地 重新使用ssh登录:

1
ssh do

如果不需要密码,自动登录进去,就说明免密快捷登录成功了~

以上,按照我的初始化服务器惯例,创建了新用户,安装了git,zsh, 创建了免密快捷登录,至此初始化ubuntu完毕

安装shadowsocks

1. 安装shadowsocks服务端

1
sudo apt-get install -y python-pip && sudo pip install shadowsocks

2. 创建shadow socks配置文件:

1
sudo vi /etc/shadowsocks.json

写入:

1
2
3
4
5
6
7
8
9
10
{
"server":"<你的VPS IP>",
"server_port": <自定义shadowsocks服务端口>,
"local_address": "127.0.0.1",
"local_port":1080,
"password":"<自定义密码>",
"timeout":300,
"method":"aes-256-cfb",
"fast_open": false
}

3. 启动shadowsocks:

1
sudo ssserver -c /etc/shadowsocks.json -d start

打开你的shadowsocks客户端,配置上相应的ip,端口和密码,就可以出墙啦~~~

打造高效前端mac工作环境

打造高效的Mac工作环境

Mac简直是为程序员量身打造的开发利器,华丽丽的外观以及内置的一系列开发工具与编程语言,最重要的是,OS X基于unix系统,命令行与GUI的完美结合体.但是Mac仍然需要经过geek们的不断”折腾”才会变得更加得心应手,于是就有了这篇文章,欢迎每个读者不断补充内容!

本文参考https://github.com/macdao/ocds-guide-to-setting-up-mac/blob/master/README.md#spotlight-%E5%BF%AB%E6%8D%B7%E9%94%AE
感谢飞哥分享

一.触控板篇

设置单击为轻点

默认情况下按下触摸板才是单击,设置单击为轻点:
系统偏好设置->触控板->光标与点按:勾选『轻点来点按』

双指滚屏

双指滚屏比起鼠标,那是爽快的不是一点点。但你可能不知道的是,双指滚屏支持横向滚屏!当你双指在触控板上移动时,好比在触屏手机上,用一个手指在在屏幕上移动,360度随意滚动页面,快试试吧~

设置三指拖动

使用三指一起在触控板上移动即为拖动效果:
系统偏好设置->辅助功能->鼠标与触控板->触控板选项->勾选『启用拖移』->选择『三指拖移』。
用于拖动窗口或选中文本非常方便!

查看当前工作空间所有子窗口

四指上划,感受一下华丽丽的动画。。。

四指切换工作空间

四指水平滑动,全屏切换桌面,装逼不错。

Force Touch

  • 点击chrome网页中的单词 ,可用于查看字典
  • 点击dock中的图标,可查看当前应用下的所有子窗口

更多。。。

二.快捷键篇

⌘ = Command
⌃ = Ctrl
⇧ = Shift
⎇ = option

通用

序号 快捷键 实用指数 描述
1 ⌘ + tab ★★★★★ 切换应用程序,类似win的alt + tab
2 ⌘ + ~ ★★★★★ 切换应用下的不同子窗口
3 ⌘ + H ★★ 隐藏应用程序
4 ⌘ + M ★★ 最小化应用程序子窗口
5 ⌘ + N ★★★★ 新建应用程序子窗口
6 ⌘ + O ★★★★ 打开文件
7 ⌘ + P ★★ 打印
8 ⌘ + W ★★★★★ 关闭子窗口
9 ⌘ + Q ★★★★★ 退出应用程序,finder不可退出
10 ⌘ + 空格 ★★★★★ 切换输入法

文本

序号 快捷键 实用指数 描述
1 ⌘ + C ★★★★★ 复制
2 ⌘ + V ★★★★★ 粘贴
3 ⌘ + X ★★★★★ 剪切
4 ⌘ + S ★★★★★ 保存
5 option + → ★★★★★ 跳至下一个单词
6 option + ← ★★★★★ 跳至上一个单词
7 ⌘ + → ★★★★★ 跳至行末
8 ⌘ + ← ★★★★★ 跳至行首
9 ⌘ + fn + ← ★★★ 跳至文件首字符
10 ⌘ + fn + → ★★★ 跳至文件末字符
11 ⇧ + 以上5-10 ★★★★ 区域选择文本
12 ⎇ + delete ★★★★ 删除光标前一个单词
13 ⌘ + delete ★★★★ 删除光标到行首的内容

截图

⌘ + ⌃ + A QQ截图可满足大部分需求

Finder

Finder是OS X的资源管理器,为常驻程序

序号 快捷键 实用指数 描述
1 空格 ★★★★★ 快速预览文件内容
2 ⌘ + A ★★★★ 全选当前目录下的文件or目录
3 ⌘ + I ★★ 显示简介
4 ⌘ + N ★★★★ 新建文件夹
5 ⌘ + C ★★★★★ 复制
6 ⌘ + V ★★★★★ 粘贴(需先复制)
7 ⌘ + ⎇ + V ★★★★★ 移动文件(需先复制)
8 ⌘ + delete ★★★★★ 移动到废纸篓,如果在废纸篓中,则是放回原处
9 ⌘ + ⇧ + delete ★★★★★ 清空废纸篓
10 方向键 ★★★★ 切换选中的文件or目录,切换方式视具体视图类型而定

Chrome

Chrome是我们使用最多的浏览器,掌握它的快捷键能使工作效率大大提高。

序号 快捷键 实用指数 描述
1 ⌘ + T ★★★★★ 新建tab页
2 ⌘ + W ★★★★★ 关闭tab页
3 ⌘ + R ★★★★★ 刷新
4 ⌘ + ⇧ + R ★★★ 强制刷新
5 ⌘ + ⎇ + → ★★★★★ 向右切换tab页
6 ⌘ + ⎇ + → ★★★★★ 向右切换tab页
7 ⌘ + ⇧ + T ★★★★ 恢复刚刚关闭的tab页
8 ⌘ + ⇧ + N ★★★★ 新建隐身窗口
9 ⌘ + L ★★★★★ 聚焦地址栏
10 ⌘ + D ★★★★★ 添加当前页面至收藏夹
11 ⌘ + ⇧ + U ★★★★★ 查看页面源代码
12 ⌘ + ← ★★★ 后退(触摸板手势同样可实现)
13 ⌘ + → ★★★ 前进(触摸板手势同样可实现)
14 ⌘ + ⇧ + I ★★★★★ 开发者工具
15 ⌘ + ⇧ + J ★★★★★ javascript控制台
16 ⌘ + ⇧ + C ★★★★★ 抓取元素
17 ⌘ + ⇧ + M ★★★ (聚焦开发者工具)切换移动端模式
18 ⌘ + [ ★★ (聚焦开发者工具)向左切换工具栏
19 ⌘ + ] ★★ (聚焦开发者工具)向右切换工具栏
20 Esc ★★★★ (聚焦开发者工具)切换底部工具栏,尤其是全局搜索
21 ⌘ + = ★★★★ 放大页面
22 ⌘ + - ★★★★ 缩小页面

三.工具篇

命令行类

1. homebrew

实用指数:★★★★★
http://brew.sh/
命令行软件包管理器,自动管理依赖,mac必备工具
一行命令安装命令行软件,比如:

1
brew install nodejs

2. brew-cask

实用指数:★★★★★
https://caskroom.github.io/
brew-cask是brew的插件,用于管理GUI软件,一行命令安装GUI软件,比如:

1
brew cask install qq

省去搜索-下载-打开-拖动的繁琐过程
缺点是,下载速度可能会慢,有些软件的版本跟不上官方下载

3.oh-my-zsh

实用指数:★★★★★
https://github.com/robbyrussell/oh-my-zsh
http://macshuo.com/?p=676
zsh本身比bash等shell优秀,但是难于配置,所以就有大神开发了oh-my-zsh这么个工具,实现简单完成zsh的配置。有了它,我们就可以驰骋在彩色的世界里,主题随心换,命令行插件(比如git,sudo,npm)多的不要不要的~

4.VIM

实用指数:★★★★★
管理Linux服务器必备编辑器,不必多说
可通过brew安装

5.Vundle

实用指数:★★★★★
https://github.com/VundleVim/Vundle.vim
VIM插件包管理工具

6.wget

实用指数:★★★★
命令行下的下载工具,mac居然没有自带这个工具,很奇怪,不过用的也不多
可通过brew安装

7.tree

实用指数:★★★
通过制表符的形式展示目录结构,有时候写文档蛮有用
可通过brew安装

8.tldr

实用指数:★★★
https://www.npmjs.com/package/tldr
有时候不记得一个命令的用法,但又不想看又长又啰嗦的manpage,可以使用这个命令查看
可通过npm安装

9.nginx

实用指数:★★★★★
http://nginx.org/
这可能不算工具,但绝对是web世界中的好软件,不管前后端,都应该好好学习它!

10.autojump

实用指数:★★★★★
https://github.com/wting/autojump
快速cd到常用目录,可通过brew安装

GUI类

0.alfred

实用指数:★★★★★★★★★★
这款首推,以至于序号都得是0才行,实用指数爆表!!!
它是mac上提升效率的神器,可以是一切的入口,比如打开软件,搜索文件,执行命令,粘贴板历史。更叼炸天的是它的workflow,这通常来自第三方开发者,当然你也可以自己手动开发workflow来定制属于自己的workflow,可以去 这里 挑选适合自己的workflow。
强烈推荐购买
可通过brew cask安装

1.appcleaner

实用指数:★★★★★
有的软件可能会在电脑的很多目录下都创建文件,导致卸载不干净,通过它可以帮我们找出想卸载软件涉及到的所有文件,有洁癖同学的利器。
可通过brew cask安装

2.bbedit

实用指数:★★★
一个轻量级的文本编辑器
可通过brew cask安装

3.beyond-compare

实用指数:★★★
一个比较工具,win上很火,但收费很贵,个人认为webstorm自带的比较工具也不错
可通过brew cask安装

4.charles

实用指数:★★★★★
一款优秀的抓包工具,收费比较贵,一直没舍得买,试用版每半个小时会退出一次
可通过brew cask安装

5.cheatsheet

实用指数:★★★★
长按⌘即可查看当前应用的所有快捷键
可通过brew cask安装

6.cyberduck

实用指数:★★★
与linux服务器,传输文件,比较直观
可通过brew cask安装

7.daisydisk

实用指数:★★★
收费,可试用,分析你的mac的磁盘情况,比较详细,偶尔用用也可以
可通过brew cask安装

8.dash

实用指数:★★★★
收费,可试用,开源技术文档本地化工具,与alfred结合很好用
可通过brew cask安装

9.evernote

实用指数:★★★★★
高级功能收费,记笔记的利器,多端同步
可通过brew cask安装

10.filezilla

实用指数:★★★★★
ftp工具,蛮好用
可通过brew cask安装

11.firefox

实用指数:★★★★★
就是火狐浏览器啦,有的人喜欢
可通过brew cask安装

12.foxmail

实用指数:★★★★★
对QQ邮箱支持比较友好,几乎免配置
可通过brew cask安装

13.ghostlab

实用指数:★★★★★
收费,可试用7天,移动端多设备同步测试很叼
可通过brew cask安装

14.haroopad

实用指数:★★★★
一款比较好的markdown编辑器
可通过brew cask安装

15.hosts

实用指数:★★★★
用于方便的修改hosts文件
可通过brew cask安装

15.istat-menus

实用指数:★★★★★
实时监测你的mac情况,比如温度,cpu,内存,ip等
可通过brew cask安装

16.iterm2

实用指数:★★★★★
加强版终端,每天都在用啊,尤其喜欢它的全局调用方式
可通过brew cask安装

17.macdown

实用指数:★★★★
也是一款不错的markdown编辑器
可通过brew cask安装

18.macvim

实用指数:★★★★★
客户端VIM,编辑器之神
可通过brew cask安装

19.manico

实用指数:★★★★
通过功能键+数字快捷切换常用程序
可通过brew cask安装

20.mindnode-pro

实用指数:★★★★
用于画导图,用的比较少
可通过brew cask安装

21.mou

实用指数:★★★★
鼻祖级的markdown编辑器
可通过brew cask安装

22.qq

实用指数:★★★★★
不必多说,每天在用
可通过brew cask安装

23.scroll-reverser

实用指数:★★★★★
单独调整鼠标和触控板的滚动方向,系统自带的只能两者同时调整
可通过brew cask安装

24.shadowsocksx

实用指数:★★★★★
shadowsocks客户端,轻量级的梯子,每天在用啦
可通过brew cask安装

25.sizeup

实用指数:★★★★★
快速调整窗口大小,位置,外接显示器时,更加好用!
可通过brew cask安装

26.vmware-fusion

实用指数:★★★★★
一款强大的虚拟机软件
可通过brew cask安装

27.xtrafinder

实用指数:★★★★★
增强Finder的功能,例如剪切文件,新建文件,复制文件路径
可通过brew cask安装

28.photoshop

实用指数:★★★★★
前端必备

27.office 2016

实用指数:★★★★★
办公必备

28.google-chrome

实用指数:★★★★★
前端必备
可通过brew cask安装

29.RAR Export

实用指数:★★★★★
优秀加解压软件,兼容rar,zip等格式

30.Teamviewer

实用指数:★★★★★
优秀远程桌面软件

31.webstorm

实用指数:★★★★★
前端开发神器,个人偏爱

32.微信web开发者工具

实用指数:★★★★
用于调试微信一些接口,还可以

33.sublime text 3

实用指数:★★★★
号称最优雅的编辑器

34.sourceTree

实用指数:★★★★★
git的GUI应用,非常直观

35.zeplin

实用指数:★★★★★
读取sketch设计文件中的标注

Chrome插件

一键管理所有扩展

实用指数:★★★★
你没看错,它就是这个中文名,作用如其名!

Vimium

实用指数:★★★★
有了它你几乎可以实现全键盘上网!

HTML5高清二维码生成器

实用指数:★★★★★
对于移动端开发,还是很方便的

有道词典

实用指数:★★★★★
在网页上划词翻译,很好用

Chrono下载管理器

实用指数:★★★★★
下载管理,好用

Google文档、表格及幻灯片的Office编辑扩展程序

实用指数:★★★★★
google doc必备

JSONView

实用指数:★★★★★
美化json格式数据

LastPass

实用指数:★★★★★
管理表单密码

AngularJS Batarang

实用指数:★★★★★
调试angularjs应用必备

React Developer Tools

实用指数:★★★★★
调试reactjs应用必备

Vue.js devtools

实用指数:★★★★★
调试vuejs应用必备

前后端分离实践

早几个礼拜前,就想写这篇文章了,昨天刚刚找到一个画图的好工具https://www.draw.io(请自备梯子),今天顺势把这篇文章补了。

在遇到前端MV*框架以前,前后端分离几乎无从做起,前端仔严重依赖后端,即页面大都是服务端渲染。有时候前端们不得不去写一写后端模板代码,也因此前端代码经常被后端『侵犯』,而且模板文件冲突时有发生。前端MV*框架诞生后,至少在开发阶段前端攻城狮们可以从后端的『魔爪』里解脱出来。这里的处理方式有多种(引入线上node服务的情况暂不讨论),我实践过/即将实践的大致有这么几种:

  1. 前端代码和后端代码可以在同一个版本仓库,前端开发时本地启动后端服务,把前端代码所在目录设置为静态资源根目录,然后直接访问入口html。当然,可以把入口文件也经过后端模板输出,但是静态资源构建时就有点麻烦了。
    此方案有个很大的弊端,为了启动后端服务,本地还要搭建后端服务环境,而且万一哪个后端大神提交了影响服务的代码,前端一拉代码,就只能停滞开发了

  2. 将上述方案迁移到某台测试服务器上,本地不启动任何服务,只需一个ftp实时上传工具,可实时检测到文件内容变更,立即通过ftp上传至服务器。
    此方案对本地环境要求低了不少,但是不适合多人协作,如果每个前端都单独使用一台服务器,成本也不低(即使是虚拟机也不例外)。

  3. 前端本地启动node服务,数据请求通过node代理到后端服务。
    此方案大大降低了对后端服务的依赖,如果后端HostA不可用,就换到HostB,灵活性非常高;而且此方案构建自由度也大大提高,并且可利用gulp+browser-sync或webpack之类的工具实现watch工作流。另外,此方案前端代码不一定要和后端代码在同一版本库管理,进一步脱离后端,如果线上并未分离部署,可在部署时,将前端代码同步给后端。

  4. 算是方案3的一个变种,本地还是启动node服务,去掉方案3中的代理中间件,再另外启动一个nginx反向代理,访问nginx服务,由nginx来区分动态/静态请求,静态请求转发到本地node服务,动态请求则类似方案3转发到指定的后端。
    此方案使得本地node服务更纯粹,切更接近线上前后端分离的部署架构,还能顺便学习一下nginx!

我们线上的前后端分离架构是这样的:
front-back-seperating.png
短期内这个方式应该不会变,目前我们正在探索线上node应该怎么玩。目前线上流量还不够大,后期会把静态资源迁移至CDN。

开发阶段,每个前端开发环境是这样的,即方案3:
frontend-dev.png

接下去打算改造成方案4:
frontend-dev-next.png

前后端分离是十分有意义的,一来使前后端各司其职,提高了开发效率;二来使得前端的角色更加重要。待到Node在生产环境发挥大展身手时,前端就真的不只是前端了.

再见wordpress

wordpress-drop
今天早上收到wordpress虚拟空间提供商发来的短信,说服务已关停,心里却是还有那么点舍不得。
然而,一个多礼拜前我就意识到wordpress虚拟空间快到期了,上周末纠结了已上午后,终于决定转战Hexo,并且完成了本地环境搭建与博客初步迁移。
Wordpress作为开源博客的老大哥,但现今已经变得臃肿不堪,变的越来越难以维护,性能也不好。Hexo基于Nodejs,简单快速,非常适合前端攻城狮,而且可以免费部署在github上,速度也不错。
这次迁移遇到了几个问题:

  1. wordpress后台无法快速迁移图片资源,只能导出一份包含所有文章,分类,标签的xml,结果是,文章是迁移过来了,但是图片还是引用原来wordpress服务器上的图片,如果wordpress服务关停,新服务器上的文章图片将无法加载
  2. 迁移后的文章标题居然是类似于28-e4-b8-89-e4-b8-aacss3-e8-b6-a3-e7-8e-a9-e5-b0-8f-e8-af-95.md这样的,简直没法维护!
  3. 地址栏中的文章标题依然是16进制的形式
  4. 代码高亮格式需要重新整理

对于问题1:
google一番后,一个国外的geeker,用了一个比较hack的方式实现图片迁移:
1)把上文提到的xml后缀改为html
2)用chrome/firefox打开这个html,将这张网页另存为本地文件,然后所有的图片就一次性保存了下来
3)将所有图片复制到Hexo目录的source/images下
4)把文章中的图片地址批量替换为新的相对地址

折腾了小半个下午,总算是搞定了图片问题。

对于问题2:
一位国内的哥们也遇到了同样的问题,最后通过一段shell脚本完成了重命名。果断学习之,我这边还有日期需要处理,研究了一晚上shell,终于完成了markdwon文件的重命名(虽然不多,但也有60来篇)。

对于问题3:
起初以为是和问题2是同一个问题,谁知解决了问题2,这个问题还是存在。考虑从到就要到24点了,想在今天结束前,写下新博客的第一篇文章。这个问题明天找时间处理。

引用一下阮一峰老师的话:
喜欢写博客的人,会经历三个阶段:

第一阶段,刚接触Blog,觉得很新鲜,试着选择一个免费空间来写。

第二阶段,发现免费空间限制太多,就自己购买域名和空间,搭建独立博客。

第三阶段,觉得独立博客的管理太麻烦,最好在保留控制权的前提下,让别人来管,自己只负责写文章。

我自认算不上『喜欢』写博客,但也折折腾腾,踏上了第三阶段。
纠结期间,还发现了Farbox这个国产的优秀博客平台,考虑到自己是技术人员,还是折腾一下的比较好,对于非技术人员或懒得折腾的,强烈推荐Farbox。

而wordpress,已经无力维护,太过庞大。Hexo + Github小清新,很轻量,很自然。

Wordpress,再见!
Hexo,重新上路!

wordpress-to-hexo

–update
地址栏里的中文问题,第二天一看,居然好了,可能昨天检查的时候有缓存吧- - 看来这个问题应该如我之前所料,和文件问题是关联的。

再见2015

2015年将要过去,此博客也维护了近10个月,近来工作比较忙,回家后还要分给小公举一部分时间,已经无法像从前一样回家后有大把时间研究技术。

最近几篇文章,质量已经有所下降,几乎只能挤出时间去玩弄点新技术,而无暇去写文章了,似乎也只是借口。

react也断断续续研究了有个把月了,虽然没有在正式项目中使用,但在个人把玩中也略微能体验到其独到精髓之处。今晚加入了immutable之后(https://github.com/stoneChen/myReact),打算对react的研究,告一段落。

原本打算在公司内大力推react,但苦于公司前端整体水平欠佳,大部分人比较难上手,此想法也被扼杀在摇篮中。但是,却发生了一件『无心插柳』的事情。早前也偶尔听说过vueJS,仅有的印象便是小清新,支持双向绑定。大概不到1个月前,公司来了个新项目,正纠结技术选型,突然想起了vueJS,就建议一个蛮有实力的小伙伴去尝试一下。经过一个礼拜的探索,竟也毫不费力的搭建出了一个前端架构出来,然后几个初级前端也加入进来,几天下来,也能勉强上手了!vueJS还有一点对国人比较友好的是,作者是一名华侨(尤大),官网有中文版的!这让很多英文不好的同学,也能尽快学习入门~

vueJS轻量,支持双向绑定,社区也不算冷,很多大牛们也蛮看好,预测在2016年会有大的增长趋势。接下来我也要加入vueJS的浪潮中~说了这么多,其实我还没敲过一行关于vueJS的代码囧,只是读过一些关于它的文章,和官网的一些文档,感觉还是很好上手的,尤其是用过angularJS的同学,就从2016的元旦开始!

虽说就要投入vueJS的怀抱了,不过react native也放下好久了,公司正好准备搞一款新的ios App,心里还是蛮痒痒的。

且行且看吧。

新的一年,怕是没有那么多时间可以写文章了,更是做不到每周一更了,这一篇就已经断更一次了。只能说,尽力而为吧,多攒点干货一起发,好过每周都是不痛不痒的文字。

再见2015!

忙里偷闲把玩webpack

这周各种通宵加班。。。有时候也只是处理等待状态,不久的将来工作上需要频繁的开发静态页面,于是想到搭建一个快速开发环境,于是想到了webpack这个神器。

之前也只是在研究react的时候,用了一下webpack,但也仅仅是入了门。这次有机会从零开始基于webpack搭建开发环境,等基本功能完毕后,又基于yeoman开发了一个非常非常简单的搭建上述开发环境的脚手架,项目地址: https://github.com/stoneChen/generator-xpage

也没有用到webpack太高级的功能,前端类库,无非就是jquery,lodash,fastclick.CSS预处理器选择了stylus,less用了很久了,有点审美疲劳囧,sass的node-sass安装太慢太慢。。。gulp用于清理dist目录,其实有点大材小用哈,不过说不定以后会用它来做更多的事情呢。

然后今天下午开始基于 这个篇文章 提到的目录结构,重构之前的react demo,期间卡在reducers的import好久,后来终于纠结完毕后,最后无法忍受视图与reducer和action分离之苦,放弃,只是简单重命名了之前的某些目录并作微调。

angular中的$q小结

近日,公司小伙伴把angular的$q服务,运用的炉火纯青,登峰造极,遂对之做个小结。

名词解释:

resolveHandler:then方法的第一个参数

rejectHandler:then方法的第二个参数或catch方法的第一个参数(catch方法即为then(null, function)的简写)

先来个基本用法:

1
2
3
4
5
6
7
8
var p = $q(function (resolve, reject) {
setTimeout(function () {
resolve('success');
}, 100)
});
p.then(function (data) {
console.log('then1:', data);
});

结果会输出

1
then1:success

这应该很好理解。

然后再来一个:

1
2
3
4
5
6
7
8
9
10
11
12
13
var p = $q(function (resolve, reject) {
setTimeout(function () {
resolve('success');
}, 100)
});
p.then(function (data) {
console.log('then1:', data);
});
p.then(function (data) {
console.log('then2:', data);
});

结果会输出:

1
2
then1: success
then2: success

再看这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
var p = $q(function (resolve, reject) {
setTimeout(function () {
resolve('success');
}, 100)
});
p.then(function (data) {
console.log('then1:', data);
return 'haha'
})
.then(function (data) {
console.log('then2:', data);
});

结果却是:

1
2
then1: success
then2: haha

两者非常相似,结果却不一致,为什么呢?

前者属于『分发式』调用(我自己YY的),『分发』后的resolveHandler的入参是分发者的返回值,即

后者这种属于链式调用,后一个then的resolveHandler的入参就是上一个then的resolveHandler的返回值, 即

再看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var p = $q(function (resolve, reject) {
setTimeout(function () {
resolve('success');
}, 20)
});
p.then(function (data) {
console.log('then1:', data);
return 'haha'
})
.then(function (data) {
console.log('then2:', data);
return $q.resolve('xixi');
})
.then(function (data) {
console.log('then3:', data);
return $q(function (resolve, reject) {
setTimeout(function () {
resolve('success again')
},20)
})
})
.then(function (data) {
console.log('then4:', data);
})

输出结果为:

1
2
3
4
then1: success
then2: haha
then3: xixi
then4: success again

如果上一个then的resolveHandler返回的是一个promise对象,那么下一个then的resolveHandler的入参为这个promise对象resolve的值.

为了印证上述结论,再看一个更复杂的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var getPromise = function (resolveValue) {
return $q(function (resolve, reject) {
setTimeout(function () {
resolve(resolveValue);
},20)
})
};
getPromise('p1')
.then(function (data) {
console.log('then1:', data);
return 'haha'
})
.then(function (data) {
console.log('then2:', data);
return $q.resolve('xixi');
})
.then(function (data) {
console.log('then3:', data);
return getPromise('p2').then(function (data) {
console.log('then4:', data);
return getPromise('p3');
})
})
.then(function (data) {
console.log('then5:', data);
})

输出结果为:

1
2
3
4
5
then1: p1
then2: haha
then3: xixi
then4 p2
then5: p3

OK,上述都是resolve的情况,下面看看reject的情况。

来一个基本的:

1
2
3
4
5
6
7
8
9
10
$q(function (resolve, reject) {
setTimeout(function () {
reject('failed');
}, 20)
})
.then(function (data) {
console.log('success1:', data);
},function (data) {
console.log('fail1:', data);
});

结果输出:

1
fail1: failed

应该很好理解。

来看一个复杂的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$q(function (resolve, reject) {
setTimeout(function () {
reject('failed');
}, 20)
})
.then(function (data) {
console.log('success1:', data);
})
.then(function (data) {
console.log('success2:', data);
},function (data) {
console.log('fail2:', data);
return 'fffff';
})
.then(function (data) {
console.log('success3:', data);
return $q.reject('reject 3');
}, function (data) {
console.log('fail3:', data);
})
.then(function (data) {
console.log('success4:', data);
})
.catch(function (data) {
console.log(data);
});

输出结果为:

1
2
3
fail2: failed
success3: fffff
reject 3

promise被reject后,第一个rejectHandler将接受到reject的值,但是这个rejectHandler返回的值就此『迷途知返』,传给接下来的resolveHandler。如果返回的是将被reject的promise对象,被reject的值才会被传递给下一个rejectHandler。

 

总结

似乎讲的并不是那么清楚,请读者仔细推敲代码的运行结果,可以更加深刻理解$q的用法,用于处理复杂异步逻辑非常合适。本文没有涉及$q的所有API,而且promise规范也不仅仅只有一种,请读者自行延伸查阅。

内网web服务穿透微攻略

虽然这些天经常加班,但有时候加班处于待命状态,所以抽空研究了下内网穿透,即从外网访问内网web服务。

本来想想这种事情除了开VPN,似乎没有别的办法,直到前段时间一同事告诉我他通过ssh隧道实现了这个需求,并发给我一篇英文博客,当时只是随便瞄了几眼文章里的图,没有时间去看。于是后来断断续续的暗暗研究,由于英语不好,都是搜索中文文章,但看了好多篇文章,都是单单讲SSH,没有涉及到HTTP,没有说到我需求的关键点。直到最后,再回头看看前面那篇英文博客,一切都豁然开朗了!

那篇文章在这 https://chamibuddhika.wordpress.com/2012/03/21/ssh-tunnelling-explained/ (请自备梯子)

好了,下面开始进入正题。由于是『微攻略』,只涉及到操作的步骤,不讲具体原理。

看了好多篇文章,ssh隧道需要借助中间主机(外网需可访问)进行端口转发,而且分为本地转发和远程转发,我们这里需要的是远程转发。

核心命令,即在内网主机执行:

ssh -C -f -N -R *:{中间主机监听端口}:localhost:{内网主机监听端口}{中间主机用户名}@{中间主机} [-p {中间主机ssh端口}]

举个栗子,假设:

内网主机:192.168.100.101

中间主机:123.123.123.123(ssh端口为333,一般默认为22)

需要从外网访问内网主机的web服务端口:8080

希望中间主机监听的端口:2222

登陆主机的用户:root

那么在内网主机上需要执行的命令为:

1
ssh -C -f -N -R 2222:localhost:8080 root@123.123.123.123 -p 333

然后会提示输入中间主机的用户密码,输入完毕后,则建立ssh隧道完毕。

此时在中间主机执行:

1
curl localhost:2222

就可以看到打印出内网主机返回的http信息。

至此核心部分已经完成了,还剩下几个问题:

  1. 第三方主机(HTTP客户端)尚无法通过中间主机访问内网web服务
  2. 每次执行此命令还需要输入中间主机的用户密码
  3. 即使是守护进程中运行的,也会在一段时间后断开连接
    我们一个个解决:

1.需要开启中间主机的GatewayPorts:

通过vi /etc/ssh/sshd_config 文件,将 GatewayPorts 设置为 yes,保存退出vi。然后执行

1
/etc/init.d/sshd restart

这是centos的命令,其他linux版本可能有所不同
然后就可以在家里用自己电脑,访问内网的WEB服务了!比如在浏览器里打开http://123.123.123.123:2222/something就能看到内网的web页面了~

2.把内网主机的ssh公钥添加到中间主机的相应用户的~/.ssh/authorized_keys中,甚至可以设置中间主机别名

3.通过autossh(一个命令行工具),当隧道断开连接后,可自动重连,通过包管理工具安装好后,只需将上述命令的ssh替换为autossh即可,比如上面的例子,改为autossh就是:

1
autossh -C -f -N -R 2222:localhost:8080 root@123.123.123.123 -p 333

好了,接下来就可以愉快的玩耍了~