海阔天空的云

我们在自己的世界里独自狂欢

0%

1.线程的问题

2.各个方法优先级的问题

需要知道宏任务,微任务的概念。
process.nextTick()

3.对event loop的理解

事件循环机制可以让程序来执行非阻塞的io操作。虽然js语言本身是单线程的,把一些任务转移给操作系统内核来完成。

因为大多数现代操作系统内核是多线程的,因此他们能够控制多个操作在后台执行。当这些操作中有一个操作完成之后,这个内核就会告诉nodejs,这个操作已经完成,这个时候,callback函数就会被添加到队列中,等待执行。

┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘

从上面的流程图可以看出,timer的顺序是要高于poll的

各个阶段

各个阶段:

timer=>pending callback=>

pending callbacks:

poll: callbacks池,一些callback放到这个队列中,等待执行,setTimeout的时间最少是设定的时间,因为还有从队列中取出来执行的时间。

check: setImediate 的callback在这里执行

close callback:一些关闭callback在这里执行

理解io操作

我们编写的程序除了自身会定义一些数据信息外,经常还会引用外界的数据,或是将自身的数据发送到外界。比如,我们编写的程序想读取一个文本文件,又或者我们想将程序中的某些数据写入到一个文件中。这时我们就要使用输入与输出。

读取文件,我们可以使用读取文件的方法。比如fs.readFile(‘/path/to/file’, callback);

堆内存 栈内存

二叉树来进行维护

堆是一种数据结构,是利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆

堆内存 栈内存
https://juejin.im/entry/589c29a9b123db16a3c18adf

与其他语言不通,JS的引用数据类型,比如数组Array,它们值的大小是不固定的。引用数据类型的值是保存在堆内存中的对象。JavaScript不允许直接访问堆内存中的位置,因此我们不能直接操作对象的堆内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用类型的值都是按引用访问的。这里的引用,我们可以粗浅地理解为保存在栈内存中的一个地址,该地址与堆内存的实际值相关联。

二叉树

在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个叶子节点,至多有2k-1个节

setTimeout

解释:setTimeout/setInterval 的第二个参数取值范围是:[1, 2^31 - 1],如果超过这个范围则会初始化为 1,即 setTimeout(fn, 0) === setTimeout(fn, 1)。

setTimeout 的第二个参数只是说的,callback什么时候放到事件循环的队列中去。

为什么timeout的时间不准

setTimeout 的第二个参数只是说的,callback什么时候放到事件循环的队列中去。

To reduce the load (and associated battery usage) from background tabs, timeouts are throttled to firing no more often than once per second (1000 ms) in inactive tabs.

如果是非活跃标签页,那么它每1000ms会去检查一下callback执行。这个时候也是会出现时间不准的情况。

dom.min_background_timeout_value

For Firefox in particular, you can change the dom.min_background_timeout_value preference in about:config to a number of your liking in the profile that you use to run the tests. I wouldn’t suggest doing that in your default browsing profile, though: the reason for the high clamp is that it cuts down on web sites in background tabs chewing up CPU updating silly tickers and the like.

Node uses libuv which a cross-platform abstraction layer for lower level system things like file-system

In Node, if you specify setTimeout(callback, 1) then it will be executed one millisecond later (assuming the system doesn’t delay it due to be overwhelmed). In browsers, the minimum time will be 4 milliseconds as specified by the HTML5 spec:

https://stackoverflow.com/questions/7221504/does-node-js-enforce-a-minimum-delay-for-settimeout

宏任务,微任务

先执行同步任务,再执行微任务,最后执行宏任务。
宏任务有 setTimeout, setInerval, setImmerdate等,优先级不能确定

微任务 process.nextTick , promise, 按照优先级排列

当然是为了和浏览器更加趋同。
了解浏览器的eventloop可能就知道,浏览器的宏任务队列执行了一个,就会执行微任务。
简单的说,可以把浏览器的宏任务和node10的timers比较,就是node10只有全部执行了timers阶段队列的全部任务才执行微任务队列,而浏览器只要执行了一个宏任务就会执行微任务队列。
现在node11在timer阶段的setTimeout,setInterval…和在check阶段的immediate都在node11里面都修改为一旦执行一个阶段里的一个任务就立刻执行微任务队列。
最后
所以在生产环境建议还是不要特意的去利用node和浏览器不同的一些特性。即使是node和浏览器相同的特性,但规范没确定的一些特性,也建议小心使用。否则一次小小的node升级可能就会造成一次线上事故,而不只是啪啪打脸这么简单了。

作者:zy445566
链接:https://juejin.im/post/5c3e8d90f265da614274218a
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

异步意味着任务不会阻塞,比如,如果我要下载一个比较忙的网络资源,我的程序不需要一直等待下载完成,它可以在等待下载时继续做其他事情。这与并行执行多个操作不同。 其实还是应用上了多线程,对于js语言而言,等于js的主线程上,再等待响应,去做了其他的事情。而系统的其他线程,则再处理相应。这是从系统层面来看这个问题,比如读取某个文件的操作,其实也是有两个线程,一个线程是js主线程,另一个线程是系统上读取文件的线程。

参考资料

https://juejin.im/post/5c3d8956e51d4511dc72c200

https://zhuanlan.zhihu.com/p/34182184

https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
https://juejin.im/post/5c3d8956e51d4511dc72c200

2019年初,由于公司裁员,我成为了公司里的唯一一个互联网程序员,即负责与线上商城有关的所有维护和开发事宜。这样的一段经历,在我看来,比较有趣,因为我一直想尝试,看看自己是否有能力做到一个人维护开发一个系统。事后证明,我也的确做到了一部分,至于为什么说只有一部分,听我慢慢道来。

工作

由于只有我一个人,我的工作包括了前端开发,后端开发,运维,以及与业务人员沟通需求等事项。对当时的我来说,已经在这家公司从事了两年开发工作,其实前端开发和后端开发已经轻车熟路,相比之下,我对运维这一块很陌生,也想借此机会,了解一下。这样,我也就能够对整个互联网产品的开发维护有个全面的了解了。我当时是有这样的考虑的,但是后来发现,其实更多时候,我其实是把这个项目以前从未接触过的边边角角的业务和技术都拎出来晒了晒,以至于,后来很多问题,我都不得不通过看代码,了解其业务实现。也让我对这个系统的后端服务有了更加全面的了解。

开发

我有两个月的时间,来开发一个服务。也就是我之前提到的https://www.jianshu.com/p/bd2090b7140e ,没有人监督,我自己也不急,考虑问题也考虑得很全面,另外,基本上每天的工作状态处于半天开发,半天维护的状态。因此从时间跨度上来看,开发了很长的时间。这两个月,现在想来其实是蛮享受的,我也挑战了一把独立开发,我曾经以为我自己没有能力独立开发,但是后来发现,通过一步一步走,也是能够做到的。

维护

除了开发之外,每天还有一项任务就是系统的维护。我在最初做这件事情的时候,经常会忘记。因此,就在我自己的手机日历上加了提醒,每个工作日的早上九点半,查看系统的任务队列处理情况以及日志报错情况。这个日历提醒直到最近,才被我去掉。有时候,因为有一些任务队列的错误,每天都要花费一些时间来处理这些事情。也因为这些错误,又总是能够发现系统代码上的一些问题,这样也就能够及时改正。

我印象很深,又一个任务队列的任务,

技术上

技术上,以前从来没有动过的自有后台框架,由于要了解其部署过程,也有了一些深入的了解。

这五个月的时间,其实还是学到了很多。但更多的并不是单纯的理论知识。更多的是,如何跟周遭的形形色色的人打交道,业务人员,需要对接的技术人员,不懂技术的领导,别的业务部门的领导等等。当然除此之外,还有,我前面提到的对整个互联网线上服务的全方面的了解和认知。

我其实是身心俱疲的,在这几个月的时间里,我看着身边熟悉的同事一个个离开,公司的经营不景气,于是开始裁员。虽然是裁员,可是也裁不到我这里,毕竟我已经是那个only one了 。然而,对于其他的业务部门的同事来说,他们肩上的担子更重了。离职了很多人,离职的交接工作很匆忙,于是原本早就教给过这些人的系统使用,又要重新再教一遍,对我来讲,实在是不情愿。当然,偶尔也会情愿,比如写了很久的代码,已经累了的时候,如果恰好有个业务部门的同事过来问问题,我就当是休息休息,耐心给她解答了。

但是,毕竟身兼数任,我明显感觉自己做的太多。却每一件都做得不足够好。

不再一个人

一个人的状态持续了两个半月的时间,之后,由于公司的“战略”,需要“紧急”开发一个项目,我经过了评估,认为我自己一个人无法在规定的时限内,完成开发。于是就有了大概半个多月的招聘,我也当了一把面试官,面试了五六个人选,最后入职的那位同事,也是通过我的面试才进入这家公司的。

然而,人手虽然多了,但是却感觉工作量,较之前两个月有了大幅的增长,在前两个月,我没有加过班,但是自从这位新同事入职之后,我们也会因为赶工期而加班,这并不是一个好事,尤其是当我正与女朋友热恋的时候。也就是在这个时候,我辞职的意念越来越强烈。

疲惫

公司处在“危险期”,于是又给人一种乱弹琴的感觉。有一次,我“有幸”参与了一场公司老总都参与的会议。会议的主要内容是谈论某个项目是否有价值做,以及怎么做的问题。在这次会议上,我明显感受到了老板的强势。虽然,偶尔也有人提出不同的看法,但是大致上,还是老板说啥,下属们听啥。老板明明是做实体经济起家的人,却在o2o上指手画脚,很多的想法,给人的感觉甚至是自己想到了一个点子,于是拼命地群策群力,给这个点子找出几个值得做的理由。而不是,因为有那么几个合理的理由,而去做这样一个事情。

