手把手教你从头搭建Web服务器及LEMP环境(使用Ubuntu16.04+Nginx+MySQL+PHP)

前言

拿到一台新装的Linux服务器,该如何配置成一台可以解析动态网页脚本的Web服务器呢? 相信这是很多人都会有的问题。本文将一步一步带你从头开始搭建给予LEMP技术栈的Web服务器,并使其可以正常运行PHP、Nodejs等语言。

所谓的LEMP技术栈,顾名思义其实就是Linux, Nginx, MySQL, PHP的组合。当然,如果喜欢,你也可以不用Nginx,而去选择Apache,这就是所谓的LAMP技术栈了。

本文使用Linux版本为Ubuntu 16.04 64位版本。

TL;DR.

Ubuntu服务器基本设置

使用root登录服务器

首先我们需要使用root用户登录服务器,当然你可以选择很多工具,诸如SecureCRT或者putty等。这里通过ssh命令行登录:

1
local$ ssh root@SERVER_IP_ADDRESS

前面的local$表示是在本地机器操作,在服务器端,该提示符会类似root@my-remote-server:~$这种形式,后边会看到。

新增超级用户权限用户

root用户虽然强大,但是正是由于太强大了,所以显得不够安全,因此通常情况下我们需要创建一个新的用户,然后给他设置超级用户(superuser)权限,这样就可以安全的进行各种操作了。

使用root用户登录,做如下操作:

1
2
root@my-remote-server:~$ adduser dennis
root@my-remote-server:~$ usermod -aG sudo dennis

这里就将新创建的用户加入了sudo用户组,就具有了超级用户的权限。更详细的信息可以参考这个教程

然后我们就可以以新创建的用户登录了:

1
2
root@my-remote-server:~# su - dennis
dennis@my-remote-server:~$

Nodejs大批量下载图片入坑指南(使用async和bagpipe处理大并发量请求)

前言

故事还得从头说起。乌云网挂掉之后,乌云知识库也无法访问了。曾经,在上面看到那么多优秀的安全类文章,一下子看不到了,颇觉得有点不适应。还好网上流传着民间的各种版本,于是我收集了一下,放在了Github上。这些文章只是一些html文件,并不包含页面上的图片。幸运的是,图片的域名static.wooyun.com还可以继续访问,因此有必要把这些图片也抓取下来。

Wooyun Drops 文章在线浏览

Wooyun Drops 文章在线浏览
Github: wooyun_articles

使用Nodejs下载图片

抓取图片链接的过程在此不再详述,无非就是打开每个html页面,找到其中img标签的src属性。我们拿到了这些html页面的图片链接,是这个样子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var imageLinks = [
'http://static.wooyun.org//drops/20160315/2016031513484536696130.png',
'http://static.wooyun.org//drops/20160315/2016031513484767273224.png',
'http://static.wooyun.org//drops/20160315/2016031513485057874324.png',
'http://static.wooyun.org//drops/20160315/2016031513485211060411.png',
'http://static.wooyun.org//drops/20160315/201603151348542560759.png',
'http://static.wooyun.org//drops/20160315/201603151348563741969.png',
'http://static.wooyun.org//drops/20160315/201603151348582588879.png',
'http://static.wooyun.org//drops/20160315/201603151349001461288.png',
'http://static.wooyun.org//drops/20160315/201603151349032455899.png',
......
'http://static.wooyun.org//drops/20150714/2015071404144944570.png',
'http://static.wooyun.org//drops/20150714/2015071404144966345.png',
'http://static.wooyun.org//drops/20150714/2015071404144915704.png',
'http://static.wooyun.org//drops/20150714/2015071404144980399.png',
'http://static.wooyun.org//drops/20150714/2015071404144927633.png'
];

我们将其定义为一个模块备用(总共大约有13000个图片链接)。

在Nodejs中下载图片有很多解决方案,比如可以使用npm包download。本文中使用比较简单的版本,具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var fs = require("fs");
var path = require('path');
var request = require('request');
var downloadImage = function(src, dest, callback) {
request.head(src, function(err, res, body) {
// console.log('content-type:', res.headers['content-type']);
// console.log('content-length:', res.headers['content-length']);
if (src) {
request(src).pipe(fs.createWriteStream(dest)).on('close', function() {
callback(null, dest);
});
}
});
};

代码来源: stackoverflow

手把手教你为React Boilerplate添加测试代码覆盖率报告

前言

上一篇文章中,葱哥从零开始创建了一个react的boilerplate,并使用webpack进行build,使其支持ES6,同时使用karma+mocha等进行单元测试。虽然单元测试有了,但是代码中哪些写了测试,哪些没写呢?本文就将在上一篇文章的基础上为其增加生成代码覆盖率的功能。

代码

本文的最终代码可以在react_boilerplate_v8中查看。

准备工作

react boilerplate代码

首先拿到上一篇文章的代码:

1
2
3
# git clone https://github.com/jiji262/react_boilerplate.git
# cd _tutorial_/react_boilerplate_v6

在正式开始之前,我们将对之前的代码做一些简单的修改,app目录用于存放源代码,test目录用于存放测试文件,文件结构如下:

1
2
3
4
5
6
7
8
9
|____app
| |____components
| | |____FooBar.js
| | |____HelloWorld.js
| |____index.js
|____test
| |____components
| | |____HelloWorld-spec.js
| |____index.spec.js

