lnmp编译日志

重新布署开发环境,基于CentOS6.4 64位。直接贴记录。

1. 基础配置
==================================================

1.1 连接网络
vi /etc/sysconfig/network-scripts/ifcfg-eth0

#NM_CONTROLLED="no"
ONBOOT="yes"

1.2 配置静态IP
IPADDR="192.168.80.91"
NETMASK="255.255.255.0"
BROADCAST="192.168.80.255"
GATEWAY="192.168.80.2"
DNS1="8.8.8.8"
DNS2="8.8.4.4"

1.3 配置网卡MAC地址
删除网卡信息
rm /etc/udev/rules.d/70-persistent-net.rules
重启

1.4 安装基础软件
yum install wget man lrzsz ntpdate

1.5 配置repe
wget http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm

1.6 更新源
yum makecache
yum update -x kernel*

1.7 更新系统
yum update

1.8 切换语言为中文
vi /etc/sysconfig/i18n
LANG="zh_CN.UTF-8"
source /etc/sysconfig/i18n

1.9 修改时区
tzselect
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

1.10 关闭防火墙和selinux
chkconfig iptables off
chkconfig ip6tables off
service iptables stop
service ip6tables stop

修改/etc/selinux/config文件中的SELINUX="" 为 disabled
如果不想重启系统,使用命令setenforce 0

1.11 加快启动
vi /boot/grub/grub.conf
修改 timeout = 5 为 timeout = 1


 1.12 安装工具
# 压缩解压工具
yum install p7zip-plugins
# 编译工具包软件
yum install gcc gcc-c++ make automake autoconf libtool zlib-devel openssl-devel

2. vmware相关配置
==================================================
2.1 添加虚拟硬盘
#查看
cat /proc/scsi/scsi
#添加
echo "scsi add-single-device 1 2 3 4" >>/proc/scsi/scsi
#移除
echo "scsi remove-single-device 1 2 3 4" >> /proc/scsi/scsi
#命令行解释
1 : SCSI HBA ID
2 : SCSI Channel
3 : SCSI ID
4 : LUN ID
#添加到第一块SCSI HBA, Channel 0, ID 3, LUN 0:
echo "scsi add-single-device 0 0 3 0" >>/proc/scsi/scsi

2.2 格式化,挂载
fdisk /dev/sdb 分区
mkfs.ext4 /dev/sdb1 格式化
mkdir /data
vi /etc/fstab
/dev/sdb1    /data    ext4    defaults    0 0
mount -a

2.3 安装vmtools
mkdir -p /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
cp VMwareTools-9.2.0-799703.tar.gz /data/pkg/
cd /mnt/cdrom
umount /mnt/cdrom
tar -xzf VMwareTools-9.2.0-799703.tar.gz
开启时间同步
vmware-toolbox-cmd timesync enable

3. 编译软件
==================================================
目录配置
#创建/data目录,所有数据放在此文件夹中
mkdir /data
#存放源码包
mkdir /data/pkg
#存放解压代码
mkdir /data/src

3.1 nodejs
cd /data/pkg/
wget http://nodejs.org/dist/v0.10.10/node-v0.10.10.tar.gz
tar -xzf node-v0.10.10.tar.gz -C /data/src
cd /data/src/node-v0.10.10
./configure --prefix=/usr/local/node-v0.10.10
ln -s /usr/local/node-v0.10.4 /usr/local/node
mkdir /usr/local/node/node_modules
ln -s /usr/local/node/node_modules /usr/local/lib/
npm config set prefix /usr/local

vim /etc/prefix
#环境变量
export NODE_HOME=/usr/local/node
export NODE_PATH=$NODE_PATH/node_modules

export SOFT_PATH=$NODE_HOME/bin

PATH=$PATH:$SOFT_PATH

source /etc/prefix

npm config set prefix /usr/local

3.2 编译nginx
cd /data/pkg
wget http://nginx.org/download/nginx-1.4.1.tar.gz
tar -xzf nginx-1.4.1.tar.gz -C /data/src
#安装依赖
yum install pcre-devel
#添加用户
groupadd www
useradd -s /sbin/nologin -g www www -M
cd /data/src/nginx-1.4.1

