Docer for Mac的ca.pem找不到的问题

之前安装过Docker Toolbox来实现在Mac上面跑Docker,后来Docker又出了一个Docker for Mac,好奇心一起就卸了Docker Toolbox,装了它。

愿意尝试的原因是Docker Toolbox主要是用VirtualBox来放container,Mac环境里面相关的docker命令其实都是代理,最终的实现是在VirtualBox里面。而Docker for Mac用的是macOS的一个框架HyperKit来实现的,不需要使用VirtualBox来做中间代理,性能上会有很大的提升。当然,前提是你的系统是升级到了macOS10.11。

顺利安装和启动Docker for Mac之后,在命令行运行docker info命令,会出现如下错误。

could not read CA certificate "/Users/{{username}}/.docker/ca.pem": open /Users/{{username}}/.docker/ca.pem: no such file or directory

在网上找了不少解决方式,

bash_profile

尝试了下这个网址里面说的https://github.com/boot2docker/osx-installer/issues/126
我的用户目录下没有.bash_profile的文件,我是用的zsh,所以在.zsh_rc找了找(安装Docker Toolbox是很久之前的事情了,根本不记得当初怎么安装的),意外的也找到了当初配置的一些DOCKER_*的环境变量。注释,重启zsh,再次运行docker info,还是不行。

docker machine

然后又继续尝试上面网址里面,后续给的方法:

docker-machine regenerate-certs default

 egenerate TLS machine certs?  Warning: this is irreversible. (y/n): y
 Regenerating TLS certificates
 Host does not exist: "default"

失败。

既然是说default不存在,那我就来创建一个

查看了docker-machine相关的命令,刚好有一个create命令,执行了一下:

docker-machine create default
 Creating CA: /Users/{{username}}/.docker/machine/certs/ca.pem
 Creating client certificate: /Users/{{username}}/.docker/machine/certs/cert.pem
 Running pre-create checks...
 Error with pre-create check: "exit status 126"

搜了一下关于exit status 126 的相关错误,说的是没安装VirtualBox,这时候我觉得不对劲了,因为跑Docker for Mac是不需要VirtualBox的啊。

正式看了一下docker machine是什么东西,原来是一个用来方便的管理多种类型的docker主机的一个工具,可以是虚拟机,本地主机和云平台,具体可以看看这个链接:https://yeasy.gitbooks.io/docker_practice/content/machine/usage.html

顺便推荐一下这本电子书《Docker —— 从入门到实践》

看完docker machine的作用,可以看的出来,这和我现在想做的事情和遇到的问题,没有太大干系。我是安装完了Docker的环境,然后在执行docker命令的时候出现了问题,不是在已经有container的时候在维护上出了问题。

环境变量

这时候我开始回到官网来追根溯源了,很幸运的找到一篇深入比较Docker for Mac和Docker Toolbox的文章:Docker for Mac vs. Docker Toolbox

这个对于Docker for Mac和Docker Toolbox各自的实现机制说的十分透彻,同时还意外的有一个Setting up to run Docker for Mac章节,说了如何配置Docker for Mac的环境,在你已经或者曾经安装过Docker Toolbox的情况下。

按照上面说的执行命令

env | grep DOCKER

顺利的找到了所有的DOCKER_*的环境变量

对对应的变量执行 unset

 unset DOCKER_TLS_VERIFY
 unset DOCKER_CERT_PATH
 unset DOCKER_MACHINE_NAME
 unset DOCKER_HOST

再次执行

env | grep DOCKER

保证环境变量已经清除。

然后执行

docker info

一个正常的信息列表出来了

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.03.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host ipvlan macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
...

以上就是整个debug的过程。其实这么折腾,主要还是自己不是很了解docker,得抽空再好好看看上面说的那本电子书才行了。

webpack的target选项的作用

从一个Electron项目说起

这两天在折腾用Electron来写一个弹幕助手,方便用PC直播的主播能够看到用户发的弹幕并且进行回复和相关管理操作。

主要的开发任务就是对PC站点已有功能的搬迁和调整。

在最后实现退出功能的时候,希望是在菜单栏上有一个退出按钮,用户点击就能直接退出。

下面是mainProcess里面配置菜单的代码,针对退出登录按钮注册了事件,点击的时候,通知对应的web页去实现退出登录功能。