我从来也不看好这个项目,做起来也当然觉得无聊。我细数了一下,在此之前,做过的很多项目或功能都已经荒废掉,没人用了。我开始质疑我自己的工作,我的付出最后得到了什么。当然,我最质疑的其实是这个公司的运营策略和方针。牺牲了那么多的人力物力财力,最后却统统成了空耗,白白浪费掉了。

那个项目进入测试阶段,我提出了离职。而在提出之后不久,却突然被告知,公司大领导决定,上面的项目暂时搁浅,集中精力去做另外一个新的项目。而那个新的项目,又是一个充满槽点的项目。这个公司里,没有人懂互联网。就像是以前看过的那个段子,人人都是产品经理,人人都想设计互联网产品,但是哪里是那么容易的。这个公司大老板,给我一种强烈的外行领导内行的感觉。其实在我看来,外行不是不能领导内行,问题在于外行应该给予内行足够的空间,而不是四处指手画脚。就像是以前听到的一个说法,领导的作用是用人,让人做事。而不是指手画脚,当提线木偶的提线人。从这个案例,我觉得我有些懂得为何传统行业做不好互联网了。如果都是外行领导内行,的确会很困难。

我想起了19年年初的那场年会,年会的节目并不精彩,看得人昏昏欲睡。但又因为这官僚的作风,不能离开年会的现场,只能够继续看着这鸡肋的年会。在年会即将结束的时候,大boss上台,跟公司的中层领导们一起合唱李克勤的《红日》,并且口中说着一日公司不上市,一年的年会结束就要唱《红日》,要把《红日》唱到公司上市。她的话,让我毛骨悚然,让我之后每次听到《红日》,就想起这位董明珠式的女boss。

一个公司如果长期陷入内耗之中,我不认为它会走得长远。当然,它可以因为财大气粗,不断地去试错。但是这个试错的过程,对于员工来讲,是会很疲惫的。如果有足够的物质精神奖励,当然还好,否则,有能力的员工当然会选择飞走了呀。

离职

在我离职前,仅仅是因为觉得续费腾讯云,需要在公司的帐目上走一个流程,略显繁琐,加之,公司的战略从不再重视自有商城的研发和维护,于是经过几个中层领导的讨论,决定不再为腾讯云续费。原本为微商城和app做的静态资源云托管,也就不能再继续用了。这也就意味着,我在最早的一个人开发系统的两个月内所作的工作又白费了。对于公司而言当然是白费了,对于我个人而言,当然还是增长了一些技术知识和经验的。而如果再仔细想想,由于我在这家单位的过去两年所做的主要工作就是移动端自有商城的开发和维护,则我过去两年的工作,也都被所谓的“公司战略”抹杀了。当然,如果我继续留在这家公司,也是能够有所作为的,只不过那个工作就是与第三方商城的对接及相关业务,这的确对我没什么挑战性,我也不打算如此。对我来说,老的项目宣告结束,但毕竟学到了很多知识。有些放到了脑子里,有的放到了文字里,总之,都有收获。

总结

一个人来维护开发一个系统可以吗?当然可以,但是我开发维护的是前人们用七八年时间积累下来的代码量数万行的项目,其实维护起来也并不容易。虽然也有一些文档,但文档上讲的比较概括,之前的领导推崇代码即文档,于是有些业务逻辑经常要去看代码实现,才能知道,业务实现。另外,还要和形形色色的人打交道,当我意识到我有能力应付这些人之后,就不想再打交道了。同理,当我知道,我自己有能力一个人开发维护这个系统之后,我就不想再继续了。为什么呢?因为觉得很累,而且性价比很低。

/etc/apt/sources.list

https://blog.huihut.com/2017/08/25/LinuxInstallConfigShadowsocksClient/

deb https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse

转载自:http://www.ti6.net/wangzhanjishu/2406.html

在使用vim编辑器的时候,有时候编辑一个文件,而文件内容比较多,如果需要快速清空整个文件,可以使用一下命令: 在命令模式下,首先执行  gg 这里是跳至文件首行 再执行:dG 这样就清空了整个文件! 还有一种方法就要退出VIM,然后使用echo >> file ,这样也能快速清空文件内容,当然你也可以删除了这个文件再新建一个就是了。

https://github.com/honovation/ljmall/issues/843

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC65Gt/3HyHe1RdL0MQBUrAh6YfR4HlXABDzN4+bJJolIHIP9A+iWRctjw5ny8OlpFLbBrBRzlCmBg5VzqEYtg4ZKLsyMsSm1944NK/ygS1Zj3PtrU93XGW+G5ItxmjhfocWS1FJJ6NtzppFE4tmkIaL32TJEZDu/jMYUu0C81s3DhZwaQNv3pzqJG3N7aeOD1RpF1aHn3FnjhbnGmZ4GNN71jyKjZQES+mGZTmVGmTde7deuc+OUM6P1ECEKzntTZJZDo7iqeoaLqweXbsI5Or1hTT4zIddkL1OnOsnb6FR/92PfHNn3lcoN1UFpG+8vOHOqT2kcVZu7NGZFwgC/5rxRhx4bHqGHnIH+zuKNihVE70zu8uiHi/n0T0+vLlTUBog8YyN5HsnbQCKI0sfMsQ7yq9vlyP/zE2RErwN8YGzqU3EvZpFVxr5KDGbZ4TazBtyTvWEs+ru1iZXy0qk+y0C3xKKF8W7h9T8ykIvASY1XfffRYQKZ+NkdxKqkl/Ioq7Z32MslWW2t8Xc/6MgeII9CyynB68FqEifC0ulc3JYkAcKAuSoT0PpscrCF2OfF3xaCUVxRxhCDh4xIV1NdWfhC+jaTfDuVZszjbciJ/VW8aG3QZtxPUjfjskgkf8DrpKwqJmECCl9+A5277hJGQxPyFGHQ4JfWgUZFKfc+NlbQ== zhangolve@gmail.com

~/.ssh/id_rsa.pub

https://leihungjyu.com/post/ubuntu-install-shadowsocks.html

https://app.yinxiang.com/shard/s23/nl/5948926/4389aa9f-6f9c-479f-abd2-3b1917926db0/

https://blog.csdn.net/fx_yzjy101/article/details/80243710

https://blog.csdn.net/timo1160139211/article/details/69948540

https://blog.csdn.net/CSDNones/article/details/48917219

https://blog.csdn.net/u014044812/article/details/78727496 pycharm破解版

问题

问题大概出在18年的双十二期间,由于电商运营团队在做活动的时候,在几个活动页面展示了好几张特别大的图片(大概有800k-1M大小的样子), 致使用户在实际浏览过程中,体验并不是很好。而如果只是普通用户体验不好,也就罢了,偏偏那几天大BOSS关注起来了app,于是问起缘由来,一级一级问过来,问到了我这里。

我当然很明白这里面的问题所在,说白了就是由于你网站上的媒体资源加载太慢了,直接造成了用户体验差。而为什么你网站的媒体资源加载慢呢?那是因为你选择了在自有机房来托管这些媒体资源数据。而这些自有机房,在网络连接速度、稳定性等方面都与专业的云服务商没法比,这就间接导致了问题的产生。

选型

有了问题,就要有对应的策略。我于是首先负责了云存储的选型,当时面临的选择包括七牛云存储,腾讯云存储,阿里云储存这几家。当时与老大商量过,认为作为一款一多半流量来自于微信平台的app,当然还是应该选择一款腾讯旗下的云存储服务了,他对此表示赞同。但还是应该考虑价格因素,经过简单的计算,发现三家在价格上没有差多少。于是选型并不费事,直接就选用了腾讯云存储。

然而,我还需要根据我的选型,去做一个使用这些新服务的费用评估。这个费用评估报告,也会交给上级领导,最后由他们来拍板,是否使用腾讯云储存服务来作为媒体资源的提供者。

一切顺利,我的选型报告给领导看后,认为这个方案是可行的。一个预期的结果是,通过使用腾讯云存储方案,能够使app上的图片加载速度快将近10倍,这样的好事,为什么不做?

技术方案

摸着石头过河

我自己决定了技术方案,这个技术方案的核心是摸着石头过河。因为在当前的技术栈中,还从来没有使用过云存储,我们谁也不知道上云会有哪些风险,会产生多少费用,即便是有一些评估,但毕竟难以保证准确。

既然是摸着石头过河,我的第一步是先在app上做一个完全新的功能出来,这个新功能一定要用上云存储。这样做有几点好处,其一,数据是完全新的,没有任何历史数据,不用额外去做数据的迁移工作。其二,在做新功能的期间,也能够熟悉了解云存储接口和使用。

我选中了订单的评价功能的改进,来作为我使用腾讯云的第一步。由于历史的原因,以往的订单评价功能,只能给出文字评价以及好中差评,并不能带图片评价。之前,已经有业务部门的同事要求,希望能够实现带图评价。于是正好借助这个功能,练练手。事后来看,我这个思路非常好,这个功能做好后没多久,app所有的可用资源就都以腾讯云存储的数据方式展现了。

在这期间,由于后端语言使用的是python,因此直接参考腾讯云存储的python sdk文档 是很快速高效的学习方法。通过简单的测试,可以很方便地对接口进行熟悉。

技术细节

本地数据和远程数据