./configure --prefix=/usr/local/nginx.basic \
--user=www \
--group=www \
--pid-path=/var/run/nginx.basic.pid \
--lock-path=/var/lock/nginx.basic.lock \
--with-http_ssl_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-mail --with-mail_ssl_module \
--http-client-body-temp-path=/var/tmp/nginx.basic/client \
--http-proxy-temp-path=/var/tmp/nginx.basic/proxy \
--http-fastcgi-temp-path=/var/tmp/nginx.basic/fastcgi \
--http-uwsgi-temp-path=/var/tmp/nginx.basic/uwsgi \
--http-scgi-temp-path=/var/tmp/nginx.basic/scgi \
--error-log-path=/var/log/nginx.basic.error.log \
--http-log-path=/var/log/nginx.basic.access.log

make && make install
vi /usr/local/nginx.basic/sbin/nginxd
###启动脚本### {{{
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
prefix="/usr/local/nginx.basic
nginx="${prefix}/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="${prefix}/conf/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   if [ -z "`grep $user /etc/passwd`" ]; then
       useradd -M -s /bin/nologin $user
   fi
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    sleep 1
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac
###启动脚本结束### }}}
ln -s /usr/local/nginx.basic /usr/local/nginx
ln -s /usr/local/nginx/sbin/nginxd /etc/init.d/nginxd

# 修改启动用户为www
vim /usr/local/nginx/conf/nginx.conf
user www www;

# 添加开机启动
chkconfig --add nginxd

3.3 编译mysql
cd /data/pkg
wget http://cdn.mysql.com/Downloads/MySQL-5.6/MySQL-5.6.12-1.el6.src.rpm
rpm -ivh MySQL-5.6.12-1.el6.src.rpm
cp /root/rpmbuild/SOURCES/mysql-5.6.12.tar.gz /data/pkg
tar -xzf mysql-5.6.12.tar.gz -C /data/src/
yum install cmake bison gperf ncurses-devel readline-devel time
#添加mysql用户
groupadd mysql
useradd -s /sbin/nologin -g mysql mysql -M

cd /data/src/mysql-5.6.12
cmake . -DCMAKE_INSTALL_PREFIX=/opt/mysql5.6
make && make install

cd /opt/mysql5.6
./scripts/mysql_install_db --user=db
vi my.cnf

datadir = /opt/mysql5.6/data
socket = /tmp/mysql.sock
pid-file = /var/run/mysql.pid

ln -s /opt/mysql5.6/support-files/mysql.server /etc/rc.d/init.d/mysqld
/etc/rc.d/init.d/mysqld start
#修改密码
./bin/mysqladmin -u root password '123456'

#添加开机启动
chkconfig --add mysqld


3.4 编译php
cd /data/pkg/
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
wget http://tw1.php.net/distributions/php-5.3.26.tar.gz
tar -xzf libiconv-1.14.tar.gz -C /data/src
tar -xzf php-5.3.26.tar.gz -C /data/src

yum install libxml2-devel curl-devel libjpeg-devel libpng-devel gd-devel freetype-devel zlib-devel libmcrypt-devel libtool-ltdl-devel
cd /data/src/libiconv-1.14/

./configure --prefix=/usr/local/libiconv
make && make install
echo "/usr/local/libiconv/lib">>/etc/ld.so.conf.d/usr_local_lib.conf
ldconfig

ldconfig -p | grep libiconv

cd /data/src/php-5.3.26/

./configure \
--prefix=/usr/local/php5.3 \
--with-config-file-path=/usr/local/php5.3/etc \
--with-config-file-scan-dir=/usr/local/php5.3/etc/conf.d \
--with-mysql=mysqlnd \
--with-iconv=/usr/local/libiconv \
--with-freetype-dir \
--with-jpeg-dir \
--with-zlib \
--with-libxml-dir=/usr \
--enable-xml \
--disable-rpath \
--enable-discard-path \
--enable-safe-mode \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--with-curl \
--with-curlwrappers \
--enable-mbregex \
--enable-fpm \
--enable-mbstring \
--with-mcrypt \
--with-gd \
--enable-gd-native-ttf \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets  \
--with-xmlrpc \
--enable-zip \
--enable-soap \
--with-pdo-mysql=mysqlnd \
--with-mysqli=mysqlnd

make ZEND_EXTRA_LIBS='-liconv'
make install

#复制配置文件
ln -s /usr/local/php5.3 /usr/local/php
mkdir /usr/local/php/etc/back
cp php.ini* /usr/local/php/etc/back
cp sapi/fpm/init.d.php-fpm /usr/local/php/bin/php-fpm
#因为php5.3开始自带fpm,使用自带的管理脚本
cd /usr/local/php/etc
cp back/php-fpm.conf.default ./php-fpm.conf
cp back/php.ini-production ./php.ini