const template = [
    {
        label: '操作',
        submenu: [
            {
                label: '关闭助手',
                role: 'quit'
            },
            {
                label: '退出登录',
                click: function(){
                    mainWindow.webContents.send('main-process-message', '{action: "quit-login"}');
                }
            }
        ]
    }
];

然后是renderProcess这边监听事件并对应处理

const ipc = require('electron').ipcRenderer;
ipc.on('main-process-message', (event, data) => {
    switch(data.action) {
        case "quit-login": 
            user.quit();
            console.log('quit');
            break;
    }
});

一个意外的错误

项目这块,renderProcess的代码都是用webpack进行编译的。

在renderProcess里面引入electron模块之后,立马就报了一个问题:

ERROR in ./~/.1.6.2@electron/index.js
Module not found: Error: Can't resolve 'fs' in '/xxx/electron-quick-start/node_modules/.1.6.2@electron'
@ ./~/.1.6.2@electron/index.js 1:9-22
@ ./js/index.js

上网看了一圈,发现github上的webpack项目里面有人遇到了类似的问题:

Error: Cannot resolve module ‘fs’ with electron and js

然后底下有人给出了解决方式,在webpack.config.js里面加上target: 'electron'就可以的。

试了一下,发现果然是可以的。

深入了解target属性

解决问题之后,出于好奇,就去webpack官网看了target配置的文档

webpack可以为js的各种不同的宿主环境提供编译功能,为了能正确的进行编译,就需要开发人员在配置里面正确的进行配置。

默认情况下,target的值是web,也就是为类浏览器的环境提供编译。

完整的target属性值及对应作用的列表如下:

拷贝自https://github.com/webpack/webpack.js.org/edit/master/content/configuration/target.md

target Description
async-node Compile for usage in a Node.js-like environment (uses fs and vm to load chunks asynchronously)
~~atom~~ Alias for electron-main
~~electron~~ Alias for electron-main
electron-main Compile for Electron for main process.
electron-renderer Compile for Electron for renderer process, providing a target using JsonpTemplatePlugin, FunctionModulePlugin for browser environments and NodeTargetPlugin and ExternalsPlugin for CommonJS and Electron built-in modules.
node Compile for usage in a Node.js-like environment (uses Node.js require to load chunks)
node-webkit Compile for usage in WebKit and uses JSONP for chunk loading. Allows importing of built-in Node.js modules and nw.gui (experimental)
web Compile for usage in a browser-like environment (default)
webworker Compile as WebWorker

所以,把target设为electron,也就能正确的对Electron环境下的代码进行编译了,不过我的代码是写在renderProcess里面的,所以把targets设置为electron-render才是更加合理的选择。

关于如何挑选云存储的一点想法

在13年的时候, 写过一篇博文–关于数据备份. 里面讲到了我悲惨的数据丢失和找回的经历, 也说了一些对数据备份的方案. 关于云备份, 只是大致的说了点.

就在今天, 先是群里面有人发了张照片, 说金山快盘要关闭了

kuaipan-down

一开始是有点不相信的, 因为我从快盘刚出现的时候, 基本就开始使用了, 看着它一个平台一个平台的支持, 性能也是一天天的好, 给的空间也是一天天的大. 中间自己还提过不少的反馈. 而且是金山公司的. 怎么可能突然就要关闭了.

kuaipan-storage

然后就访问官网, 还真是要关闭了, 而且所属公司, 也不知道什么时候变成迅雷了…

对数据的分级

所以我现在就得重新考虑我这几十个G的数据的何去何从了. 也算是来一次”重构”吧.

首先, 就得对数据做一个划分, 不能再跟以前一样, 所有的数据都是大杂烩的放一起了, 存储是要钱的(后面会说到选择收费的云存储)

按隐私,重要性,可维护性,体积来划分:

  • 很隐私的文件: 不能被他人看到, 也不能被政府等第三方随意抽查
  • 比较隐私的文件: 可以接受被第三方做安全和和合法性的检查, 但是不能被抓取和利用文件中的内容. 比如一些工作文件,系统备份
  • 不是隐私文件: 虽然不是隐私文件, 但是也想能够收集起来, 方便查阅
  • 很重要的文件: 绝对不能丢失
  • 比较重要的文件: 平时收集的一些网上的文档和程序. 丢失很可惜, 但是也是可以再次收集的
  • 方便维护的文件: 数量相对比较少, 而且划分的维度不多. 比如手机照片, 基本一个文件夹, 可劲的塞进去都行
  • 不方便维护的文件: 比如媳妇做设计收集的图片和psd, 各种分类各种划分, 人工维护不方便. 还有系统的备份, 手机的备份
  • 大文件: 体积在200M以及往上的文件 软件和视频
  • 中等文件: 1M到20M 多是音乐和图片
  • 小文件: 个人文档, 代码等等