从一开始我就不想完全放弃本地数据,也就是说,即便是我将所有的本地数据都迁移到了云上。我还是要在本地进行一次备份。数据的存储,删除,更新等操作,一定是先在本地完成,再同步到云上。这个同步的过程,为了快速,并不是说再执行一次迁移数据的脚本,而是说,将原有的操作,在云上再重新执行一遍。而实际客户端读取资源文件时,还是直接拉取云上的资源,而无须去获取本地资源。这里要再多说两句,最初我为了以防万一,写的读取资源的方法,原理是如果云上没有这个资源,就去读取本地资源,但是经过实际测试,发现判断云上是否含有某个资源的方法(get_qcloud_object)执行效率太低了,考虑到我当时已经将所有的数据完全进行了迁移,并且保证本地所有的操作,也会同步到云上,因此我可以放心地拼接一个可用的云存储链接,来作为我的图片资源地址来使用。这样以来,整个读取速度就上去了一大截。当然这样做还有一个好处,也就是容灾,我看到前不久,阿里云的北京机房还出了乱子,导致很多app处于不可用状态。我这个方案,当然能够很好地解决这个问题,一旦腾讯云上的资源处于不可访问的状态,我也可以快速地进行部署,然后将资源读取从腾讯云切换到本地机房服务器。

说到这里,其实已经很明白了。其实我的核心方法,只有三个。一个是上传数据的,用到的sdk里面的方法是client.put_object这个方法,另外一个是删除数据,用到的sdk里面的方法是client.delete_object,还有一个则是展示资源的方法,这个方法是完全自己写的,其原理也不过是将云上的资源url拼接好。

本地bucket与远程bucket

在实现腾讯云存储的时候,有一个bucket的概念。其实按照我对于bucket的理解,就是跟他的中文解释一样,是一个篮子。这个篮子里面,什么东西都可以往里面装。在我最初的设计中,我考虑到要创建一个bucket的时候,想到了直接创建一个名叫commentbucket来存放商品评价图片。之所以这么做,也是因为我在本地也是想要创建一个commentbucket,但是后来发现不能简单地将本地bucket与远程bucket一一映射。

这主要也是从两个方面来考虑。第一是数据的迁移,数据迁移的时候,其中一个配置项就是bucket的名字,这个时候如果我将本地20几个bucket一一迁移,就会显得很麻烦,每次都要修改配置文件,也要上传好多次。所以这个时候我开始考虑将原来的bucket放到下一级去处理。这有点像是苏联的成立,原来的共和国本身也是国家,但是我让他成为苏联的加盟共和国,这样就能够方便管理。同样的道理,我这里只要对象存储上创建一个bucket,由它来作为‘苏联’。这样就能够让我的数据迁移工作更简单。

方便的还不只是数据迁移,由于在腾讯云的对象存储中,每个bucket需要单独配置。比如,跨域访问CORS设置,防盗链设置,回源设置,是否开启CDN设置等,这些操作我们不能通过API来完成,必须要通过工程师手动配置。而如果有多个bucket的话,那么配置起来就会很麻烦。

而我最后虽然建立了一个苏联,但是也只不过是多写了两行代码,将原来上传资源,删除资源,展示资源的方法又修改了一下,重新做了映射。一起都非常简单,就能够解决我的难题。

当然,我们也是需要考虑每个bucket的最大存储空间和存储资源数量,我后来调查了一下。发现我的数据量,完全可以将原来的多个bucket合并成一个,而无需担心这个问题。

迁移数据

迁移数据乍一看是个麻烦事,我开始有几点考虑。一是整个bucket的数据量,达到了几十GB。当时考虑如果在网络情况不好的情况下,一天的时间也未必能够完成数据的全部迁移。有这个担忧并不是毫无道理,我最先想到的其实是当前用迅雷下片的体验,几个G的资源都要下载几个小时,更不要说是几十GB的大量碎片文件了。但是后来发现,我本地网速还不错,上传的速度够快,至少是比我想象中要快。我的第二点考虑,虽然数据迁移速度很快,但是由于在迁移工作开展之前,并没有对哪些数据需要迁移进行分析,致使有很长一段时间,我都看着terminal窗口中在上传一些日志文件、发票文件。而这些文件,用户是很少有感知的,其实也并不是我此次工作想要解决的问题。

这个时候,就看出腾讯云这个数据迁移工具的可配置性了。

在本地迁移中,有两个设置,一个是用来设置本地数据迁移的包含目录,一个则是需要排除的目录的。

1
2
3
localPath=/opt/demo/var/buckets

exeludes=/opt/demo/var/buckets/log;/opt/ljmall-public--2/var/buckets/invoice

通过上面的配置,我就可以将占用大量内存空间的日志文件,发票(主要是pdf)文件排除出去,节省了云上大量的存储空间。

由于对配置文件进行了修改,也加上网络情况良好。实际上,整个数据迁移的过程不仅快速而且也很完美。并没有出现丢失数据的情况,这里需要补充一点,由于腾讯云存储数据迁移工具是支持日志记录的,因此所有已上传成功的文件信息都已经记录在日志中,这样也避免了重复上传等问题。所以,虽然我在中途修改了两次配置文件,但并不影响我最后将我需要上传的资源快速高效地上传上去。

由于在迁移数据之前,几乎所有的图片资源都是由运营人员产生的,所以我特地选择了一个运营不上班的周末来做这件事。之后,只需要在迁移数据完成之后,将原来写的上传、删除、展示资源的方法启用,之后所有的数据就能够实现同步了。当然,为了做的更好一点,也是可以每隔一段时间,定期执行迁移脚本,来保持数据的同步的。只是,从我目前的观察来看,无需定时迁移的脚本已经能够满足业务的需要了。

前端资源的处理和上云

本来我做这个功能的时候,最初其实只是想把图片等媒体资源进行迁移,这样能够确保用户在访问媒体资源的时候,不至于因为网络情况差,造成打开图片卡顿,半天出不来一张完整的图片。然而后来,我仔细想这个问题。所谓的对象存储,理论上来说,只要是静态资源文件,就都可以用上这个方案。因此,后来,我也将微商城的前端资源放到了云上。

这些前端资源是由webpack生成的一些js,css等文件,也包括由url-loader生成的一些图片资源,字体资源等。我使用到了一个开源的前端工具库来帮我自动完成build之后的上传操作,这个工具库是cos-webpack

这里的一切也很简单,不过这个工具库,让我觉得有一点不舒服的是,他只会负责将生成的文件上传到云上,但是却不会负责将云上原有的资源删除掉,这样一旦新的前端资源上传上去了,部署了新的前端代码。那么那些老旧的前端资源就失去了意义,再也不会有他们的用武之地。我并没有对这个前端工具库进行修改,直接使用了。当然,这样的设计也有好处,因为我们build新的前端资源的时机有可能与我们下一次部署服务的时机并不相同,这个时候如果说build之后,就将原有的资源删除掉,那么就会直接导致线上的某些页面,甚至所有页面处于不可访问状态。这显然不是我们希望得到的结果。

也许有一天,我会对之进行修改,做一个更好的工具,来处理前端资源。

顺便多说一句,我将前端资源单独放到了一个叫做febucket里面。这样,实际上,我整个项目完成之后,一共是有两个bucket,也能够很好地应付业务,逻辑清晰。

智能压缩

在使用COS来作为前端资源存放地的时候,还发现,如果不应用CDN的话,我没有办法做到资源的压缩。我们知道,包括js,css等资源,通过gzip压缩之后,能够节约一半以上的体积。对于chrome等浏览器来说,就意味着传输效率快了一倍以上。在没有应用COS之前,我们通过本地服务器上的nginx来实现gzip。相关原理,点这里:探索HTTP传输中gzip压缩的秘密。但是如果直接使用上传到COS上的资源链接,正常加载的时候,是不能进行智能压缩的。查看文档才知道,只有配合了CDN之后,我才能够实现智能压缩。但是仅仅启用了CDN并没有什么作用,后来我为此还专门发了工单提问,后来终于在腾讯云工程师的帮助下解决了。原来,我虽然启用了CDN,但是我没有相应地将对外展示的资源url进行修改,用户访问的其实还是对象存储北京机房里面的数据。后来,当我将url重新拼接,换成cdn的链接后,智能压缩才应用上。

CDN的设置

在使用过程中,由于没有或对CDN设置得有问题,导致CDN上的资源加载也出了问题。

需要说明一下的是,当以COS源的方式接入CDN的时候,在对象存储上的bucket是与CDN上的域名一一对应起来的。正式因为有这样的对应关系,我又要说了,我建立的那个苏联是多么的有必要。只需要一个苏联去跟美国单独建立外交关系,而无需各个加盟共和国单独去建立外交关系,省了好多事。

我最初设置了一个IP访问限频配置,当时设置的时候也没有在意。后来过了几天,发现有时候,资源的访问会出现514 错误,经过查询才发现原来是这个设置出的问题,又赶紧把这个设置放宽到了一个比较大的标准上。

另外,前面提到的fe这个bucket也出了问题,有跨域的问题,后来我把HTTP Header配置进行了设置,问题才得以解决。

当然,前面提到的智能压缩,在默认情况下也是关闭的,需要手动打开。

效果和理解

开始的时候,我虽然考虑到了要使用腾讯云的对象存储(COS)服务,也想按照大众的做法用上CDN,但是坦白讲,那个时候我对CDN还没有一个特别清晰的理解。我当然知道他是内容分发网络,能够让资源分配到各个节点,让全国各地,甚至全球各地的用户在获取资源时,都能够享受到一个比较快的速度。我有这样一个理解,但是还是很难将他与对象存储之间的关系说明白,讲透彻。

后来真正开始使用对象存储和CDN了。有那么几天,也通过腾讯云的后台,观测数据的变化,渐渐得也观察出来点门道。且听我一一道来。

我最初只用了对象存储,因此资源的访问地址就是

1
bucketname-appid.cos.region-code.myqcloud.com/key

如果上面的参照不好理解,可以举个例子,比如:

test-125777777.cos.ap-beijing.myqcloud.com/test.jpg