#修改 php-fpm.conf
vi /usr/local/php/etc/php-fpm.conf
修改  ;pid = run/php-fpm.pid 为  pid = run/php-fpm.pid (去掉前面的分号)
修改 user = nobody 为 user = www
修改 group = nobody 为 group = www

#配置php-fpm
chmod +x /usr/local/php/bin/php-fpm
ln -s /usr/local/php/bin/php-fpm /etc/init.d/php-fpm

#添加启服务
chkconfig --add php-fpm
#启动php-fpm
service php-fpm start

3.5 编译python
cd /data/pkg/
wget http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tgz
tar -xjf Python-2.7.5.tgz -C /data/src
cd /data/src/Python-2.7.5
./configure --prefix=/usr/local/python27
make && make install

rm /bin/python /bin/python2 -f
#修改yum,引用python2.6
vi yum
#!/usr/bin/python26

配置PATH
vi /etc/profile
export PY_PATH=/usr/local/python27
在SOFT_PATH后面加上:$PY_PATH/bin
}}}
cd /usr/bin
rm python
vi yum
#!/usr/bin/python2.6

3.6 编译安装ruby
wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
wget ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p195.tar.bz2
tar -zxf yaml-0.1.4.tar.gz -C /data/src
tar -jxf ruby-2.0.0-p195.tar.bz2 -C /data/src

yaml
cd /data/src/yaml-0.1.4 #pwd
./configure --prefix=/usr/local/libyaml
make && make install

ruby
cd /data/src/ruby-2.0.0-p195
./configure --prefix=/usr/local/ruby200 --enable-shared --disable-install-doc --with-opt-dir=/usr/local/libyaml
make && make install

vi /etc/profile
export RUBY_PATH=/usr/local/ruby200
在SOFT_PATH后面加上:$RUBY_PATH/bin

gem sources --remove http://rubygems.org/
gem sources -a http://ruby.taobao.org/
gem update --system


4. 其它配置
4.1 目录配置
#放置网站
mkdir /data/www
ln -s /data/www /www
#放置配置
mkdir cfg
mkdir cfg/nginx #nginx配置
mkdir cfg/php53 #php5.3配置
mkdir cfg/vim #vim配置

4.2 配置samba
yum install samba

#存放samba共享
mkdir /share

groupadd share
useradd -M -s /sbin/nologin -g share share
#设置share帐号的samba密码
smbpasswd -a share
chown share:share /share
chmod 777 /share

vi /etc/samba/smb.conf
# 在[global]处添加
; 软链接
follow symlinks = yes
wide links = yes
unix extensions = no

# 在底部添加
[Share]
comment = share
path = /share
public = no
writable = yes
valid users = share
; 权限
force user = root
force group = root
create mask = 0664
directory mask = 0775

#链接目录
ln -s /data /share
ln -s /data/www/ /share/
ln -s /data/cfg /share/
ln -s /data/local /share
ln -s /data/opt /share
ln -s /data/src /share
ln -s /data/pkg /share

4.3 php扩展
安装 APC redis
/usr/local/php/bin/phpize
./configure --enable-apc --with-php-config=/usr/local/php/bin/php-config
make
make install

vi /usr/local/php/etc/conf.d/apc.ini

extension = "apc.so"
apc.enabled = 1
apc.cache_by_default = on
apc.shm_segments = 1
apc.shm_size = 32M
apc.ttl = 3600
apc.user_ttl = 3600
apc.num_files_hint = 0
apc.write_lock = On

vi /usr/local/php/etc/conf.d/redis.ini

[redis]
extension = "redis.so"


