这是一篇很好的指导和学习React的介绍文章, 原文在这里.

react-howto

如果你是一个React的初学者(或者是前端的初学者)你可能会对React的生态系统感到疑惑.原因是因为以下.

  • 因为历史原因, React最初的目的是给有经验的开发者或者专家使用
  • React只会提供给facebook这种大型的项目使用, 并且facebook也是一直很好的使用React, 所以它不会专注解决“比facebook更小”的项目
  • 然后网络上到处充斥着各种React的劣质教程

这篇文章的阅读者适合有经验的web前端开发工程师

为什么要相信我

网上有成千上万的关于React的建议的文章; 为什么要相信我的建议?

因为我曾经是Facebook的React开源团队的其中一个成员, 我已离开Facebook并在一家创业公司任职, 所以我不会以facebook公司的员工名义和观点来评论和分享.

阅读全文 »

前言

前天看到有同事分享了一个照片分享的相册系统,看完之后,想起我之前也是因为团建旅游回来后写了一个基于node的相册和目录浏览的系统folder-gallery,不敢私藏,开源出来给大家。因为我之前写过一个基于nw的桌面版照片浏览应用 AlexGallery ,所依赖的一些库也是差不多,所以网络版写起来比比较快。

其实这个系统,我并没有写多少代码,估计也就100多行左右,都是使用开源的库搭起来的,所以简单的说,我其实不怎么写代码,我只是github的搬运工,再简单的说,呃,其实我是个搬砖的。

我觉得,一个高效多产的coder,不但要写得一手好代码,还得要搬得一手好砖。下面我会简单介绍一下搬砖的全过程。

阅读全文 »

关于Sails

Sails 是一个很优秀的node.js的web服务器框架,提供完整的web服务的解决方案,比如:

前不久写了一个小工具实现自定义我自己的.gitignore文件,因为在官方的.gitignore,我不明白为什么没有bower_components,因为很多node.js项目可能是会用到浏览器端的依赖。

所以我在自己的工具里面加上了bower_components和我的IDE webstorm自动生成的.idea

这样我每次新建node项目,我直接在项目文件夹里面命令行运行node-gitignore,就会自动生成我需要的.gitignore文件。

这个工具非常简单,用了tj大神的commander库,可以很方便写node的cli库,commander非常强大、简单、易用,我的这个工具就这么几行代码而已:

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
#!/usr/bin/env node

var program = require('commander');
var request = require('request');
var fs = require('fs');

program
.version('0.0.1')
.parse(process.argv);
var append = "# .idea\n.idea\n# Dependency directory\nbower_components";
var ws = fs.createWriteStream('.gitignore');
ws.on("finish", function(){
fs.appendFile(".gitignore", append, function (err, data) {
if(err){
console.log("error.");
}else {
console.log("done.");
}
});
});
request
.get('https://raw.githubusercontent.com/github/gitignore/master/Node.gitignore')
.on('error', function(err) {
console.log(err)
})
.pipe(ws);

使用方法

1
2
$ npm install node-gitignore -g
$ node-gitignore

或者你也可以定制自己的.gitignore文件,你可以fork然后修改代码后,发布到npm上,然后安装后就可以用。

android开发的同学,相信都遇到过在写代码的过程中,需要花费很多时间去做一些重复的劳动,比如下面这些:

  • activity和fragment创建后要写一大堆的findViewById来初始化各个view
  • 创建一个列表ListActivity的界面,我需要配套创建相关的一大堆文件包括:
    • activity、fragment、adapter、listener等class
    • activity layout、fragment layout、list item layout等layout
    • Model层相关的比如我们是用retrofit就包括:manager、service、request、response四个类文件
      如果上面这些文件一个个创建,累死之余build时候发现各种缺漏
  • 调试时候每次都要build一两分钟,上个洗手间回来,发现gradle任务还在运行中
  • 调试webview时候,只能chrome来模拟,调试好了,真机上又有问题
  • app的数据http请求调试各种繁琐,又加代理连到pc,又要开charles,手机又要连内网,手机的wifi代理经常要反复切换,坑爹的居然没有自动保存代理功能

上面这些提到的没有技术含量得“体力活”,可能会占据了我们开发不少的时间,一方面浪费时间、另一方面无法专心开发具体业务需求,我下面总结了一下消灭这些体力活的方法

阅读全文 »

screenshot1

关于AlexGallery

AlexGallery是一款图片浏览、预览、批量处理、编辑的开源图片桌面应用,它是基于node.js环境,使用nw封装,可以在mac、windows等系统使用。

因为自从我使用Mac后,发现没有一款工具或者软件可以快速浏览和预览图片,虽然系统自带图片预览工具也是可用,但是始终很不方便,我需要快速进入文件夹浏览图片的工具,也用过Google的Picasa,功能很多,但是也还是没有我需要的简单快速浏览方式,其他的比如acdsee又要收费