由于我访问资源的时候,已经指定了资源是在ap-beijing这个机房,因此全国各地的用户访问app进而访问到这个资源,都会从腾讯云北京机房获取这个资源。需要说明的是,我们的本地服务器的所在地也是在北京,但是由于我们本地服务器在网络延迟,响应速度方面还是与腾讯云有较大差距。从实际体验来看,只使用对象存储而不使用CDN已经对app中资源的加载速度有很大的改善了。(实际经过统计发现,有60%的流量是来自于北京,外地的流量不足一半)

之所以,我们还要使用CDN,一方面当然是希望能够越快越好,尽善尽美,这也是我作为一个开发者的追求。由于我身处北京,很难去测试外地用户在直接访问源站的时候的速度,但是我却能够通过CDN 的后台看到,全国各地,访问资源,普遍的延时在200ms以内,这对我来说,是可以接受的。另外一方面,其实从整体费用上来看,使用CDN并没有增加多少费用,没有使用CDN之前,费用的大部分来自于COS外网下行流量费,应用上CDN之后,由于用户可以访问分布在全国各地的各个节点来获取资源,因此对于COS来说,它的外网下行流量没有了。取而代之的是CDN流量,以及CDN回源流量。这里有必要再解释一下CDN回源流量,我最初还没有应用上腾讯云的时候,也不是很能理解CDN回源流量,当时在做费用评估的时候,将外网下行流量=CDN回源流量来计算。

实际上,按照我的理解,应该有这样的公式。在未使用CDN之前,

总流量 = 外网下行流量

在使用CDN之后,

总流量 = CDN流量 + CDN回源流量

当然我这里必须有一个前提,那就是COS(对象存储)的外部读取完全基于CDN。

通过上面两个公式,我们可以得出一个简单的结论,由于使用了CDN,外网下行流量没有了,由于业务的情况,总流量约等于CDN流量。

既然总流量约等于CDN流量,那么这个性价比就可以说非常高了。

后话

完成这个工作之后,被运营人员夸奖,说是自己家的app已经赶上天猫的速度了,听到这个话,还是很开心的,也不枉我这些天的努力。

起因

我在11月底的时候,在知乎上看过一个帖子,讲的是某人通过搬运B站上面的视频,获取了很大的经济收益。我当然是很羡慕的,后来简单研究了一下,发现YouTube 有API供开发者调用,这意味着上传的工作完全可以由计算机来完成。我很快想到,既然别人能够搬运B站上面的视频,可能这些人,还没有技术,只是靠手动搬运。那么我是不是可以通过代码来实现,视频的全自动搬运呢?

我觉得这是个不错的点子,后来又经过研究,得知YouTube上的视频,大概每千次观看量,视频的所有者可以得到大概5元人民币的收益(已经过换算)。而内容的影响力又是绵延不绝的,只要是好的内容,接下来就是躺着挣钱了。我当然是看好YouTube和他的收益情况的,毕竟我要做的,也不是自己制作视频,而是靠搬运。但紧接着,我又发现,谷歌对于YouTube频道的收益有一个门槛,只有达到了在过去的一年里,有1000个订阅者,4000个小时的累计播放量,才能够申请通过广告分成的方式获取收益。经过简单的计算,我发现,实际上,只需要每天10个小时的播放量,就可以达到4000小时累计播放量这个门槛,而只要有几个爆款视频,订阅者也会越来越多,这个门槛并没有多难以跨过。

说干就干

接下来就是写代码了。甚至不想看代码思路的直接跳过此部分。

说一下,我搬运视频的代码思路。这种做法,毕竟是侵权的。

首先,通过node爬虫,模拟浏览器的访问,获取到B站某个up主的所有视频,接下来通过node的child_process来执行you-get 的命令行命令,使得这个up主的视频能够批量地被下载下来。当然,我并不想竭泽而渔,也觉得老视频没有多少意义,所以每个up主,我最多只爬去最新的100个视频。

接下来,我会将视频通过YouTube接口的方式,批量地上传到指定的频道上面去。

后来,随着我的开发,细节也越来越完善。

  • 支持持续订阅某个up主,思路也无非是隔一段时间,爬去最近这段时间内他的上传的视频。

  • 支持将同一个up主的视频放到同一个播放列表里,之所以这样做,一则是因为视频更方便管理和浏览。二则是害怕某天突然被告知,我偷了他的视频,这样删除的时候,也只需要找这个播放列表里的视频删除可以了。

  • 原有的视频下载和上传的脚本是隔离的,导致做不到自动化。后来,这个工作实现了自动化。只需要在一开始将某个up主进行订阅,之后,下载,上传,长期订阅和上传这个up主的视频都能够自动完成。

坦白讲,写这个代码写得还挺开心,很大一部分因为是以前很少用到js里异步控制的async await,但是这次代码写起来,用了很多,也用得很爽吧。另外以前也很少写node的后台服务,最多也就是写两个爬虫,这次却借助这个想法,顺便学了一波node服务的部署和运维(为了做这件事情,也为了科学上网,我当时还买了一台阿里云vps,后来因为科学上网,服务挂了。我又换到了搬瓦工,这才一切稳定)。当然,有人可能会觉得我这种行为侵权,这个话题,我一会儿再聊。

过程

我便改进代码,边上传YouTube视频。由于最近六学火热,我最初选取的是B站上某个知名六学家作为我的实验样本。后来,又在B站上找到了几个体育类,搞笑类,影视类的up主,来上传他们的视频。我也在这个过程中慢慢发现,YouTube每个频道每天只允许上传最多100个视频。所以我这种bot也不可能像个疯狗一样毫无节制地去上传视频。这也意味着,我要选取尽量符合观众期望的视频来上传。因而,有很多天,我经常会打开YouTube的后台,去看最新的浏览量分析,来看哪些视频更受欢迎。去看最新的搜索词排行,来看到底用户喜欢看哪些视频,以决定我接下来要选取哪个up主作为我下一个订阅者。

我的确从YouTube的后台看到,随着我的视频越来越多,代码功能越来越完备,各项数据也越来越好了。虽然一开始没有爆款的视频,但是凭借着人海战术,还是很快就达到了每天10小时的播放量,接下来,就只差多几个爆款,来增长一波粉丝了。

但是,但是,但是

版权是个大问题

搬运视频,不可避免地会碰触到版权这件事。我最初对这件事,做个些简单的调查。当时考虑电视剧电影一定会是版权的高压线,而且在YouTube上搬运这类视频的人也不在少数,我并不想去趟这类混水。所以,我也是将搬运的内容,选择为了短视频,因为的确看到YouTube上面有大量来自国内视频网站的短视频,想到既然别人可以,我为什么不可以呢,于是也就选择了这个领域。

但是,从搬运的前几天起,邮箱里就开始接收来自官方的版权警告。比如下面两个截图,就是我随意从邮箱里YouTube发来的邮件里截取到的。

版权警告

版权警告

看过越来越多这种版权警告,发现YouTube很智能。这种版权警告,应该完全都是由机器来判断和筛选,因为有些刚刚上传的视频甚至都没有播放量。不过我并没有对这种版权警告有所警惕,只是觉得,既然YouTube很智能,能够帮我查找到哪些视频是侵权的,哪些不是,那我只需要把一些漏网之鱼搬运上去,也就很好了。

但是随着我的频道观看量和订阅量越来越多,也收到了下面这种邮件。
版权警告

版权警告

这个视频,其实是这个视频频道刚刚创建之初上传的,YouTube大概反应了一段时间,才把这个视频封锁了,而且还给了我严厉的警告。这是第二次copyright strike,当第三次收到这种邮件之后,我那个视频频道就被封锁了,而且很快,我谷歌帐号关联的另外一个我平时看视频的频道,也被封锁了。

我发了两封邮件过去,想要解释我的动机。我解释了我是个程序员,只是为了学习知识,不过,谷歌没有饶过我,截至到现在(2019年1月13日),我的YouTube帐号仍然处于封锁状态。

申诉无效

我侵犯的谁的版权

接下来解释一下这个问题, 我侵犯的谁的版权?

很多读者,可能从一开始就对我这种行为表示不屑,毕竟这涉及到侵犯版权。但我还是要辩解两句,首先,从上面我的侵权截图也可以看出来,我搬运的视频几乎都是影视片段和搞笑类的小视频,之所以侵权,侵的也是那些影视片段原作者的权益。再说明白点,虽然我是从B站搬运的视频,但YouTube并不认为我对他们有侵权行为,甚至,即便是那些B站up主把那些他们剪好的小视频发布到YouTube上,他们也依然会侵权。就像是前两年很火的谷阿莫那样,他的确付出了很多时间精力,但实际上他用到的素材也是涉及侵权的,在YouTube一样行不通。当然我也不否认,我的侵权行为,毕竟你从贼的手里偷到了路人的钱包,难道你就是清白的吗?

我还记得我那个频道刚刚建立十几天的时候,因为搬运了某个在B站上有1万+粉丝数量的up主的小视频,因为我的播放列表名字就是这个up主的名字,因而在YouTube上搜索很容易找到。那个up主在我搬运他的最新的一个视频下面留言,说他就是B站上的谁谁谁。也只是说了这么一句,我也并没有回复他,我又能说什么呢?

教训

关于盗版这件事情,我自己的态度一直模凌两可。我不认为这件事完全没有正面价值,不然,我也不会去做这样的事情。在写此文的时候,我甚至会想到13年去世的亚伦·斯沃茨 ,他是个反对禁止网络盗版法案的运动的人,很大程度上,我是欣赏这种黑客精神的。所以,我对版权上的问题,其实是没有多少反思的。因为如果真要较真的话,我搬运的那些B站视频up主们也毫无例外都有问题。