其中components目录用于存放React组件,其中有两个小的示例。具体代码可以参考Github.

build和test

现在在我们的项目目录下可以通过如下命令来运行和测试代码了。

1
2
3
4
5
# npm run dev # 开发环境,运行后使用http://localhost:3000/看到效果
# npm build # 生产环境编译
# npm run test # 使用karma+mocha进行测试

手把手教你基于ES6架构自己的React Boilerplate项目

Update

  • [20160725] Facebook 官方提供了一个可以生成React Starter项目的工具,有兴趣可以看下:create-react-app

前言

React技术之火爆无须多言,其与webpack的完美结合,也让二者毋庸置疑的成为天生一对。为了进行React的快速和规范化开发,开源社区中涌现了很多React+webpackboilerplate项目。通过使用这些boilerplate,我们可以快速的创建一个React项目的架构。

葱哥之前专门创建了一个Github项目用于收集这些boilerplateawesome-react-boilerplate。当然这里不可能完整收录,但是目前为止已经有近30个了。连boilerplate都这么多,真让我们眼花缭乱,无从下手。

当然,由于每个人的使用习惯和技术背景的不同,每个boilerplate都会有自己的侧重点,因此即便是公认比较好的boilerplate项目也未必适合所有人。我们拿到这些开源项目,只是知其然但是并不知其所以然。葱哥相信,只有适合自己的,才是最好的。这就是本文的初衷,葱哥会追根溯源,从项目开发的蛮荒阶段开始,搭建开发环境,配置webpack,在React项目中使用webpack,搭建项目的测试环境,一步一步构建适合适合自己的React + webpack起始项目。

本文陆陆续续写了将近一个月的时间,所使用的技术和依赖库均选用目前最新版本,其间大大小小的坑踩过不知道多少。本文供入门参考,如果你是前端大牛,请直接忽略此文。

当然,如果读后觉得对你有帮助,还请关注葱哥的Github

TL;DR

代码

本文所有代码可以在我的Github中找到:codeigniter_boilerplate

将使用的技术栈

如前所述,本文的主要目的是构建适合适合自己的React + webpack起始项目。与其他多数类似项目不同的是,我们不仅要支持ES6,使用webpack,而且要搭建一套相对完整的单元测试和自动化测试体系。本文主要使用到的相关技术如下:

  • React
  • webpack
  • babel
  • ES6
  • mocha
  • chai
  • sinon
  • karma
  • phantomJS

手把手教你使用Hexo + Github Pages搭建个人独立博客

系统环境配置

要使用Hexo,需要在你的系统中支持Nodejs以及Git,如果还没有,那就开始安装吧!

安装Node.js

下载Node.js
参考地址:安装Node.js

安装Git

下载地址:http://git-scm.com/download/

安装Hexo

1
2
3
4
5
6
7
$ cd d:/hexo
$ npm install hexo-cli -g
$ hexo init blog
$ cd blog
$ npm install
$ hexo g # 或者hexo generate
$ hexo s # 或者hexo server,可以在http://localhost:4000/ 查看

这里有必要提下Hexo常用的几个命令:

  1. hexo generate (hexo g) 生成静态文件,会在当前目录下生成一个新的叫做public的文件夹
  2. hexo server (hexo s) 启动本地web服务,用于博客的预览
  3. hexo deploy (hexo d) 部署播客到远端(比如github, heroku等平台)

另外还有其他几个常用命令:

1
2
$ hexo new "postName" #新建文章
$ hexo new page "pageName" #新建页面

常用简写

1
2
3
4
$ hexo n == hexo new
$ hexo g == hexo generate
$ hexo s == hexo server
$ hexo d == hexo deploy

常用组合

1
2
$ hexo d -g #生成部署
$ hexo s -g #生成预览

现在我们打开http://localhost:4000/ 已经可以看到一篇内置的blog了。

Javascript知识点:IIFE - 立即调用函数

Immediately-invoked Function Expression(IIFE,立即调用函数),简单的理解就是定义完成函数之后立即执行。因此有时候也会被称为“自执行的匿名函数”(self-executing anonymous function)。

IIFE的叫法最早见于Ben Alman的文章。文章中Ben Alman 已经解释得很清楚了,希望定义自执行函数式常见的语法错误有两种:

1) function (){ }()

期望是立即调用一个匿名函数表达式,结果是进行了函数声明,函数声明必须要有标识符做为函数名称。

2) function g(){ }()

期望是立即调用一个具名函数表达式,结果是声明了函数 g。末尾的括号作为分组运算符,必须要提供表达式做为参数。
所以那些匿名函数附近使用括号或一些一元运算符的惯用法,就是来引导解析器,指明运算符附近是一个表达式。

按照这个理解,可以举出五类,超过十几种的让匿名函数表达式立即调用的写法:

1)使用括号

( function() {}() );
( function() {} )();
[ function() {}() ];

2)使用一元操作符

~ function() {}();
! function() {}();
+ function() {}();
- function() {}();

3)使用void等操作符

delete function() {}();
typeof function() {}();
void function() {}();

4)使用表达式

var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
1 ^ function() {}();
1 > function() {}();

5)使用new关键字

new function(){ /* code */ }

new function(){ /* code */ }() //如果没有参数,最后的()就不需要了