4.4 nginx模板范本
# localhost
server {
    listen 80 default;
    root /www/localhost;
    index  index.html index.htm index.php index-dev.php;
    server_name localhost;

    location ~* \.php {
        fastcgi_pass 127.0.0.1:9000;
        #fastcgi_pass unix:/tmp/nginx_sockets_php5-fpm.sock;
        fastcgi_index index-dev.php;
        include fastcgi.conf;
        set $path_info "";
        set $real_script_name $fastcgi_script_name;
        if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
            set $real_script_name $1;
            set $path_info $2;
        }
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param SCRIPT_NAME $real_script_name;
        #fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
        #fastcgi_param PATH_INFO $fastcgi_path_info;
        #fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
    }
    location ~* \.(jpg|png|jpeg|bmp|gif|swf|js|css) {
        #expires 7d;
        access_log off;
        add_header Cache-Control no-cache;
    }
    #if (!-e $request_filename) {
        #rewrite ([0-9]+)-qr\.png$ /qr.php?id=$1 last;
        #rewrite "^(.*)\.[0-9]{8,}\.(js|css|png|jpg|gif|bmp|ico)" $1.$2 last;
        #rewrite ^(((?!\.php).)*)$ /index-dev.php$1 break;
        #rewrite  ^(.*)$  /index-dev.php?s=$1 break;
        #rewrite  ^(.*)$  /index-dev.php$1 last;
    #}
}

linux磁盘分区和挂载

接昨天的[linux热拔插scsi硬盘],分享下磁盘分区和挂载。输入fsdisk -l可以看到/dev/sdb磁盘信息。

1.分区
fdisk /dev/sdb
#按 m 可以显示帮助
Command (m for help):
#输入n并回车添加一个1个新分区
n
#分区类型提示
Command action
   e   extended
   p   primary partition (1-4)
#p创建主分区,e创建扩展分区。这里创建主分区,按p并回车
p
#输入分区号
Partition number (1-4):
#按1并回车
1
#输入起始柱面默认为1,这里直接回车
<Enter>
#结束柱面可以输入柱面数或分区大小,这里创建20GB,输入+20GB并回车
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610):
+20GB
#创建完成,按w并回车写入分区信息
w

2. 格式化分区,这里直接格式化为ext4的磁盘格式。
mkfs.ext4 /dev/sdb1

3. 挂载分区
将新的分区挂载到 /data 目录下,创建挂载目录
mkdir /data
修改分区信息 vi /etc/fstab 在后面加入下面的内容。
/dev/sdb1               /data                   ext4    defaults        0 0
使/etc/fstab中的挂载信息生效
mount -a
输入mount -l,可以看到/dev/sdb1 on /data type ext4 (rw)的信息,表示挂载成功。直接修改/etc/fstab配置,下次开机自动挂载。

测试系统是 CentOS6.4_x64

linux热拔插scsi硬盘

自己配置虚拟机,需要添加一块虚拟硬盘存放数据。虚拟机在更新软件,不想停机。学习了下热拔插硬盘的知识点

1. 在虚拟机中创建虚拟磁盘并添加。

2. 查看目前的磁盘信息
cat /proc/scsi/scsi
我返回的结果如下:

Attached devices:
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: NECVMWar Model: VMware IDE CDR10 Rev: 1.00
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Host: scsi2 Channel: 00 Id: 00 Lun: 00
  Vendor: VMware,  Model: VMware Virtual S Rev: 1.0 
  Type:   Direct-Access                    ANSI  SCSI revision: 02

上面scsi1是光驱,scsi2那个设备是我的系统硬盘。

3. 添加硬盘设备
echo "scsi add-single-device 2 0 1 0" >> /proc/scsi/scsi
数字参数说明:默认添加一块硬盘和原有系统硬盘是同一组的,第一个数字是scsi2这里的2,第二个是Channel这里是0,第三个是Id,在原有值上面加1,Lun默认为0。再用cat /proc/scsi/scsi可以看到硬盘信息,fdisk -l,可以看到/dev/sdb硬盘。

如果需要移除刚才添加的硬盘使用 echo "scsi remove-single-device 2 0 1 0" >> /proc/scsi/scsi 就可以,把add-single-device换成了remove-single-device,其它相同。

测试系统是 CentOS6.4_x64

用js闭包特性实现一个缓存器

闭包这个词,不知道什么时候起成了js必须掌握的知识点。分享一个实例,一个简单的缓存器。

使用场景:需要存储一些内容,但希望内容是受保险的,只存储符合一定规则的内容,通过指定的接口访问。不会被不受控的代码修改其中的值。代码如下:

window.cache = (function(){
  var _data = [];
  return {
    add: function(name, value, force) {
      if (force || !_data[name]) {
        _data[name] = value;
        return true;
      }
      return false;
    },
    get: function(name) {
      return _data[name] || false;
    },
    del: function(name) {
      try {
        delete _data[name];
      }
      catch (e) { }
      return true;
    }
  }
})();