当然我也要说,是谷歌为了版权方的利益,对YouTube进行了控制,让这个社区更能够良性发展,他也并没有错。只是,在谷歌YouTube这张大的鱼网之下,有的成为了漏网之鱼,因此你还是能够在YouTube看到大量的国内视频网站上的盗版视频。有的成为了网中之鱼,成为了牺牲品。这其中包括了我自己,也包括那个曾经依靠视频广告分成获利颇丰的“B站授权搬运工”。我也许可以做的更好,比如只搬运搞笑类的视频,不搬运视频剪辑类的视频,这都可以让我的视频频道活得更久一些。但是,我并不想那么做了,它终究有一种做贼的感觉。

1月份

工作照常做,但是心里已经有点不踏实了,毕竟马上就要过年了,所以其实工作效率并没有多高。不过似乎大家也都没有强到哪里去,如此而已。1月份经历了人生中第一次年会,之所以说是第一次,是因为虽然从15年实习开始就算是上班了,但是却一直没有参加过年会。直到这个时候,才终于参加了第一次年会。然而年会也并没有多有趣,演出的节目并没有很有趣,大概也是演给70后居多的boss们看的。演出无聊,也没有拿到奖品,当然觉得不好玩了。不过,这次年会保留下来两张照片,是与其他同事的合影。其中有两位同事后来离职了,于是这两张照片也成为回忆,让我想起了之前与那两位同事一起工作的那段经历。为了年会,还买了一双皮鞋,一件衬衫,都只穿了那么一次,就放到柜子里了。总之,我对年会的印象并不好,甚至不想参加今年年会。说到这,你可以已经明白了,我还在这家单位接着干呢。

2月份

2月赶上过年,工作中断了几天,但好在工作并不紧张,所以也就还好。

过年,这件事,越来越驾轻就熟了,以前可能会惶恐于走亲戚串门子,不知道怎么称呼那些叔叔阿姨,哥哥姐姐,也不知道怎么跟他们打交道。现在却觉得这也算是一件沟通感情的好事情了。套路已然熟悉,接下来就是表演了。于是表演地也还不错,至少是及格了。也没有像那些年那样,跟我的老舅在酒桌上翻脸,跟我爸爸的老舅在酒桌上耍脸子。其实我到现在我也不明白,为什么那两年,我都跟这些舅们过不去。我并不想说那个时候年轻,也不想说这个时候成熟。也许,大家只是对对分多了两分了解。

过年如旧,但参加了1次高中同学聚会,这聚会也让我喜欢不上来。打算今年如果继续举办的话,不再去了。为什么我不喜欢呢?人们好多年没见了,于是开始聊天,聊到的内容非常肤浅,“在哪里工作”,“上什么班”,“有没有对象”,我甚至觉得今年的聚会,聊天的套路依然如此。其实我也能够理解,彼此之间并不熟悉的人们,能聊的内容本来也并不多,为了化解尴尬,聊一些最浅显的话题当然并不是错。但是,前面说的是理性,而感性的我,并不喜欢如此,我选择逃避。

想起来,几个月前,看到的推特上有人表态,说他明确拒绝了同学的邀请,去参加同学聚会。我当然做不到直接拒绝,可能哪天找个借口就不去了吧。

2月份写过几篇博文,大多是谈吃的,比如就是喜欢饺子 。这当然还是因为过年的缘故,会很容易让人想起来聚餐,饮食之类话题。另外,还有一个原因,也是想找一些由头,来回忆一些可能即将就会忘记的事情。

3月份

三月份,真正值得说的,大概两件事。

第一件事,去了一次香山。这个时候,天气还略显寒冷,爬香山的人也并不是很多。而偏偏就是这个时候的香山,让我第一次去,就喜欢上了,之后我又陆续去过两次。

我第一次去过香山以后,曾经想,以后要每一个月都争取去爬一次山,后来却发现,之后,也不过只又去了两次而已。上一次去的时候,正是十一国庆节期间,我以为游客们会去到故宫长城这些热门景点,香山的游客应该不会很多。但我却没有想到,去到那里,已经人流如织了。爬过两次山之后,这一次爬很轻松了,以至于,我对香山有了疲倦。

第二件事,由于Y同学在固安出差,因此我们得以相聚两次。当我写下这些的时候,也觉得时间很快: 这件事似乎就是昨天才刚刚发生。那两天,我带他去了还在下着雪的北京故宫,去了五棵松附近吃了顿潮汕火锅,去南锣鼓巷附近吃了顿烤鸭。我们当然不光是玩,也聊过去这两年的变化,成长,经历,也怀有对未来的憧憬。他说他以后不想在深圳长期工作,想要回到西北发展,去西安工作。我说了我的生活,我的遭遇。拭目以待吧,相信明天会更好。

4月份

同样是两件事

第一件事,去了工体看了场国安对阵恒大的比赛。这是我第一次在现场看正式比赛,因为是第一次,很新鲜,很有趣,加上比赛过程一波三折,我这次看球的体验实际上非常好了。以至于在接下来的几个月里,我又来到工体看过两场球。不过略显遗憾的是,我三次来到工体,看了三场平局。即便是第三次,我以为稳稳地能够拿下的长春亚泰,最后也跟国安踢成了平局。说起来,也很有意思,在现场看过几次足球之后,再去现场看篮球,即便都是国内最高水准的比赛(足球是中超,篮球是CBA),也会觉得现场看篮球相比足球来说太无聊了 。我是喜欢现场几万球迷一起助威的声势的,喜欢大喊牛逼,大喊口号的,当然喊傻x就是另外一回事了。关于看球,也许以后还会单独开辟一篇单独来讲,总之,我是享受的吧。

第二件事,去了北京草莓。后来写了我的2018北京草莓全纪录 ,应该是非常全面了,没有什么可再补充了。

5月份

到五月份为止,入职一周年,于是开始考虑是加薪还是辞职找工作的问题。如果找工作当然是要总结知识经验喽,又赶上那段时间自己也的确有一些知识上的积累想要分享,于是写了很多篇技术博文。其中大部分是关于React的,后来我就把他们结集,放到简书的一个文集React分享 下面了。不过话说回来,后来顺利地加了薪,工作量也没有增加,我也就继续在这家单位工作了。大概由于动力不足,后来也就很少再写技术博文。

第二件事,买个手机,被骗了。后来,我把这件事,写成了博文,又有万余字。

我遭遇的北京实体店卖手机骗局,希望你们不会遇到
我现在觉得, 走在街上,路边都是黑店!
在被侮辱,被威胁之后,我跟骗子达成了和解

6月份

6月的主题是世界杯了。至今,如果你让我自己想,我也会觉得六七月份是我整个2018年最愉快的两个月,工作上没有很多烦心事,也不用加班,下班后看两场球,评评球,看看足球相关的八卦,连朋友圈里面,那个时候讨论世界杯也成为了政治正确的主流,觉得好极了。优酷那档《这就是世界波》节目也很不错,它陪我度过了几乎一整个世界杯期间的夜晚,我也开始认为王自健是一个很不错的主持人,而越来越看不上李诞了。

7月份

7月份两件事

第一件事,当时大概有些无聊,关注了BEJ48的ddd,于是只要B站上那个应援会up主一更新视频,我就会去瞅一瞅看一看。但是,隔着屏幕的美女,看得久了,也是会腻的,于是新鲜感没过多久也就散去。慢慢地,我又没有兴趣了,对那个应援会up主取消了关注,相应地,ddd也很少关注了。

第二件事,有了一次相亲。相亲始于互相成为微信好友,终止于见面。相亲对象是一个做财务的女生,比我还大两岁,但我本着“学习”“的态度去了。见面之前,还曾经在微信上热烈地聊过三五天,见面之后,其实对方也没有明确表态不同意继续交往,我们就也继续聊着。但感情就以肉眼可见的速度,疏远了。我继续拖延着,这样父母就不会让我再去找下一个,对方也继续拖延着,经常是我发过去一条微信,对方隔一个小时才回复,而且各种理由,今天说是去健身房了,明天又说是去图书馆了,显得自己很忙的样子,只是太忙了没有时间理我。于是我也只好只是说句,那你忙吧,明天再聊。想要约来第二次见面,就迟迟约不到。终于在加了微信一个月之后,对方提出了我们不适合。其实我又怎么会不知道呢,不过就是一直拖延着罢了。我没有问她哪里看不上我,觉得显得有些扯皮和无聊。却矫情地发了一首徐志摩的诗,发在朋友圈,只给她一个人看。现在想想,倒也觉得有几分可笑了。

第一件事和第二件事有什么联系呢?关注的ddd,是隔着屏幕的人。然而觉得新鲜的时候,也曾经认为,还是屏幕里的人好,现实中的妹子怎么这么难猜呢。那个时候,我也像是一个迷恋二次元的肥宅,不愿意去做现充。可当我的那股新鲜劲过去之后,现实中的妹子也选择放弃了我。

8月份

八月,因为”谈判破裂“,心情不好,于是去了一趟泰山。关于这次旅行,我写了两万多字,凑了四篇博文。下面是第一篇

济南是个小姑娘,泰安才是山东大汉(1)

该说的,我也都说了,就不再多说了。

另外,继续追《权利的游戏》,去年的夏天看了这部剧的前两季,今年的夏天,看了这部剧的三四五季。我一时也归纳不出个原因,反正总是很喜欢在春夏看美剧,在秋冬看日剧。顺便一提,今年的春夏,除了《权利的游戏》之外,还看了《摩登家庭》,《硅谷》,都是追了好几年的,已经成为习惯的剧,本来还想看《毒枭》的,但是看了半集就看不下去了,也许时机没有到吧。这个冬天,看了今年唯一一部日剧,《我们无法成为野兽》,剧当然是好剧,只是看到第六集之后,因为其他变故,看剧的过程又中断了,反倒不想再继续追下去了。但,应该还是会找个时间补上剩下的剧集的。