所以我决定自己做一个图片预览的工具,而且因为在这之前,我有留意到2个开源库,一个是轻量的图片处理node库lwip,另一个是nw,在做AlexGallery之前,我没用过这两个库做过任何东西,但是当我第一次看到lwip的介绍和例子后,我就有个自己写个图片处理工具的想法,两周之前工作忙完差不多就开始动工,因为用了不少开源前端web组件,所以做了一周左右功能基本都出来了

阅读全文 »

ngNode

ngNode是一个可以简单快速开发MEAN web应用的framework

特点

  • 实时的MEAN应用,通过配置生成web api,angularjs构建ui界面.
  • 通过简单的配置,简单快速创建web应用,除此之外不需要做其他事情
  • 自动生成相关功能,包括:mongodb ODM、CRUD api、数据显示datatable、排序、分页、搜索、编辑数据等
  • 内置User模块和passport.js验证模块
    阅读全文 »

关于分享

本文是关于单元测试的分享,单元测试是在项目开发里面某个模块对某个接口或者函数进行测试检查,在服务器端开发这是非常常见的,但是在web前端开发,特别是js开发中,是比较少见的,所以对于各位前端开发工程师,单元测试一件非常痛苦的事情,所以我打算在这里跟大家分享一下,我所了解到一些比较新的前端的测试框架。
本文所有的例子都可以在最后的example的github地址里面找到

阅读全文 »

这是我2年前写的blog,原文在这里

来自爆栈这里

首先有人抱怨这个:

“Like the old Albert Einstein said: “If you can’t explain it to a six-year old, you really don’t understand it yourself.”. Well, I tried to explain JavaScript closures to a 27-year old friend and completely failed.
How would you explain it to a 6-year old person that is strangely interested in that subject? ”

这位楼主大概意思是:

爱因斯坦说过:“如果你不能向一个六岁大的小孩解释清楚,那么你自己并不完全领悟”,好吧,当我向一个27岁的朋友尝试解释关于javascript中的闭包,尼玛他完全不懂。那还能如何指望一个六岁屁大的孩子能够听懂?

楼下一位非常有想象力的码农贴出了以下:

很久以前:

有一位公主…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function princess() {
// 她住在一个充满其妙冒险的世界。她遇到一个非常有魅力的王子,骑着一个独角兽,她还遇到巨型战龙,甚至还有会说话的动物等不可思议的事情。
var adventures = [];

function princeCharming() { /* ... */ }

var unicorn = { /* ... */ },
dragons = [ /* ... */ ],
squirrel = "Hello!";

// 但是,这个小公主每次都不得不返回到现实世界,变成一个普通人,还要面对各种无趣的大人们。
return {

// 她每一次回来,总会告诉这些大人,她所遇到各种非常令人惊讶的事情
story: function() {
return adventures[adventures.length - 1];
}
};
}

但是,大人们只是看到的是一个天真无邪的小女孩说…

1
2
3
var littleGirl = princess();
...这些只会发生在童话中的故事
littleGirl.story();

但是他们不会相信独角兽和龙,因为他们永远看不到这些怪兽。大人们觉得这些只是存在小女孩的想象中。
但是我们都知道,其实这些都是真实存在…

这是我2年前写的blog,原文在这里

来自爆栈这里

以下是原文回答精选

条件判断中的“===”操作符,相当于“==”操作符中没有类型转换的条件对比,并且类型必须是一样的。

“==”操作符在判断是否相等之前会进行类型转换,“===”操作符则不会做任何类型转换,所以如果两个值的类型不一样,那么===会返回false,所以当这种情况下===效率会更加快,并且返回的结果可能会和==不一样,如果类型一样的话,则性能也将会一样。

引用javascript大师Douglas Crockford的《JavaScript: The Good Parts》:

javascript中有两组相等判断的操作符:===、!==,和另外一个SB组合 ==、!=。如果两边的对象是相同的类型,并且是相同的值,那么===返回true,!==返回false,SB组合也是一样会返回同样的结果,但是如果他们不是一样的类型,那么会尝试强制转换类型,然后再进行比较,至于转换规则,是异常的复杂和坑爹。

下面有些有趣的例子:

1
2
3
4
5
6
7
8
9
10
11
12
'' == '0'           // false
0 == '' // true
0 == '0' // true

false == 'false' // false
false == '0' // true

false == undefined // false
false == null // false
null == undefined // true

' \t\r\n ' == 0 // true

我的建议是不再使用SB组合,而是要使用===和!==。以上的例子,将==替换成===都将会返回false。

关于性能的对比测试
回到主题,以下这个例子,我将原来的改了一下,测试这两种组合的效率,结果一定会使你和你的小伙伴们都惊呆了。