wanderyt的博客

会踢足球的程序猿


  • 首页

  • 归档

  • 标签

  • 搜索

Yarn - New Package Management Tool

发表于 2016-10-13 | 分类于 UI Development , Javascript , npm

今天偶尔看到一篇文章,讲到Facebook新出的一个Package Management Tool:Yarn。

主要的优势就是分析包之间的关联关系,并缓存已下载的内部包依赖。Yarn的实现方法主要有三步。

  1. 分析:分析每个包的内部依赖,并发送请求到registry。
  2. 获取:先从本地的全局缓存目录下查找所有的包,如果没有则进行下载。
  3. 链接:拷贝所有缓存中的包,到项目的node_modules目录下。

Yarn已在Facebook的生成环境中使用,证明其工作的有效性。

$ npm install -g yarn

相关命令:

$ npm install
$ npm install --save <name>

可以替换成:

$ yarn
$ yarn add <name>

我也在本地试验了一下,找了一个最基本的项目,这是项目中目前的包依赖,package.json文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
// ...
"devDependencies": {
"express": "^4.14.0",
"grunt": "^1.0.1",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-requirejs": "^1.0.0",
"grunt-contrib-uglify": "^2.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-express-server": "^0.5.3",
"grunt-nodemon": "^0.4.2"
}
}

总共只有这几个包依赖,但是如果使用npm进行安装。

$ npm install

这一条命令总共执行了3分钟。但如果换成yarn命令。

$ yarn

这一条命令分析出了380+个包依赖,优化后总共只执行了不到80秒。速度提升一倍以上,确实是很实用。

以后继续分析yarn的其他功能。

最后感叹一下,Facebook真是的前端技术领域里的担当啊。

Git Flow With Branch Sync

发表于 2016-07-22 | 分类于 Git

During the collaborative development, it is easy to find out that the local branch of your own repo is out-dated with the branch in remote repo.

For example, there is a repo named remote/repo. Then you fork it within your own github as you/repo.

To keep the develop branch in you/repo with the develop in remote/repo, the following steps may be needed.

Checkout

Checkout two develop branches.

$ git checkout -b remote-develop remote/develop
$ git checkout -b develop you/develop

Merge

If there are commits after the lastest sync, the remote-develop will be ahead of develop with several changes. Then you need to keep the develop with remote-develop.

$ git checkout develop
$ git merge remote-develop

Then you have updated the local branch develop with lastest code. Finally the update for you/repo should be made to keep the two repos sync.

$ git push you develop

Git Checkout With Updating Paths Error

发表于 2016-07-11 | 分类于 Git

During co-development process, after we fork a repository, we always want to keep up our own repo updated with the original repo, then when I want to checkout a branch that tracking a branch on original remote, an error occurs.

$ git remote -v
origin  git@github.corp.ebay.com:yuren/app-browse.git (fetch)
origin  git@github.corp.ebay.com:yuren/app-browse.git (push)
upstream    git@github.corp.ebay.com:Stubhub/app-browse.git (fetch)
upstream    git@github.corp.ebay.com:Stubhub/app-browse.git (push)

$ git checkout -B develop upstream/develop
fatal: Cannot update paths and switch to branch 'develop' at the same time.
Did you intend to checkout 'upstream' which can not be resolved as commit?

Here listed a correct answer from stackoverflow. It works for me.

$ git remote update
$ git checkout -B develop upstream/develop

Deep Clone in Javascript Object

发表于 2016-05-27 | 分类于 Javascript

Continue with the last post, issue about deep clone in Javascript object.

Here is a test code snippet for shallow clone or deep clone.

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* Test clone for array
*/
var cloneArray = function(element) {
var result = [];
for (var i in element) {
result.push(element[i]);
}
return result;
};

var deepCloneArray = function(element) {
var result = [];
for (var i in element) {
if (typeof element[i] == "object") {
result.push(deepCloneArray(element[i]));
} else {
result.push(element[i]);
}
}
return result;
};

/**
* Test clone for object
*/
var cloneObject = function(element) {
var result = {};
for (var i in element) {
result[i] = element[i];
}
return result;
};

var deepCloneObject = function(element) {
var result = {}; // Trap 1
for (var i in element) {
if (typeof element[i] == "object") {
result[i] = deepCloneObject(element[i]);
} else {
result[i] = element[i];
}
}
return result;
};

For testing array code part, I am really amazed that the cloned array is independent from the original array.

Maybe there is no deep or shallow clone difference in Javascript array objects.

However, for testing object code part, the difference does exist.

Trap 1

In this place, a type check should be added. This version is simplified.

Among objects, there are mainly three sub types that need attention.

1
2
3
4
5
6
7
typeof [1,2,3]; // object
typeof {}; // object
typeof function() {}; // function

[1,2,3] instanceof Array; // true
(function() {}) instanceof Function; // true
Function instanceof Object; // true

Therefore, for trap 1 case, an instanceof check should be added, to decide whether the result structure should be array or object.

Subset Algorithm Solution