9月份

工作上,一直想在项目中引入的postcss autoprefix终于被我引入进来的。相应地,也学到了好多新的知识,不必详细说了,之前也写过博文记录这件事: 在webpack项目中配置postcss,实现autoprefix

生活上,终于跟父母进行了一次旅行。虽然去的地方也不远,只是在北京,只是去了天安门,故宫,北海公园而已。但整件事现在回想起来,还是挺有意思的,我会想起很多小事,比如我妈不敢地铁站的电动邪梯,于是我爸只好搀扶着我妈走楼梯,而我以前甚至似乎从来都不知道我妈是不敢坐电梯的;又比如我爸我妈不认路,全程我来当导游,一下有一种当家做主的感觉。再比如我那个不听话的小表弟,到了天安门哭着喊着要他妈给他买这买那,去了故宫又觉得这里不好玩,嚷嚷着赶紧走;我也会想起,我给同行的父母和老姨一家办了5张北京公交卡,我们一行人在北京从来没有分离过,结果退卡的时候,其中4张卡退卡金额一致,只有一张卡多了几块钱,所以一定是有人逃了票,又会是谁呢?

这个旅行的所有景点,在此之前,我都去过,有的甚至去过不止一次。但是跟父母去的话,又有新的好玩的点。从这个角度来说,这也算是旅行的意义了。

其实整个夏天,母亲都在念叨着,谁谁谁又去哪哪哪玩儿去了。后来老爸大概是被念叨烦了,才带她来了北京。他们本来还想来我住处参观一番,然而我的住处真的是寒舍,委婉地拒绝了他们。父亲本来想要去八达岭长城的,但是从南城往北城走,这实在是太远了,后来也并没有去。而我,过了差不多两个月之后,自己一个人跑到八达岭逛了一圈,跟想象相差无几,没有多少惊喜。也许到了2019年的中秋节,能够跟父母一起去八达岭吧,到那个时候,我都能够给他们当导游了。

10月份

那位“前女友”说过她爱玩网易某款吃鸡游戏,而当时我的手机根本带不动吃鸡游戏。后来我换了个手机,终于能够玩吃鸡了,那位也不在了。我又将那款吃鸡手游卸载了,直到后来因为表弟结婚,去他家吃包子,看见他的电脑上有网易那款吃鸡端游,看他们玩觉得蛮有意思,于是觉得既然玩不了端游,那就玩手游吧,就又重新把游戏装回来了。不过这次,我不光装回了网易那款吃鸡手游,还装了腾讯那款吃鸡手游。结果两相对比,发现腾讯那款手游更加出色一些,对新手也很友好。于是几乎每天都要玩上一两把。我的段位也一路从青铜打到了黄金2。

有那么一段时间,很痴迷。于是也跟很多玩家一样,去看一些打游戏的直播视频,去知乎上看那些“刺激战场的技巧有哪些”之类的帖子。当然,这样一段时期,很快就又过去了,现在又觉得游戏不过是套路罢了。

第二件事,我买了一个魔方,经常会在空闲时候,学习学习魔方的公式。后来经过一番学习,终于拼出了第一个完整的魔方。但是最后一个公式,我没有记住。后来,我每次也只是把前两层都拼好。然后,就心满意足地打乱魔方,重新拼下一个了。

有那么两个周末,我一个人背着包,包里放着kindle和魔方,去到住处附近的一个公园,坐在一个角落里。我会安静地看会书,看书觉得没有意思了呢,就玩会儿魔方。魔方觉得没意思了呢,又打开手机玩会吃鸡手游。总是有事情做,总是很悠闲。我很难说这种状态是好是坏,但对我都是经历,而这种经历,今年经历了,明年就未必了

11月份

可能还是孤独吧,11月份,竟然又开始在B站上看聊天直播,开始我只是看吃鸡的直播,有一个叫做大忽悠的主播觉得很有意思,看了三五天之后,偶然间又看到一个聊天主播,发现她人气并不高,只有几百人关注,而长相甜美可爱,简直就像是被遗忘的丑小鸭,于是赶紧关注了。后来,还专门充值了直播的虚拟货币,虽然也没有充值多少钱,但是要知道,我此前从未给主播冲过钱的。其实,这样一个小主播,直播间里面同一时间段内在说话的,也不超过五个访客,即便是你不充值,你要是在弹幕里跟她聊上两句,他也是会搭理你的。当然,主播们当然不是靠空气活着的,她们当然是需要打赏的,于是你每次打赏点小钱,她们也是会对着手机屏幕,喊出你的昵称,说上两声谢谢,比一个心,嘬一下嘴。我后来了解到,这个主播,当时还是一个学民乐的大三学生,家在呼和浩特,在包头上学,我关注她的时候,她才开播没有多久,她没有多少才艺,偶尔会唱两首歌,唱的歌也不是多好听,有一个跟老婆关系不是很融洽的大佬,几乎每天都会到她的直播间逛一逛,说说生活,有时候,我甚至觉得在那个直播间呆了近一个月,我知道那个大佬的故事,要比知道那个主播的情况还要多。大佬好像也只是想找一个对象倾诉,于是直播间里,大佬在屏幕上喋喋不休地说着,主播和几个听众看着。我想起这些事,总会觉得每个人都不容易,逃避也并不可耻。我从十月中旬开始看这位主播的直播,看到11月中旬,看着他关注人数基本不动,直播间人数一两百就算是高的,我知道她快要离开了。果然,毫无预告地离开了。

第二件事,去看了改革开放四十周年的展览,也顺带着看了一个《大唐风华》的展览。其实最初,我是在某公众号上,看到小编有推荐《大唐风华》这个展览,可正当我准备过去看的时候,却听到一个新闻,国博闭馆改造。等又过了近两个月之后,再次得到国博的消息,已经是说,国家领导人们集体去参观了改革开放四十周年的展览。

12月

一件事是相亲,因为还没有结束,所以也不想先说太多。另外一件事则是工作上的变动,也不想说太多。除了这两件事之外,最让人意外的,应该还是奶奶生病这回事了。

某天突然接到老妈的电话,告诉我,第二天要去县医院看一看,因为奶奶住院了。我并没有在电话里问起她的病情,怕自己如果知道了一个坏的结果,会失眠,而老妈也没有直接告诉我奶奶的病情。然而,当天晚上,我虽然很早就睡了,但还是做了不好的梦,第二天早上起来去吃早餐的时候,更是往最坏的方向想了好多回,心情并不舒畅,情绪也一直在压抑。等到坐了一小时火车,打了个的来到医院,见到在病床上处于昏迷状态的奶奶的时候,突然发现,自己前一天夜里的梦,以及当天早上所有最坏的结果都有可能出现。旁边的亲戚跟我讲,喊喊你的奶奶吧,我于是坐在床边喊了两声,积压的情绪得到了释放,哭了出来,哭了好一会。这次哭,后来也让我想起,小的时候,一直跟着奶奶的我,突然要离开奶奶,去爸妈那边生活,同样是哇哇地哭了一场。

此后一天半的时间,我都在医院里陪护,索性奶奶也渐渐好转过来,从沉睡中苏醒过来。她醒来的时候,我就在旁边,竟然也把我吓了一跳。她拼命用力去闹腾,试图摆脱呼吸的口罩,插在身上的输液用的针管。我于是赶紧去叫医生,医生回答病人已经苏醒了,这是好症状。我没有特别的欢喜,因为此前,已经从医生的口中得知奶奶并无生命危险,只是有可能会有并发症。可能的并发症包括脑血栓,肺炎,糖尿病等,但后来奶奶苏醒以后,情况的确越来越好,我于是也安心地在周日的下午离开了医院。

后来隔了几天,听老爸说奶奶已经出院了,又过了几天,我回家去看望。说话已经没有问题,但活动还是有些费力。回家的当天,我在奶奶这屋待了很久,想要做一个补偿。但是,第二天,眼见着奶奶的确好转了,而我也的确还有更有意思的事情要做,也就又去做别的了。

亲情,大概是永远都可以聊的一个话题。

结语

整个2018年还是很平淡的,一切行走的轨迹都非常地自然,也几乎没有做什么选择,相比2016年的自己,简直可以说是非常平淡了。偶尔有两三件事情,给生活造成“波澜”,其实也并不是自己主动去制造的,而是被动接受的。

我希望2019年做出更多主动的改变。

我希望2019年能够增加更多的睡后薪水。

当然,我还有很多美好的希望,这里不展开了。

缘起

最近的工作,接触了很多云计算相关的皮毛知识,虽然是皮毛,但也毕竟让我对此多了几分认识。于是就再整理整理思路,写下来吧。

发展历史

曾经有段时间,哪怕是一点都不了解互联网的人,也能够经常听到“云计算”,“大数据”这样的词汇,他们的热门程度,类似于较早之前的“AI”,”VR”,“人工智能”。不过作为一个搞计算机的,“AI”和“VR”其实我一直也从没有能够从技术上应用过他们,以至于一直觉得十分遥远。但”云计算“却随着了解地越来越多,觉得不再那么高山仰止了。

亚马逊应该是最早布局和应用云计算的。他从02年正式发布了AWS,之后这个业务也给他带来了很高的回报,股价一路飙升。后来微软和谷歌也紧随其后,开始布局云计算。国内云计算的发展稍晚了一下,但是也是很牛的。前一段时间,有篇《阿里云的这群疯子》的文章,讲了阿里云从初创到繁荣的历史转变,一时间也刷爆了朋友圈。阿里云诞生自09年,腾讯云诞生自10年,两个巨头也是你争我赶,虽然在我们外人看来已经很牛了吧,但毕竟亚马逊云计算发展的比较早,还是亚马逊的AWS更加给力一点。