按范围分: 个人文件和公司文件.

按类型分: 图片, 文档, 软件, 字体, 音乐, 视频, 备份, 代码

这些划分不是独立的, 四个维度可以综合的来描述某一类文件.

云存储的分级

云存储的公司很多, 需要一个好的筛选维度去进行划分, 这样才好按照自己的需要进行选择.

按隐私, 持久, 价格和便捷性来划分:

  • 隐私程度: 存储的内容不会被云存储公司自身或者政府翻阅的可能性 国外的大于国内的 要翻墙的大于不要翻墙的
  • 持久: 这个云存储能保证有效的时间, 像这次金山快盘的突然关闭, 来几次会让人崩溃, 所以要挑选能长久有效的云存储. 一般来说, 收费的大于免费的, 价格高的大于价格低的
  • 价格: 今天看了下. Dropbox(€9.99/月 1TB) > GoogleDrive ($1.99/月 100GB) > OneDrive(¥15/月 50GB) ~ 坚果云(30GB起 增量1GB/月 不封顶 ¥16.66/月) > 百度云盘(免费, 存储按T算, 基本算不封顶) = 微云(免费, 存储按T算, 基本算不封顶) = 360云盘(免费, 存储按T算, 基本算不封顶)
  • 便捷性: 速度,是否需要翻墙,对各个系统的支持,对文件的格式的支持. 这个基本上对系统的支持, 对文件格式的支持都差不多. 所以主要看速度和是不是需要翻墙. 个人感觉 OneDrive > 国内云 > Dropbox > GoogleDrive

最终的筛选

从以上的划分, 最后决定如下

  • 针对很隐私很重要的文件(手机的日常照片,视频; 个人的一些重要的有纪念意义的文档), 不论体积和数量, 放Dropbox, 尽量使用它的免费空间. 针对邮件, 邮件附件, 基于Google系列产品构建的文件, 使用GoogleDrive.
  • 针对比较隐私的文件. 对不方便维护的Mac系统备份, 采用自购的移动硬盘, 用Mac的TimeMachine. 对手机, 则使用iPhone的备份到Mac功能. 对工作文件, 比较重要, 往往不方便维护, 是小文件或者中文件, 比如设计用的字体, psd, 图片; 以前早起的没有版本系统的一些没有太大实际意义, 纪念意义更重的代码. 用OneDrive, 如果空间不够, 可以增加容量.
  • 针对比较随意的内容, 比如一些软件备份, 一些电影资源, 一些音乐(ape等高清资源或者一般的mp3) 就用百度云盘, 速度不错, 短期不会倒闭, 而且有算法能对重复内容做识别, 可以免上传.

希望通过这样的划分方式能比较方便又安全的进行个人数据的管理. 如果大家有更好的方案, 也期待分享交流.

一点小广告:

如果大家想用OneDrive而且没有注册过, 可以用这个链接https://onedrive.live.com?invref=031414c742a7d364&invscr=90 进行访问, 这样我也能得到0.5G的奖励^_^

svn迁移到git

本文参考自:Git-与其他系统-迁移到-Git

也建议阅读之前,先看看此文章,本文主要是对里面方法的一个补充和完善,保证可用性

第一步:把之前svn的提交者的信息映射为git需要的

在本地的svn目录,执行以下命令:

svn log ^/ --xml | grep "^<author" | sort -u | perl -pe 's/<author>(.*?)</author>/$1 = /' > users.txt

显而易见,本方法要求主机上安装了grep,sort 和 perl.

最后得到的user.txt 是所有svn提交者的name。

在对应等号后面加上Email地址。

最终变成如下格式:

schacon = Scott Chacon 
selse = Someo Nelse 

第二步:使用svn2git来导入

在一个新的打算放置导入成功之后的git项目的目录(最后也把上一步的users.txt拷贝到此处)

前往github上面的svn2git项目,安装这个工具,能比较方便的进行svn到git的导入

执行以下命令:

svn2git svn://yourdomain.com/your/path/to/svn --username xingwang --verbose --authors users.txt

解释一下几个参数:
--username: 设定你在svn里面的用户名,方便执行svn co
--verbose: debug模式,能够了解svn2git执行了哪些命令,方便出问题的时候调试
--authors: 用来设定提交者信息,也就是上一步生成的users.txt

Nginx 错误[emerg] “server” directive is not allowed here的可能情况

Nginx 错误[emerg] “server” directive is not allowed here的可能情况:检测的配置文件不对

  • 服务器环境:ubuntu 14.04, nginx/1.4.6

  • 执行命令:sudo nginx -t -c /etc/nginx/conf.d/default.conf

  • 命令目的:查看新修改的nginx是否有错误,避免上线导致服务器出错

执行结果:

nginx: [emerg] "server" directive is not allowed here in /etc/nginx/conf.d/default.conf:1
nginx: configuration file /etc/nginx/conf.d/default.conf test failed

default.conf里面的内容:

server {
    listen                      80; 
    server_name                 localhostmanager.com www.shuizhongyueming.com;
    root                        /var/www/www.shuizhongyueming.com;

    location / { 
        index   index.html index.php;
    }   

    # 媒体资源文件
    # TODO: 用一个static.hostmanager.com 之类的域名放置
    location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
         expires      30d;
    }   

    # 前端代码
    # TODO: 用一个fe.hostmanager.com之类的域名放置
    location ~ .*.(js|css)$ {
         expires      1h; 
    }   
}

一开始以为是语法错误,可是复制了官方文档里面的一个简单PHP站点配置之后,还是报同样的错误,所以基本算排除了语法错误

上网Google的结果,大多说的是server的配置应该放在http里面

可是我的default.conf 是在/etc/nginx/nginx.conf 里面,在http模块下include的,不应该有任何的错误才对

最后自己根据网上这些答案猜测,是我进行语法检测的对象有问题。

要检测现有的修改过的Nginx配置是否有错误,不是单单检测那个修改过的扩展的.conf文件。而是不管任何时候,始终都是去检测主文件/etc/nginx/nginx.conf,只有这样,才能顺利的在对应的模块加载扩展的.conf文件。

这样一来保证了配置的前后语境的正确性,二来,这样才是真正的检测(完全和实际运行情况相符)

所以正确的检测修改的Nginx的语法是否错误的命令应该是:sudo nginx -t -c /etc/nginx/nginx.conf,然后一个欣喜的结果就会是:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

希望这个小的发现能帮助到大家。

itunesconnect上传应用图片报Images can’t contain alpha channels or transparencies错误的解决方法

介绍了如果解决在iTunes connect中,上传应用图片,遇到Images can’t contain alpha channels or transparencies问题的解决方法

Images can't contain alpha channels or transparencies

今天给一个已经reject了N多次的APP做再一次的上传和提交。因为一些问题,需要重新上传图片。这算是iTunes Connect更新之后,头一回做图片上传的操作,发现果真方便不少。

首先已有的图片展示速度提升很多,点击图片可以全屏查看,鼠标放图片上会在左上角有个红色的删除按钮。最棒的是上传图片的时候,可以拖进去,而且还是批量的。比老版的点击一次上传一张要方便多了。而且图片上传的速度也是快的惊人。But 图片上传失败了,就像上面那个图片。

stackoverflow上面找到了答案,得使用Photoshop重新生成图片,然后去掉alpha值,也就是透明度。

我的操作流程是这样的:

  • 在Photoshop中打开图片
  • alt+ctrl+shift+s(或者文件=>存储为web所用格式)
  • 去掉透明度复选框的选中
  • 存储

去掉透明度复选框的选中

这样再次生成的图片,就可以顺利的上传到iTunes connect上面了

GitHub帮助-使用Pull Request

本文是翻译的https://help.github.com/articles/using-pull-requests/ 。旨在帮助大家了解GitHub上面如何给别人的仓库提交变更,英文好的同学可以查看上述网址,获取最新的内容

本文是翻译的https://help.github.com/articles/using-pull-requests/ 。旨在帮助大家了解GitHub上面如何给别人的仓库提交变更,英文好的同学可以查看上述网址,获取最新的内容