简单说明:_data是函数的局部变量,存在于函数中的add、get、del方法在函数执之后依然可以访问到_data,这种情况被称之为闭包。数据存储在_data这个局部变量中,add get del可以访问_data进行操作,充当外界访问的接口,与外界代码隔离。可以在add中添加过淲规则,达到对数据进行过滤的目的。外界通过 add、get、del方法来操作,可以防止某些不兼容的代码直接将变量置空或删除(这种概率较低的)。

关于弹出层的两个兼容性bug

这两天修改一个弹出层,发现两个较诡异的bug。一翻折腾得出结论:不要直接在body标签中插入大段html代码。

bug1:ie6下,弹出层中的背景图片有一定机率不显示。

正常情况下:

背景图片未显示:

bug2:在世界之窗(基于chromium17的壳浏览器)中,点击调用弹出层,默认不显示。将页面滚动一下,弹出层正常显示。

bug1在经过各种折腾后,将开发的web服务器上去掉add_header Cache-Control no-cache;之后正常。bug2原来打算在显示弹出层之后,将页面的scroll的值+1。隔天因为另一个需求对js代码进行调整,原来弹出层代码段是下面这样的:

var html = '...';
$("body").append(html);
 
修改为下面代码段
 
$wrap = $('...');
$wrap.hide();
$wrap.appendTo('body');
$wrap.html('...');
$wrap.show();

后面再校验时,上面两个bug全部消失。

 

一个批量转换coffee的Makefile

有一个小需求,将一个目录包括子目录中的coffee文件批量转换到另一个指定的目录中,同时保挂子目录的结构。改了一个类似的Makefile。发一下备忘:

coffeeBaseDir=coffee/
coffeeDir=$(abspath $(coffeeBaseDir))
jsBaseDir=js/
jsDir=$(abspath $(jsBaseDir))

jsFile=$(shell find $(coffeeBaseDir) -type f -name *.coffee | sed 's@^$(coffeeBaseDir)@$(jsDir)/@g' | sed 's@\.coffee$$@\.js@g')

jsDeploy: $(jsFile)

$(jsDir)/%.js: $(coffeeDir)/%.coffee
	@mkdir -p `sed 's@/[^/]\+$$@/@g' <<< '$@'`
	coffee -bp $< > $@

test:
	@echo $(jsFile)

clean:
	@rm js -fr
	@echo 'clean success!'

测试结果:

 

>find coffee -type f
coffee/abc.coffee/3.coffee
coffee/abc.coffee/1.coffee
coffee/abc.coffee/2.coffee
coffee/p1/3.coffee
coffee/p1/1.coffee
coffee/p1/2.coffee
coffee/p2/3.coffee
coffee/p2/1.coffee
coffee/p2/2.coffee
coffee/p3/3.coffee
coffee/p3/1.coffee
coffee/p3/2.coffee

>find js -type f
js/abc.coffee/2.js
js/abc.coffee/1.js
js/abc.coffee/3.js
js/p1/2.js
js/p1/1.js
js/p1/3.js
js/p2/2.js
js/p2/1.js
js/p2/3.js
js/p3/2.js
js/p3/1.js
js/p3/3.js

 

nginx使用ngx_http_empty_gif_module模块

在nginx官网看到有ngx_http_empty_gif_module这个模块,可以默认输出一个空白的gif,某个png透明的插件要用到这种透明的gif文件,简单看了下,配置方法很简单:

location = /_.gif {
    empty_gif;
}

最开始我本地总是提示File not found.针对php框架的rewrite将这个请求重定向到了php请求,在rewrite最开始添加了一行 rewrite ^/_\.gif$ /_.gif break; 将文件重定向一次OK了

参考链接:
ngx_http_empty_gif_module: http://nginx.org/en/docs/http/ngx_http_empty_gif_module.html

 

[锋利web前端开发]vim用autocommand插件编译coffee

锋利web前端为一个系列文章,分享利用python、vimscript等语言,整合haml、sass、coffee等实现快速前端开发。

可以到 [锋利web前端开发]索引贴 查看当前系列的所有文章

本篇主要讲解 使用vim插件autocommand编译coffee并调用uglifyjs进行压缩。

自己为了提升工作效率而写的一个插件,以整合coffee开发为例子。列举一下使用方式。

1.安装:
插件地址:https://github.com/thinkjs/autocommand (目前没有发布到vim.org上面),用git获取以后,将plugin目录中的autocommand.vim复制到vim的plugin目录即可。
依赖:python2.x