发展历史终究只是浮云,对于开发者来说重要的是能够实际应用这些云计算技术,并为自己创造价值。

saas, paas, laas

关于这三者其实网上已经有很多人在科普了,比如我文章下面参考链接里的阮一峰大大。但是我还是想将我的理解表达出来,给自己一个回顾。

saas

按照我的理解,这三种服务面向的群体实际上并不是重合的。

什么是基础设施

我先说说我自己觉得最好理解的,laas,Infrastructure-as-a-service, 也就是基础设施即是服务。那么问题来了,什么是基础设施呢,我们试想假如你已经有了一个好点子,要建立一个面向全国范围内的电商网站,这个网站一旦投入使用,立刻就会成为行业前十,但是你没有太多的投资。这个时候你需要自己在万网或者狗爹(goaddy)买一个域名,如果是面向国内用户的站点,你要对你的域名进行备案,这些过程都还算简单。

接下来你需要买一台服务器,如果你自己有一些特别的需求,你还可以定制你的服务器。有了服务器,有了IP,你需要你所购买的域名能够指向你的IP,你又需要DNS服务

你要给服务器装上系统,装上合适的数据库,之后你的程序能够在你的服务器上面跑起来了。但是即便如此,可能还是会有很多问题,比如为了容灾的需要,你可能有不止一台服务器,比如3台,但是你只能把这3台服务器放在一起,于是面临的第一个问题,那就是你可能只能保证你服务器所在地的访问速度,而其他区域则保证不了访问速度。但是你只是个小的创业者,根本没有能力在全国范围内,搭建多个服务器来满足全国高效的需要。于是你陷入了苦恼,感慨原来创业并不只是”就缺一个程序员了”。

然后你姑且容忍了没有CDN的问题,你考虑到你的站点虽然面向全国,但是一半的用户来自北京,于是你把那几台服务器放到了北京的联通机房。除此之外,你还需要大量时间来做运维,来支持你的服务器的正常运转。我曾经见过公司从服务器选型到网站服务安全稳定运行的整个过程,的确是需要大量的时间成本以及很高的知识储备的。

解决方案

有了需求,接下来就要有人来做了。就拿亚马逊来说,他很早就做成了全美最大的电子商务平台,而他的站点规模,决定了他一定要使用上大规模的服务器,以及应用上CDN等技术。这个时候,亚马逊说,我想把我的空余的服务器租出去,注意,我不是像dell公司那样把服务器买给你再做做售后服务工作那么简单,我是把服务器租给你,如果你愿意的话,我还可以给你一整套的解决方案。也就是说,你服务器上安装的数据库也可以从我这里来租,数据库的配置我都可以预先给你配置好,保证是一个最佳实践,你无须再为此付出大量时间精力。

我也可以把我自己成熟的CDN技术分享给你,让你的网站也能够无论在哪里,都能够有一个很快速的访问速度。如果你的网站上有大量的多媒体资源(图片,视频等等),你也可以把这些多媒体资源存放在我这里。我保证,你的多媒体资源的访问速度,与我们亚马逊自己的多媒体资源访问速度相当。凡此种种,还有很多。由此,其实我们不难看出来,当今互联网以及计算机发展的一大潮流,就是从原来的购买转变为后来的租用,类似的情况,单就美国来说,还有租用影片的netflix, 以及微软的office虽然也在卖,但也有更多的用户选择了office365。

租用的好处与坏处

让我们暂时岔开一下话题,聊一聊究竟这种租用的方式能够带来哪些好处呢?为了不岔开得太远,我们还是以云计算服务为例,我们来算一笔帐,假设一家小公司初创,为了自己的网站能够安全稳定的上线,他需要服务器以及上面提到的一套解决方案,他为此要付出很大的成本,而又由于是初创企业,自己无法准确估计自己的需求,可能最后买到了合适的服务器,以及应用上了一套解决方案,一旦业务突飞猛进,他又要对此进行升级,相应地,又要花费大量的时间人力成本。而租用的方式,则是能够在一定规模内,实现付出最小,利益最大。当然,我也说到了是一定规模内,我们看到公司一旦达到了一定规模,租用的成本要远远大于直接买的方式,因此我们也看到像dropbox就离放弃了AWS转而自建基础设施和网路。

都有哪些基础设施

为了方便,我们这次把视线瞄准国内,看看阿里云是怎么做的。下图是阿里云的产品一览

阿里云产品一览

我们也可以看到,就我们刚才所说的例子来看,用到了弹性计算(云服务器)、存储服务(oss等)、CDN技术以及数据库这些基础设施。阿里云将这些服务拆分成一个个的产品进行出售,我们可以根据自己的需要进行量身定制。

感兴趣的同学,可以通过参考链接,进入阿里云的观望去瞅一瞅。

laas 的好处

所以回过头来再来看云计算中的laas,能够看到他是有很大的优势的。主要表现在:

  • 租用的方式能够让付出最少,收益最大。前面已经提到过
  • 快速完成基础设施的应用,专注业务核心
  • 运维成本降到最低

saas

软件即服务

这个其实按照我的理解,并没有laas复杂。想对于laas而言,我认为主要区别在于:

对于购买laas的使用者,他对于在基础设施之上所搭建起来的应用程序有非常高度的掌控权,毕竟laas只是提供了基础设施的服务,真正的应用程序,还是需要自己来开发。但是saas则并非如此,他聚焦在了更高的层次上,直接为你提供了应用程序,因此你对应用程序本身的掌控力非常差,如果让我举一个例子的话,我会说当今很流行的微商城服务,比如微盟,你通过购买他的这个微商城服务,然后再在自己的微信公众号后台进行一些简单的配置,可以快速地建立起一个微商城来,如果你有需要,当然也可以快速完成微信小程序的创建。相比laas而言, 这种方式更加高效了。只是,会更加受制于人。他有点像是曾经经常被讨论的自有商城和天猫店铺的区别,在这里就不再多做阐述了。

paas

paas,也就是“平台即服务”,我接触的比较少,也就简单说一下我的理解。我自己用过的是,2013年左右的GAE,当时通过一些简单的配置,完成了一个应用,也就是goagent的开发(相信经历过那个年代科学上网的朋友,对此定会不陌生)。为了写这篇文,我也找到了一篇2014年其他人的博文,介绍goagent的原理,感兴趣的朋友,可以通过参考链接过去看看。我用goagent 的时候,还对云计算这一块毫无所知,完全是根据网上的傻瓜教程来搭建服务的。现在会过头来看,就像是阮一峰博文中所述的那样,paas是正好介于laas与saas之间的一种服务

阮一峰博文图片

还就goagent所使用的GAE为例,他并不只是给你基础设施,他也给了你一个应用程序所必须的环境(在这里是python环境),他也不同于saas,他没有给你一个完整的软件服务,让你直接就能够使用,他还是要让你自己来写程序,来实现某些功能的。其实写到这里,我又想起了当年玩贴吧的时候,也有朋友基于百度的BAE(与GAE类似),实现了百度贴吧的自动签订功能,当时依然觉得有趣,也仍不知所言。只是照猫画虎,但这照猫画虎,却让我对计算机有了更深的兴趣。

综述

其实说起来,我最早用的云服务是个人服务,百度云。后来,又用了很多其他的个人云服务,我早在4年多以前,我就说过要构建一个个人云端信息库。我就表态过,自己对于“云”这件事很乐观。我想既然2c是这样的,2b也应该不无例外。包括前面我的许多分析,也都表明,我自己是支持云计算的,即便从社会分工的角度来说,让专业的人做专业的事,这件事,从来也没有错。

标题说的个人工作实践指所见到的公司从服务器选型到网站服务安全稳定运行的整个过程,准备上云计算的过程,使用微盟微商城的体验,使用goagent的体验等等。

参考链接

前面

作为一面全栈工程师(偏重前端),对待老大交代下来的后端任务也是需要认真完成的。前段时间,有个工作,要通过淘宝的OAUTH进行授权,进而获取到access_token,通过access_token来作为授权码,进行所有需要登录权限的API访问,这些API 包括但不限于用户,商品,交易,评价,物流等API.

过程

在这里也无须去科普OAUTH2.0协议到底是什么了,感兴趣的可以自己去查wiki.

我来说的仍然是我自己的理解,所以OAUTH到底做了什么呢?它是一直验证机制,这个机制实现了两步验证,仍然以淘宝API获取access_token为例,淘宝认为开发者访问用户的信息,是以应用为单位的,每一个应用需要一个app_id,app_secret,我们是先要通过app_id 来置换到一个叫做code的字段,这个字段只是作为一个过渡,我们能够通过code值,再调取一个api,才能够最终获取到access_token.

拿实际例子来说,

、授权操作步骤

    此处以正式环境获取acccess_token为例说明,如果是沙箱环境测试,需将请求入口地址等相关数据换成沙箱对应入口地址,操作流程则同正式环境一致。
    实际进行授权操作时,测试的数据 client_id、client_secret、redirect_uri 均需要根据自己创建的应用实际数据给予替换,不能拿示例中给出的值直接进行测试,以免影响实际测试效果。下图为Server-side flow 授权方式流程图,以下按流程图逐步说明。
授权步骤

1)拼接授权url
拼接用户授权需访问url ,示例及参数说明如下:
https://oauth.taobao.com/authorize?response_type=code&client_id=23075594&redirect_uri=http://www.oauth.net/2/&state=1212&view=web

参数说明
名称
client_id
response_type
redirect_uri
state
view

2)引导用户登录授权
引导用户通过浏览器访问以上授权url,将弹出如下登录页面。用户输入账号、密码点“登录”按钮,即可进入授权页面。
授权