发表于 2016-05-26 | 分类于 Algorithm

Recently I applied for the UI engineer position, and in second Skype interview, the interviewee posted an algorithm question.

Q1:
Given an array of integers, print all subsets of size k
E.g. A = [1 2 4 2], printSubsets(A, 1) should output
1
2
4
printSubsets(A, 2) should output
1 2
1 4
2 4
printSubsets(A, 3) should output
1 2 4
阅读全文 »

ES6 Learning - Class

发表于 2016-04-18 | 分类于 UI Development

基本语法

概述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ES5
function Point(x,y){
this.x = x;
this.y = y;
}

Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
}

// ES6
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}

toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}

注意,不用加function关键字,并且方法之间不需要加分号。

类的数据类型就是函数,类本身就指向构造函数。

1
2
typeof Point // "function"
Point === Point.prototype.constructor // true

类的实例上调用方法,其实就是调用原型上的方法。

1
2
var point = new Point();
point.constructor = Point.prototype.constructor; // true

类的内部定义的所有方法,都是不可枚举的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Point {
constructor(x, y) {
// ...
}

toString() {
// ...
}
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

constructor方法

通过new命令生成对象实例时,自动调用该方法。默认返回实例对象(this),但也可以指定返回其他对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class FooTestString {
constructor() {
return 'Test String';
}
}

var fooTestString = new FooTestString();
fooTestString instanceof FooTestString; // true

class FooTestNewString {
constructor() {
return new String('Test String');
}
}

var fooTestNewString = new FooTestNewString();
fooTestNewString instanceof FooTestNewString; // false
fooTestNewString instanceof String; // true

Linux下安装Node和Git

发表于 2016-04-15 | 分类于 UI Development

还是最近UI Club的小项目。对于我这种linux白痴来说,需要在远程的Linux安装Node环境和Git环境,今天算是上了满满一堂课,感谢Guoliang老师的耐心帮忙。

首先还是要安装一些最基本的应用。

ssh远程命令行操作的神器:xterm。

操作文件系统的应用:winscp。

安装nodejs

首先去Node官网下载Linux版本的安装文件,下载下来是一个tar.xz文件。这种文件就是Linux下面的压缩包后缀。

使用winscp将安装包拖拽到远程目录中,我放到的是/root/Downloads下。之后使用解压缩命令。

$ tar xvfJ [node-install-file.tar.xz] -C [/tmp/node]

命令的含义是将压缩包解压缩到/tmp/node文件夹下。

之后将node文件夹移动到用户的目录下。

$ sudo su -c "chown -R root:root /tmp/node*"
$ sudo mv /tmp/node* /usr/local/node

这里可以任意指定node的安装目录,我是放到了/usr/local/node下。

设置node环境变量

这时访问node命令发现不会识别,主要是因为环境命令还没有设置。

设置环境命令有多个地方。

可以在顶级目录下的/etc/bash.bashrc文件中追加PATH的定义。这种方式会使所有的用户都获得这种命令的执行权。

在当前用户下的.bashrc文件中追加PATH的定义。这种方式只会让当前用户获得这种命令的执行权。我选择的是这一种方法。

首先查看当前环境变量的定义。

$ cd /root
$ cat .bashrc

可以看到里面的定义。此时利用vim编辑器编辑文件,追加PATH的定义。

$ vi .bashrc

进入编辑器模式,填写内容:

export PATH="$PATH:[node-directory]/bin"

这里将node的安装目录下的bin文件夹设置进来。加两个vim的命令。

注意,其一,Linux的环境变量是通过冒号分隔的;其二,安装目录路径一定要是绝对路径。

ESC: 从编辑模式切换到命令模式
a: 当前光标位置追加文本
wq: 保存文件并退出

保存时可能会遇到readonly option is set的错误。这时输入命令

:set noreadonly

之后再输入wq就可以保存退出了。

这时重新开一个session,就能使用node命令和npm命令了。

补充一点,cd ~会直接进入当前用户的文件夹目录。所以cnpvg50830120:/和cnpvg50830120:~的区别就在于,前者是绝对路径,是顶级目录,后者是当前用户所在的文件夹目录。

安装Git

首先查看当前Linux的版本信息再决定用哪个安装。

$ cat /etc/SuSE-release

我的那个server是SUSE Linux Enterprise 11 SP3,所以用zypper命令安装Git。

$ zypper search git // 搜索当前REPOSITORY的安装列表里是否有git安装文件
$ zypper install git

REPOSITORY是负责定义安装那些工具的来源。这些来源可以通过命令来看。

$ zypper lr // 列出所有的源
$ zypper ar [options] <URI> <alias> // 添加源

定义源其实就是定义一些安装时下载的来源,所以使用zypper install [name]时需要联网。

$ curl www.baidu.com // 检查是否能联网访问baidu.com

其他的一些命令。

$ zypper mr // 删除源
$ zypper rr // 导入导出源

安装好之后,就可以使用Git了。

创建项目

在服务器上新建一个项目目录,用于clone项目代码。

$ mkdir [WORKSPACE_PATH/PROJECT_NAME]
$ git clone [GIT_URL] [PROJECT_PATH]

这时可能会报错,说Could not read from remote repository。

这个错有可能是因为当前机器上的ssh key没设定或者没有添加到Github账号中做关联。

$ ssh-keygen -t rsa -C "USER_NAME" // 注意。USER_NAME为Github用户名

之后可能会问.ssh要生成到哪个文件夹下,我全部使用默认。

生成ssh key之后,将id_rsa.pub文件内容添加到Github账号中。之后就可以正常的clone git repository。

每次更新代码时,执行git命令。

$ cd [PROJECT_PATH]
$ git fetch origin
$ git rebase [BRANCH_NAME]

ES6 Learning - 异步操作 & Async函数

发表于 2016-04-13 | 分类于 UI Development

ES6之前,异步编程的方法大概四种。

回调函数

事件监听

发布 / 订阅

Promise对象

基本概念

异步

一个任务分成几段之后,可以先执行第一段,然后转而执行其他任务,等准备好之后再执行第二段。

同步

一个任务分成几段之后,段与段之间不能插入其他任务,必须连续执行,这段时间其他任务只能干等着。

回调函数

任务分成几段之后,第一段中的function定义了第二段函数的参数,这时第二个参数就是回调函数。

Promise

new Promise().then().then()...
阅读全文 »

Git Url HTTPS SSH 区别

发表于 2016-04-12 | 分类于 Git

继续昨天的搭环境步骤。建好一个repository之后,我是把项目的ssh url发出来给的大家,这其中遇到了一些问题。

他人无法clone

开发人员使用ssh的url进行clone的时候,发现会报错,然后换成https的url就可以。

网上查了下发现,使用https url克隆对初学者来说会比较方便,复制https url然后到git Bash里面直接用clone命令克隆到本地就好了,但是每次fetch和push代码都需要输入账号和密码,这也是https方式的麻烦之处。而使用SSH url克隆却需要在克隆之前先配置和添加好SSH key,因此,如果你想要使用SSH url克隆的话,你必须是这个项目的拥有者。否则你是无法添加SSH key的,另外ssh默认是每次fetch和push代码都不需要输入账号和密码,如果你想要每次都输入账号密码才能进行fetch和push也可以另外进行设置。

使用https的时候可能会遇到unable to get local issuer certificate错误,这时需要设置

git config --global http.sslVerify false

stackoverflow对应问题解答。

他人无法提交代码

这个有多种解决方案。

将他人的公钥加到项目的公钥中

fork + pull request

这种方式感觉不太适合协同开发

设置Collaborators

Git Fork Sync

发表于 2016-04-08 | 分类于 Git

今天在工作中,想在Github上建立一个repository供大家协同开发,有人提出要可以进行code review,之前在项目中用到过Gerrit,但是这种小型项目感觉用Gerrit有点大材小用。

总之,先尝试了一下Fork的使用。

Fork

USERA在Github上新建一个repository,之后USERB去Fork这个repository。然后clone到本地。

$ git clone git@github.wdf.sap.corp:USERB/RepositoryName.git

这里用的是ssh url。

Commit

Clone下来之后,USERB可以进行编辑,比如新建一个err.md文件,并填写一些内容。

$ git add filename
$ git commit

Push

之后,USERB进行push操作,注意,此时push是到了USERB的repository。

如果想要让项目的原作者注意到,USERB需要发起一个pull request。

Pull Request

创建一个pull request,base是远程的USERA的repository,head是USERB的repository。

填写comment,这时就可以等待原作者的同意并并入到原作者的项目中去了。

Keep Synced

此时大家可能会注意到一个问题,我们如何保持我们fork出来的项目和原项目同步呢?

$ git fetch [origin]

这条命令没有错,但是只是从USERB的repository的远程来拉代码,并不能解决同步问题。

这时我们需要设定一个新的remote源。

$ git remote -v

查看当前的remote。

origin  git@github.wdf.sap.corp:USERB/RepositoryName.git (fetch)
origin  git@github.wdf.sap.corp:USERB/RepositoryName.git (push)

新加一个新的remote。

$ git remote add upstream git@github.wdf.sap.corp:USERA/RepositoryName.git

此时我们看到,remote变成了四个。

origin  git@github.wdf.sap.corp:USERB/RepositoryName.git (fetch)
origin  git@github.wdf.sap.corp:USERB/RepositoryName.git (push)
upstream  git@github.wdf.sap.corp:USERA/RepositoryName.git (fetch)
upstream  git@github.wdf.sap.corp:USERA/RepositoryName.git (push)

之后,我们如果要保持代码同步的话,可以直接输入命令。

$ git fetch upstream

文献

参考文章: Fork and Pull, Fork a Repo

123…5
wanderyt

wanderyt

wanderyt Blog

50 日志
12 分类
27 标签
RSS
github weibo twitter
© 2015 - 2019 wanderyt
由 Hexo 强力驱动
主题 - NexT.Muse