Pull Request可以让你通知别人,你已经推送了一个修改到GitHub的版本库。在pull request被发送之后,感兴趣的成员可以review这些代码变动,讨论可能需要的修改,甚至在必要的时候在这之后push一些commits

本指南详细描述了从发送一个pull request(假设的),使用各种代码审查工具和管理工具,到最后完成变更的过程。

协同开发模式的快速笔记

在GitHub上面有两种流行的协同开发模式:

Fork & Pull

Fork & Pull模式让任何人都可以fork(复制的意思)一个已经存在的版本库并且提交变更到他们自己fork出来的版本库上,而不需要获得源版本库的访问权限。变更必须通过项目维护者才能放入源版本库。这种模式降低了给新贡献者带来的麻烦,在开源项目非常流行,因为它使人们能够独立工作而不需要前期的协调。

共享版本库模式

共享版本库模式在小团队和组织合作的私人项目中更为普遍。每个人都有push到单一共享版本库或者用来隔离变更的顶级分支的权限。

Pull requests 在 Fork & Pull 模式 中更加有用,因为它提供了一种方法去提醒项目维护者,在他的fork里面有变更. 但是,在共享版本库模式中,他们同样有用,当人们启动代码审查或者在合并到主分支之前讨论所有变更的时候

开始之前

本指南假设您有一个GitHub的帐户 ,你已经Fork了一个的现有版本,并push了您的更改。想要获得关于Fork和推送变更的帮助,请参阅文章——Forking a Repo

启动Pull Request

在下面的例子中,codercat在Fork自Octocat的Spoon-Knife版本库中完成了一些工作,在他的Fork中push了一个commit,并希望有人来审查和合并。

进入到你希望别人Pull变更的版本库中,点击Pull Request按钮。

  1. 切换到您的分支 分支选择下拉
  2. 点击Compare & review按钮 Pull Request 按钮

Pull request可以基于任何分支或者commit发送,但是推荐是从一个顶级分支。这样,在必要的时候,一些跟随的commit可以被push,去更新这个Pull Request。

审查要提交的Pull Request

开始审查之后,你将会进入一个审查页面,在这里你可以概览到所有在你的分支和源版本库的master分支之间的变动。你可以审查在所有commit中的注释,明白哪些文件发生了变动,看到所有在你的分支中的贡献者。
Pull Request 复审页

改变分支范围和目标版本库

默认情况下,Pull Request被认为是基于父版本库的默认分支 。在这种情况下, hubot/Spoon-Knife是contoctocat/Spoon-Knife中Fork出来的。所以这次的Pull Request被假定为基于octocat/Spoon-Knife版本库的master分支。

在绝大多数情况下,默认值将是正确的,但是,如果有任何信息不正确,您可以从下拉列表中更改父版本库和分支。点击顶部的Edit按钮,可以让你换你的头和底座,以及建立各种参考点之间的差别。这里引用可以包括:

  • 添加了tag的release
  • commit的SHA值
  • 分支名称
  • Git的历史标志(如HEAD^1 )
  • 有效的时间引用(如master@{1day} )

欲了解更多信息,请查看our help article on setting up comparisons
Pull Request 选择比较的分支

理解分支范围的最简单的方法是这样的: 基础分支( base branch )是你认为变更应该应用的分支,而头部分支( head branch )是你想被人应用的分支 。

改变基础版本库会导致Pull Request发生时候的通知名单发送变动。所有对基础版本库有push权限的人都会在新的Pull Request产生的时候收到邮件,并且在他们下次登录的时候能够在他们的仪表盘查看该Pull Request。

当您更改分支范围内的任何信息,commit和文件改动的预览区域将更新以显示新的范围。

发送Pull Request

当你准备好提交您的Pull Request,点击Create pull request按钮:
Pull Request 提交

你会被带到一个讨论页面,在这里你可以输入一个标题和说明(可选)。你仍然可以看到,当Pull Request发送时哪些commit将包括在内。

当你你输入好标题和描述,针对commit范围做了必要的自定义,审查了要发送的commit和修改的文件,按Send pull request按钮。
Pull Request 发送按钮

Pull Request会被立即发送。你会被带往一个Pull Request讨论和审核的主页。

在你的Pull Request发送之后,任何push到你的分支的commit会被自动更新上去。如果您需要更多的改变,这尤其有用。

管理Pull Request

所有经由你发送或者审核的Pull Request都可以通过仪表盘的pull request 查看。给自定版本库的Pull Request,对于所有能够访问对应Pull Request页面的人来说,也是可见的。
已有的Pull Request 列表