2.npm相关插件安装
通过调用外部命令来实现功能,需要安装cofee和uglify。安装命令npm install coffee-script uglify-js -g。

3.创建项目及配置
vim打开项目路径,我这里是E:\project\test。创建js文件夹,用来放转换后的js代码。创建_source文件夹,用来存放源代码及配置文件。vim切换路径到_source文件夹。pwd一下,应该显示的是E:\project\test\_source,输入:AcmdInitConfig命令,按y创建配置文件。​刷新_source文件夹,此时可以看到_config的配置文件。在_source下面创建coffee文件夹,用来放coffee源代码。这时整个目录应该是这样:

E:/project/test/
|~_source/
| |coffee/
| `-_config
|~js/

4.修改配置项
修改配置文件中的 coffee/ 相关配置项里 command 数组中添加一行 , "uglifyjs -mo ../js/#{$fileName}.min.js ../js/#{$fileName}.js",修改后整个配置文件内容如下:

{
  "jade/": {
    "path": "~",
    "jade": {
      "command": [
        "jade -PO ../ jade/#{$fileName}.jade"
      ]
    }
  },
  "sass/": {
    "path": "~",
    "sass": {
      "command": [
        "sass --style compact sass/#{$fileName}.sass ../css/#{$fileName}.css"
         /* , "cp -fp ../css/#{$fileName}.css ../../public/css" */
      ]
    }
  },
  "coffee/": {
    "path": "~",
    "coffee": {
      "command":[
        "coffee -bp coffee/#{$fileName}.coffee>../js/#{$fileName}.js"
        , "uglifyjs -mo ../js/#{$fileName}.min.js ../js/#{$fileName}.js"
         /* , "cp -fp ../js/#{$fileName}.js ../../public/js" */
      ]
    }
  }
}
/* vim:ft=javascript ts=2 sts=2 sw=2 et
*/

配置是一个json格式的文件。jade和sass的如果不用,可以删除。

5.编写代码文件
在_coffee文件夹下创建main.coffee文件,敲入一段coffee代码:

# Assignment:
number   = 42
opposite = true

# Conditions:
number = -42 if opposite

# Functions:
square = (x) -> x * x

# Arrays:
list = [1, 2, 3, 4, 5]

# Objects:
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

# Splats:
race = (winner, runners...) ->
  print winner, runners

# Existence:
alert "I knew it!" if elvis?

# Array comprehensions:
cubes = (math.cube num for num in list)

vim执行:Acmd命令,如果执行正确,VIM底部会出现一串类似 19:44:29 execute coffee 这样的提示,表示执行成功。如果报错,会把错误显示出来。这时刷新E:/project/test/js文件夹,应该有main.js和main.min.js两个文件,main.js是main.coffee生成的js文件,main.min.js是用uglifyjs压缩后的js文件。

相关链接:
coffeescript: http://coffeescript.org/
uglifyjs: https://github.com/mishoo/UglifyJS2
autocommand使用说明:https://github.com/thinkjs/autocommand/wiki/quickref03

相关截图:
配置

执行成功的提示

报错提示

vim让代码整齐美观的小技巧

一、空格和Tab相关

空格和Tab是两种常见的排版缩进的字符,常见项目中的风格问题往往由此而起。vim可以很容易的处理好这些问题。首先我们要把这两个字符显示出来,默认这两个字符都是白的。使用如下方法设置:

" 显示tab和空格
set list
" 设置tab和空格样式
set lcs=tab:\|\ ,nbsp:%,trail:-
" 设定行首tab为灰色
highlight LeaderTab guifg=#666666
" 匹配行首tab
match LeaderTab /^\t/

上面的设置将Tab显示为|(竖线),将行尾的空格显示为-(减号)。原本看起来好象还挺整齐的代码,这下原形毕露了。如下图:

列举几种常见tab和空格编码问题:
1. 代码中Tab和空格混排
需求:将空格转为Tab或Tab转为空格
解决方法:先设置自己的缩进设置,例如我是用4个空格缩进:set ts=4 sts=4 sw=4 et,然后敲入:ret可将代码中原有的Tab转成4个空格。后续编辑中,Tab键自动生成4个空格,你删除的时候,按一个删除键,删除的也是4个空格。如果你是用4个空格宽度的Tab缩进的,使用:set ts=4 sts=4 sw=4 noet,然后敲入:ret即可。

2. 行尾多余的空格和Tab
需求:删除多余空格
解决方法:输入:%s/\s*$//ge,将行尾多余空格删除。

二、换行相关

因为开发人员工具设置不同,导致两个文件换行符不同,或者同一个文件中出现多种换行符。
1. 转换文件换行方式
解决方法:设置fileformat属性,:set ff=dos (\r\n win换行) :set ff=unix (\n unix/linux换行) :set ff=mac (\r Mac换行)

2. 换行符混排(常见的情况是Win换行和Unix换行混排,VIM中会将文件识别为unix换行,在行尾显示^M)
需求:统一换行符
解决方法:输入:%s/\r//ge,将多余\r去掉,这时全部剩下\n换行然后保存。如果需要保存为win换行设置:set ff=dos再保存即可。

三、缩进对齐

类似Python的编码风格以缩进代表层级。这种情况将缩进层次多了,有时候很难确定这一段代码是否和上一段代码在同一缩进水平上。自己写了一个简单的函数,通过设置cc的值,来显示一条纵向的线作参考线。效果如下:

代码如下:快捷键Alt+o向左、Alt+u向左移动参考线

" --------------------------------------------------
" [参考线切换] {{{
" --------------------------------------------------
fu! ReferenceLine(t)
	let ccnum = &cc
	if ccnum == '' | let ccnum = 0 | en
	let csw = &sw
	if a:t == 'add'
		let ccnum = ccnum + csw
		exec "setl cc=".ccnum
	elsei a:t == 'sub'
		let ccnum = ccnum - csw
		if ccnum >= 0 | exec "setl cc=".ccnum | en
	en
endf
nn <silent> <A-u> :call ReferenceLine('sub')<CR>
nn <silent> <A-o> :call ReferenceLine('add')<CR>
" }}}

四、赋值符号对齐

有时候我们可能希望我们一段的赋值代码都用=号对齐,象下图这样:

解决方法:安装Tabular插件,选中要对齐的代码,输入:Tab/= 让代码通过=两边对齐。

用grunt自动编译sass文件并压缩

之前抽时间研究了下gruntjs,分享一下使用grunt编译sass源文件的方案。gruntjs作为nodejs的自动化工具,现在有大量可用插件可让你的工具效率提升,有兴趣的可以了解下。http://gruntjs.com/

1. 创建项目目录,进到目录。
mkdir grunt3
cd grunt3

2. 创建项目包管理文件 package.json

{
  "name": "myproject",
  "description": "我的grunt项目",
  "version": "0.1.0",
  "readmeFilename": "README.md",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-sass": "~0.3.0",
    "grunt-contrib-watch": "~0.4.4",
    "grunt-contrib-cssmin": "~0.6.1"
  }
}

3. 安装grunt包及需要用到的组件包

npm install -g grunt-cli
npm install grunt grunt-contrib-sass grunt-contrib-cssmin grunt-contrib-watch --save-dev

4. 创建grunt任务文件 Gruntfile.coffee

module.exports = (grunt)->
  grunt.initConfig
    pkg: grunt.file.readJSON('package.json')

    sass:
      dist:
        options:
          style: 'compact'
        files:
          'css/style.css' : 'sass/style.sass'
      dev:
        options:
          style: 'expanded'

    cssmin:
      min:
        files:
          'css/style.min.css': 'css/style.css'

    watch:
      css:
        files: ['sass/_common.sass', 'sass/style.sass']
        tasks: ['sass:dist', 'cssmin:min']


  grunt.loadNpmTasks('grunt-contrib-sass')
  grunt.loadNpmTasks('grunt-contrib-cssmin')
  grunt.loadNpmTasks('grunt-contrib-watch')

  # Default task(s)
  grunt.registerTask('default', ['sass'])

  undefined

上面的配置中,将sass文件放在sass目录下,css文件放在css目录下。style.sass中包含_common.sass文件,当两个中的一个发生修改时,重新编译style.sass文件。编译后执行cssmin压缩css文件。

5. 使用
创建css sass目录,在sass目录中创建sass源文件,终端中输入 grunt watch。修改sass源文件时,grunt会自动执行编译。

相关链接:
gruntjs: http://gruntjs.com/
grunt-contrib-watch: https://github.com/gruntjs/grunt-contrib-watch
grunt-contrib-cssmin: https://github.com/gruntjs/grunt-contrib-cssmin
grunt-contrib-sass https://github.com/gruntjs/grunt-contrib-sass
grunt插件列表: https://github.com/gruntjs