3)获取code
上图页面,若用户点“授权”按钮后,TOP会将授权码code 返回到了回调地址上,应用可以获取并使用该code去换取access_token;
若用户未点授权而是点了“取消”按钮,则返回如下结果,其中error为错误码,error_description为错误描述。分别如下图所示:错误

4)换取access_token

方式1(推荐):

通过taobao.top.auth.token.create api接口获取access_token(授权令牌)。api服务地址参考http://open.taobao.com/docs/doc.htm?docType=1&articleId=101617&treeId=1

最后

说起来,我最早使用OAUTH进行登录或者授权操作,还是早些年在用微博的时候,如果OAUTH的应用已经非常广泛了,了解它对我们,无论前端开发还是后端开发都有很多好处.

参考链接

http://open.taobao.com/doc.htm?docId=102635&docType=1

http://open.taobao.com/api.htm?docId=285&docType=2

需求

##1希望能够让开发者写代码更轻松

以往没有引入postcss autoprefixer之前,我们为了css相关特性能够在各个浏览器上的兼容,引入了scss,利用它的mixins来实现prefix。但是每一个mixin 都有一个自己的语法。

比如以往,如果我们我们想要写一条

div {
    display: flex;
    align-items: center;
    justify-content: center;
}

为了各个相对早期浏览器的prefix,我们需要mixin,然后这样写

import 'common/flexbox';

div {
    @include flexbox;
    @flex(1);
    @justify-content(center);
}

然后按照这样的约定,来加上需要的prefix。

这当然是一个方法,但是对于开发者来讲,实际上增加了一些学习成本,而且相当于将标准放到了一边,去使用另外一套标准。

我们之前的mixin,由于已经有好几年的历史。当时为了兼容市面上那些还有很大市场份额的浏览器,prefix写的很全。比如下面这个mixin flexbox到代码:

@mixin flexbox {
    display: -webkit-box;
    display: -webkit-flex;
    display: -moz-flex;
    display: -ms-flexbox;
    display: flex;
}

为了写这篇博客,我又确认了一下,那个mixin flexbox的开源库来自于2013年,距离现在已经五年了,五年的时间,淘汰了很多过时的浏览器,五年前可能需要兼容到ie8,现在移动端开发甚至完全可以无需理睬IE的存在,所以这样的一套prefix就显得有些过时了。那位说了,我更新我的mixin不就好了,比如在2018年做移动端开发,也许我只需要将上面的代码改写成:

@mixin flexbox {
    display: -webkit-flex;
    display: flex;
}

但是我们也许需要想地更远一些,也许再过两年,我们甚至不需要对-webkit-的支持了。那时候,难道我们又要改一遍这个mixin吗?

postcss解决了这样一个痛点,可以直接书写标准的css(现在是css3,但是过几年也可能就是css4了),我们有了这样的工具,再指定一个浏览器兼容表,就能够实现自动prefix,而这相比于sass/scss mixin的方式,维护起来更加简单,应该是一个很好的实践。

2对用户更友好

这当然也是显而易见的,以前我们可能为了兼容更多浏览器,而写更多的prefix,可是随着时间的推移,很多prefix完全并不需要。我们通过postcss来处理,简单明了,缩小了生成的css文件的体积,最后反映到用户那里,会快上一丢丢!

步骤

1 安装postcss-loader ,postcss-preset-env

yarn add -D postcss-loader  postcss-preset-env

安装postcss-preset-env,无需再安装autoprefixer,由于postcss-preset-env已经内置了相关功能。

2 添加.browserlistrc 文件到项目根目录

1% in CN
android >= 4.4
ios >= 8
not ie <= 11

这个需要根据项目的世纪情况来自由选择,我是考虑我们的项目是移动端项目,且确实有用户在用Android4.4 或者ios8,但是再很难看到低于这些版本之下的系统了。

3配置postcss.config.js

module.exports = {
  loader: 'postcss-loader',  
  plugins: {
      'postcss-preset-env': {},
    }
}

4 配置webpack.config.js

{
test: /\.scss$/,
use:[ 
    MiniCssExtractPlugin.loader,
    {
        loader: 'css-loader',
            options: {
                root: 'static',
                minimize: true,
                importLoaders: 1
            }
    },
    'postcss-loader',
    'sass-loader',
]
},
{
test: /\.css$/,
use: [
    MiniCssExtractPlugin.loader,
    {
        loader: 'css-loader',
            options: {
                root: 'static',
                minimize: true,
                importLoaders: 1
            }
    },
    'postcss-loader'
]
}

由于我们的项目中使用了scss,因此需要sass-loader。这里需要注意各个loader的顺序,一开始我的顺序是MiniCssExtractPlugin.loader,css-loader,sass-loader, postcss-loader,结果发现并没有能够autoprefix,原因是如果想让postcss-loader认识并且处理,需要先用sass-loader进行处理,转化成postcss-loader可以认识的代码。

另外需要注意的是,我们这里还在使用css-loader v0.28,目前已经有了v1.0,版本改动很大,以至于我们暂时不能升级。

熟悉前端开发的朋友,应该对 Babel这个项目并不陌生,早在两年多以前,阮一峰大大就已经写过文章《Babel 入门教程》 对他进行了介绍,那个时候,其实Babel应该已经算得上是网红开源前端库了。这两年,Babel其实也一直在发展,我这里想说的是我看到的Babel的成长

babel-preset-env

首先是babel-preset-env,详细的介绍文档在这里:https://www.babeljs.cn/docs/plugins/preset-env/

我也并不会去介绍怎么去用这个,只是想谈谈自己的体会。我记得刚开始使用babel的时候,的确有时候会用上一些stage-2,stage-3 的特性,那时候还为了了解这些所谓的stage去看了ECMASCRIPT 新版本发布的流程,觉得也很有意思。但是虽然有意思,但是配置起来却的确繁琐,有时候,你的确需要为了配置这样一个Babel看好多相关文档,这无疑算是一个痛点了。现在好了,就如同文档里面所提到的:

在没有任何配置选项的情况下,babel-preset-env 与 babel-preset-latest(或者babel-preset-es2015,babel-preset-es2016和babel-preset-es2017一起)的行为完全相同。

babel-polyfill

为什么你这么大

我们都知道,Babel为了存心让我们配置起来更困难,故意将他的功能分拆成了两部分,其一是语法上的转化,这个默认情况下他自会帮我们处理。而另外一部分,就是新API的polyfill,需要我们引入babel-polyfill来完成。当然,我前面说,Babel是存心折腾开发者的确是开玩笑的,毕竟并不是所有的时候我们都需要polyfill的。这有点像是React项目也有两个核心包,ReactReactDOM类似。

    import React from 'react';  
    import ReactDOM from 'react-dom';

babel-polyfill是好东西,能够将新API作用在老的浏览器上,但是我们要注意不要滥用。比如我们随便在百度上搜索一篇文章,讲解如何使用 babel-polyfill的引用和使用,往往都会看到有这样的描述:

module.exports = {entry: ["babel-polyfill", "./app/js"]};

这样做,从功能实现上来看当然是没有错的。但是,如果我们原来的入口是

module.exports = {entry: ["./app/js"]};

那么很容易就能够发现由于入口处增加了babel-polyfill,导致webpack在处理之后,最终的到的入口核心js文件比原来增加了有100kb左右。对于这个问题,也已经有issue,不过很奇怪这位网友把issue提到了babel-loader这个项目下。

然后针对这个问题,有老外网友介绍到了transform-runtime等。但是经过我的测试,这也并不是一个很好的实践。

动态识别

为了polyfill 这件事情,其实是有两种思路可循的。第一个思路是根据浏览器缺失哪些特性来补全哪些特性,这个思路的代表是 polyfill-service,这个项目 。它能够根据浏览器的UA来判断当前浏览器缺失哪些特性,进而进行补强。但是经过我的调研,这个项目在天朝可能还存在水土不服的问题,一个很明显的事实是将安卓微信内置的QQ浏览器X5交给这个库来处理,它会认为当前的浏览器是safari,原因大概是因为UA上有safari这个字段。考虑到我们天朝还有类似微信这样很怪异的UA,我认为并不适合在当前这个时间来对此进行实践。(在这里多说两句,polyfill-service这个库和另外一个知名项目fastclick同属于英国金融时报,而最近我发现fastclick在现代浏览器上也有一些tricky的地方,在他们的issue区有能够找到一些吐槽,然而,这个库已经两年多没有人维护了)

把polyfill-service仍在一边,我们接下来说另一个思路。能不能根据我使用了多少新API,来决定我引入多少polyfill的内容呢?比如我只在我的项目中使用了ES6的set,没有使用其他新API。那么我引入polyfill的时候,能不能只引入set的polyfill呢?答案当然是可以的,这就是babel-7的新特性,没错,由于当前稳定版是babel-6,因此这个特性还处在测试阶段。但是根据我自己的测试,表现很多。

不过有趣的是,虽然还只是Beta版,Babel却将之写入了正式版的文档当中,结果当时我为了测试这个新特性,都已经测试到怀疑人生了。文档戳这里,感兴趣的同学可以去看看。总之,实际上只是对babel增加一项配置。

      "useBuiltIns": "usage"

不过由于涉及到升级Babel,当时我在测试的时候,还是有些不顺的。但是一旦迁移成功,应用上useBuiltIns的这项配置,的确能够让polyfill的体积大幅度减小。

browserlist

前面的动态polyfill,的确可以让webpack生成的js文件体积更小,但是能不能再小一些呢?毕竟我们前端开发的目的就是极致的用户体验,当然可以。这个时候browserlist能够帮到我们。

关于这个话题,网路上相关的文章非常多,我就不再多谈了。

感兴趣的同学,可以看看ant-design项目中使用的browserlist。

https://github.com/ant-design/antd-tools/blob/master/lib/getBabelCommonConfig.js