Pull Request仪表板和版本库的Pull Request列表支持多种筛选和排序控件。用它们来把列表缩小到你感兴趣的Pull Request

审查建议的更改

当您收到一个Pull Request,要做的第一件事就是审查这些建议的更改。Pull Request被紧密地与底层的git仓库集成,所以你可以看到如果Request被接受,哪些commit会被合并:
commit 审核页

您还可以了解所有提交,查看所有文件更改的累计差异。
差异审核页

讨论Pull Request

审查了基本说明,commit,和累积差异后,负责应用更改的人可能有问题或意见。也许是编码风格不匹配项目的指引,或变更缺少单元测试,或者也许一切看起来不错,所有事情都准备就绪。设计这种讨论会面,旨在鼓励和关注这种类型的讨论。
Pull Request 讨论

这种讨论会面从Pull Request的原始标题和描述开始,然后从那里按时间顺序显示额外的活动。任何以下类型的活动,当发生的时候将会被关注:

  • 在Pull Request中的评论。
  • 在Pull Request分支中新提交的commit。
  • 在Pull Request范围内的commit中的存在的文件和行注释。

Pull Request的评论是Markdown语法兼容的,所以你可以嵌入图像,使用预格式化文本块,或者其他Markdown支持的格式。

查看长时间存留的Pull Request

当一个功能或bug修正去了几个月,但从来没有通过或者丢弃,你经常想要仔细看看,是什么阻止这个Pull Request被解决。查看旧的但仍然活跃的Pull Request,可以使得这个工作简化。

您可以从您的版本库的Pull Request页面查看和排序长时间存在的Pull Request。
排序Pull Request

长期存在的Pull Request是至少已经存在了一个多月,并已在过去一个月内有可见活动的。该过滤器将按这样一个排序方式显示那些长期运行的Pull Request:从创作到最新的活动的时间。(完)

grunt-joycss的can’t find node-gd错误的解决方案

解决了在windows下面安装和使用joycss(或者grunt-joycss)时候报gd相关错误的问题

grunt-joycss或者独立的npm的joycss运行在windows下时,经常会报php gd库未安装,或者can’t find node-gd

这个时候npm install node-gd是注定失败的,因为就连作者本身都说了他没法实现在widows下面安装node-gd,而且问题本身不在这,因为joycss是可以调用php的gd库来实现拼图的。

开启php的gd的方法

joycss是通过cli的方式来调用php(也就是命令行的模式),这个和传统的浏览网页时,由apache来调用是不一样的。

把php加入环境变量

找到你安装的php,把php.exe所在文件夹的绝对路径,复制一份,放到计算机->属性->高级系统设置->环境变量->Path(底下的)里,注意用英文的分号(;)来区分别的路径。

这样做是为了能够在命令行里面调用php

查看配置文件地址

可以通过在CMD窗口里面输入 php --ini (php 5.3版本之后支持) 查看

Loaded configuration file: 就是apache调用的php的ini文件的地址

configuration file(php.ini) path: 这个是cli模式下在哪个文件夹下寻找php.ini文件(一般情况下这个目录是没有php.ini文件,这就是很多时候,明明修改了配置文件,但是在命令行下就是不生效的问题)

修改配置文件

  1. 首先是开启GD库

找到extension=php_gd2.dll,把它前面的分号去掉

  1. 修改extension_dir的地址

在某些集成套件的设定里面,extension_dir是相对路径的。

默认情况下,这样的extension_dir也是能正常的在apache调用的时候工作,因为只有一个配置文件,相对路径也没问题。

但是后面是需要把配置文件复制一份到刚刚上一步找到的configuration file(php.ini) path:目录下,所以extension_dir必须改成到ext文件夹的绝对路径,例如:d:/usr/local/php5/ext

  1. 复制配置文件

复制刚刚修改完毕的配置文件,粘贴到configuration file(php.ini) path:指定的目录,一般是:C:windows。然后重命名为php.ini(某些集成套件里面,配置文件可能默认的名字不是php.ini)

重启电脑

试过重启apache,但是对之前的修改貌似没有效果,暂时也不知道是重启哪个服务能让之前的修改生效。所以,重启电脑吧!(如果有别的更好的方法,也欢迎指正)

现在,好好享受joycss!

