2016 总结

2016 年, 要用一个词来形容我的话, 那可能是”技术宅”. 终日沉迷代码不能自拔, 不过正因如此, 技术上成长特别快. 马上要 2017 年, 稍微总结下自己即将过去的 2016 年吧~

技术篇

2016 年, 学习使用了非常多的东西, 包括但不限于:

AngularJS, React, Redux, Vue2, Vuex, Underscore, Electron, Koa2, PEG.js, D3, jQuery, ESLint, Swig, Mongoose, Sass, PostCSS, Gulp, Bower, Webpack, NPM, Git, PHP, Laravel, Vagrant, Bootstrap, Python, BeautifulSoap.

有的技术是花了很多时间, 例如 AngularJS 几乎做了一整年项目, Vue2 则是目前主要使用的前端框架, Koa2 是目前主要使用的后端框架. 而有些则是做一下小应用, 例如 React 和 Redux 结合这做了一个问卷设计页面, PEG.js 写了一个 XML 解析器, Python 和 BeautifulSoap 撸爬虫. 另有一些其实都快忘了, PHP 和 Laravel 主要是去年年底和年初在搞, 自从把精力放在前端之后就再也没用, 大概已经忘光了.

项目篇

2016年, 做了很多项目

  • 使用 PHP 和 laravel 自己搭建了一个博客框架
  • 使用 Python 写了豆瓣爬虫
  • 使用 AngularJS 写了一个书籍推荐和购买平台
  • 使用 jQuery 写了一个飞机大战游戏
  • 使用 AngularJS 和 ELectron 写了一个类似 Windows 资源管理器的软件
  • 使用 AngularJS 和 Electron 写了一个磁盘分析软件
  • 使用 React 和 Redux 写了一个问卷设计小应用
  • 发布了 node-wmic 模块
  • 使用 PEG.js 写了一个 XML 解析器
  • 使用 Vue2, AngularJS, Koa2 写了一个 RSS 订阅器
  • 使用 Node 写了一个静态博客框架
  • 使用 JAVA 写了一个 YACC

阅读更多

浅谈 co 库

最近在写一个静态博客框架. 但不同于 hexo 之类的, 框架本身提供了博客书写和管理功能. 后端同样使用了 Koa2 来做,

归功于 Arch, 我已经在使用 Node 7.2 了, 不过好像默认还是不能支持 asyncawait , 经查发现是要输入参数开启的=.=. 不过当时第一时间并没有想说去加参数解决, 而是使用了 co 这个库… 虽然也可以用 babel , 但是通过 babel 运行代码很难调试.

node.png

co 用起来其实和 async 差不多, 甚至一些地方更简洁, 比如他可以 yield 一个 Promise 数组. 而 async 则只能 await 一个 Promise.all. 其实归根就是 co 进行了一个隐性的转换. co 内可以直接 yeild 一个数组或对象, co 会自动把数组或对象里面的所有值尝试转为 Promise 并包装在 Promise.all 中返回.

1
yield [promise1, promise2, ..., promisen]

async 要处理多个异步的并行操作, 只能把这些操作手动放入 Promise.all 返回. 即:

1
await Promise.all([promise1, promise2, ..., promisen])

草案还有一个 await* , 这个也是最近才注意到的, 使用 await* 就可以这样写了:

1
await* [promise1, promise2, ..., promisen]

然而草案并不推荐 await* , 目前 Node 7.2 也不支持 await* , 不过 babel 支持 ~

阅读更多

正确使用 JS 的 sort 方法

sort() 方法对数组的元素做原地的排序, 并返回这个数组. 默认按照字符串的 Unicode 编码排序. sort 排序可能是不稳定的. 但其实 sort 方法可能并没有你想象的那么简单, 不信的话你耐心往下看看.

默认排序

sort 方法支持传入一个比较函数, 如果不传入则默认按照其字符串的 Unicode 编码排序, 因此默认情况下会出现以下情况.

1
2
[5, 1, 4, 11, 42].sort()
// [1, 11, 4, 42, 5]

解决方法就是:

1
2
[5, 1, 4, 11, 42].sort((pre, curr) => pre - curr)
// [1, 4, 5, 11, 42]

pre - curr 的值有三种情况

  • 小于 0 时, curr 排在 pre 后面
  • 大于 0 时, curr 排在 pre 前面
  • 等于 0 时, curr 和 pre 的位置不变

另外, 我们也可以对字符串进行排序:

1
2
['d', 'c', 'b', 'a'].sort()
// [a, b, c, d]

可能?是不稳定?

因为 ECMAScript 只是制定了 sort 这个方法, 但并没有给出具体的实现方式以及是否需要稳定的要求, sort 的实现就和其他大多数的方法一样由浏览器自行制定. 不同的浏览器或者同个浏览器不同版本上 sort 方法可能是稳定的, 也可能是不稳定的.

这里结合 V8 源码分析下这个 sort 方法的内部调优过程.

在 V8 中, 会通过以下函数方法进入 innerArraySort

1
2
3
4
5
6
7
function ArraySort(comparefn) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort");
var array = TO_OBJECT(this);
var length = TO_LENGTH(array.length);
return InnerArraySort(array, length, comparefn);
}

源码有点长, 可以自己看下 这里

注释已经点明了:

阅读更多

聊聊 Webpack 使用

老早的时候就听说了 Webpack 这个工具, 当时大概的印象就是类似 Gulp 这样的东西, 并且看起来好像挺复杂的. 直到学习 React 的时候才开始接触 Webpack, 才知道 Webpack 更多的是做模块化的工作. 不过当时也是乱配置一通能用就行=.=.

现在 Vue 标配也是用 Webpack 了. Webpack 其实并没有想象中的那么复杂, 其实最核心的还是 loader 那一块. 这次就主要聊一聊 Webpack. 我用的是 Webpack 最新版本 2.1.0-beta.27.

what-is-webpack

Loader

Loader 是 Webpack 的核心, 它会自动查找项目中的我们指定的文件类型, 然后使用我们指定的 Loader 进行处理. 例如:

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
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: ExtractTextPlugin.extract({
loader: ['css-loader?minimize', 'postcss-loader'],
fallbackLoader: 'vue-style-loader'
})
}
}
}, {
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}, {
test: /\.css$/,
loader: ExtractTextPlugin.extract({
loader: ['css-loader?minimize', 'postcss-loader']
})
}, {
test: /\.(eot|woff|woff2|ttf)([\?]?.*)$/,
loader: 'file-loader'
}, {
test: /\.(png|jpg|gif|svg|ico)$/,
loader: 'url-loader?limit=8192',
}]
},

对于 Vue 文件, 我们要让 vue-loader 来处理, 这里可以先忽略 ExtractTextPlugin 部分, 它作用是提取 CSS 这个在后面会提. 对于 .js 文件, 我们使用 babel-loader 来处理, 我们可以在项目配置一个 .babelrc 文件来指定我们使用的 presets 和 plugins.

阅读更多