前言
今天有朋友问了 “KeyMirror” 这个库有什么用的问题,其实这个问题并不难,这里扫一下盲区。
会按照下面这个逻辑来展开,彻底理解一下:
KeyMirror 有什么用?
Google Closure Compiler 是什么?
KeyMirror 解决了什么问题,好处是什么?
KeyMirror 的源码是什么样子?
用 Gulp 配置一个压缩任务,测试一下 Google Closure Compiler.
一、KeyMirror 有什么用
直观的来看一下,测试代码如下:
var kv = {
GET_USER: null,
SET_USER: null,
REMOVE_USER: null
};
// keyMirror 是对应的测试方法
var kv_new = keyMirror(kv);
console.log(kv);
console.log(kv_new);
最后输出的结果如下:
然后就是相当于重新生成了一个 key == value
的结构。但是肯定就会想,为毛要多此一举呢?其实这个跟 Google Closure Compiler 的 Advanced 模式有关。接下来我们来看一下它是什么。
二、Google Closure Compiler 是什么
如果有兴趣的朋友可以直接跳到文章后面,使用 Gulp 把环境搭起来测试,因为下面的地址都要翻墙!
有官方文档,需要翻墙:文档。
大致的意思就是说,Closure Compiler 是一个工具,这个工具能够编译 JavaScript 代码,编译后的代码能下载更快并且执行也更快。它能够解析你的 JS 代码,并且去分析它,能移除没有使用到的代码,重写、压缩得到最终的生产环境下的 JS 代码。它拥有检测语法、变量声明、类型定义以及对 JS 语言缺陷做一些检查。
总之,这就是做 JS 编译并且做一些常用检测的一款工具。
具体能够在线体验,也需要翻墙,在线体验地址
这个工具有三种模式:
只去空格( Whitespace only )
简单处理( Simple )
最优处理( Advanced )
用 KeyMirror 的原因就是因为第三种(Advanced,最优处理)模式下,会将 Map<K, V>
格式的 K 进行压缩,比如:
// 源代码
var kv = {
GET_USER: null,
SET_USER: null,
REMOVE_USER: null
};
// 编译后( 整理了一下格式,实际情况下会再添加压缩 )
var a = {
a: null,
c: null,
b: null
};
在引用的时候就变成:
// 源代码
var kv_new = keyMirror(kv);
console.log(kv_new.GET_USER);
// 编译后
var a = keyMirror({ a: null, c: null, b: null });
console.log(a.a);
这样如果在没有进行 KeyMirror 处理的时候,引用就会错误了,这种编译模式破坏了我们的代码,要避免这个编译导致的 Key
改变,可以给 Key
添加引号(单、双均可),其实能够分析的就是静态的属性,动态基本上是不好做好的,可以这样理解。
// 源代码
var kv = {
'STOP_USER': null
};
// 编译后
var a = {
STOP_USER: null
};
然而我们这样做了之后,代码就得不到更有效的压缩,这样
Closure Compiler
的功能就被削弱了,所以引入KeyMirror
既能保证代码前后的功能一致,也能享受压缩带来的性能提升。
三、KeyMirror 的源码是什么样子
既然知道了上面的背景和原因,我们来看下如何实现一个这玩意,其实特别简单的功能,就是让 K,V 相等。
var keyMirror = function(obj) {
var ret = {};
var key;
// 对参数的控制,必须是对象
if (!(obj instanceof Object && !Array.isArray(obj))) {
throw new Error('keyMirror(...): Argument must be an object.');
}
// 简单的遍历,将对应 K 赋值给 Map[K]
for (key in obj) {
// 只拷贝自己的属性
if (!obj.hasOwnProperty(key)) {
continue;
}
ret[key] = key;
}
return ret;
};
四、Gulp 配置测试 Closure Compiler
这里需要用到两个东西:gulp、google-closure-compiler-js
直接上代码:
var gulp = require('gulp');
var compiler = require('google-closure-compiler-js').gulp();
gulp.task('go', function () {
return gulp.src('./index.js')
.pipe(compiler({
// 编译等级,不区分大小写哈
compilation_level: 'advanced',
warning_level: 'VERBOSE',
output_wrapper: '(function(){\n%output%\n}).call(this)',
js_output_file: 'index.advanced.min.js',
create_source_map: true
}))
.pipe(gulp.dest('.'));
});
// 测试代码
var kv = {
GET_USER: null,
SET_USER: null,
REMOVE_USER: null
};
// 必须要和 keyMirror 代码一起,不然会被提示 error。
// Error: Compilation error, 1 errors
var kv_new = keyMirror(kv);
console.log(kv);
console.log(kv_new);
亲测非常的慢,不知道是不是我姿势不对,advanced 模式都是花费 12s 左右,simple 模式也花费 8s 左右,第一次测试我还卡挂了,所以基本上代码量上去了感觉是不适用的。
参考地址:
[1] https://developers.google.com/closure/compiler/
[2] https://github.com/facebook/react/issues/1639
[3] https://gist.github.com/zpao/d25251b139647a79cddf
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。