分享我的vim配置


" Configuration file for vim
set modelines=0     " CVE-2007-2438

" Normally we use vim-extensions. If you want true vi-compatibility
" remove change the following statements
set nocompatible    " Use Vim defaults instead of 100% vi compatibility
set backspace=2     " more powerful backspacing

" Don't write backup file if vim is being called by "crontab -e"
au BufWrite /private/tmp/crontab.* set nowritebackup
" Don't write backup file if vim is being called by "chpass"
au BufWrite /private/etc/pw.* set nowritebackup

" 自动语法高亮
syntax enable 
set background=dark
colorscheme Guardian



" 突出显示当前行
" set cursorline

" 显示行号
set number

" 用空格代替制表符
set expandtab

" 设定 tab 长度为 4
set tabstop=4

" 统一缩进为4
set softtabstop=4

" 自动缩进的宽度
set shiftwidth=4

" 智能自动缩进(这个东西实际用处不大,因为只是针对简单文本的)
" set autoindent

set smartindent

" 让filetype-plugin根据文件类型自动缩进(这个必须要,它会根据文件类型自动配置缩进,插件在安装vim的时候已经装好了)
filetype plugin indent on

" 在行和段开始处使用制表符
set smarttab

"搜索忽略大小写
set ignorecase

"搜索逐字符高亮
set hlsearch
set incsearch

"代码补全
" 关掉智能补全时的预览窗口
" set completeopt=longest,menu
" vim7.3中已经集成了omnicppcomplete了
set omnifunc=omni
" omnicppcomplete配置 关闭兼容模式
set nocp
" 打开文件类型检测,加了这句才可以用智能补全
filetype plugin on
set ofu=syntaxcomplete#Complete
"共享剪贴板
"set clipboard+=unnamed

" 实现 (、[、{、"、'  输入后自动补全右边部分,光标也会位于中间位置
inoremap ( ()i
inoremap [ []i
inoremap { {}i
inoremap < <>i
inoremap " ""i
inoremap ' ''i

" 高亮显示匹配的括号
set showmatch

" 匹配括号高亮的时间(单位是十分之一秒)
set matchtime=1


"保存.vimrc文件后会自动调用新的.vimrc
autocmd! bufwritepost _vimrc source $VIM/_vimrc


" 代码折叠
set foldmethod=marker


" 状态栏显示目前所执行的指令
set showcmd


" 行号和标尺
set number
set ruler
set rulerformat=%15(%c%V %p%%%)


" 设置less文件的高亮
au BufNewFile,BufRead *.less set filetype=less


" 始终显示状态行
set ls=2 
"命令行补全以增强模式运行
set wildmenu 

用package.json来管理NPM里面的依赖包

介绍了一些最近新近知道的使用npm的技巧

很久之前

开发前端项目(基于grunt),每新建一个项目,总是先用npm init来初始化一个package.json,然后就是一遍又一遍的


  npm install grunt-contrib-less --save-dev
  npm install grunt-contrib-concat --save-dev
  npm install grunt-contrib-requirejs --save-dev
  npm install grunt-contrib-uglify --save-dev

在进行版本控制的时候,以git为例,为了让项目组成员能拥有正确的开发环境,得git add node_modules,把里面所有的包都加入版本控制。一提交就是一大tuo,要是添加新的包,或者更新包,其他成员更新的时候,也是一堆。

新的能力 Get!

如果你有个新的项目,还没有下载过任何的npm包,而需要的npm包跟前一个项目差不多。那么,你可以把这个项目里面的package.json拷贝到当前项目根目录。然后npm install,所有的依赖包就会自动的下载完毕了!

现在

一个好的开发项目流程可以是这样:有一份好的前端项目开发模版,里面的目录可能是这样


src/
    css/
    js/
    img/
    less/

dist/
    css/
    js/
    img/
    less/

index.html
index-dev.html

doc/
    xxx.psd

package.json
Gruntfile.js
.gitignore

package.json里面有基本的包依赖

{
  "name": "my-project-name",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-jshint": "~0.6.0",
    "grunt-contrib-nodeunit": "~0.2.0",
    "grunt-contrib-uglify": "~0.2.2"
  }
}

.gitignore里面添加了node_modules/

每次新建项目就可以拷贝这份模版,然后初始化,加入版本库,提交。项目其他成功,更新到本地之后,同样的初始化就可以了