如何使用Uglify2.js分析函数中的依赖项
2014-08-27 00:43
591 查看
大家都知道,require.js遵循AMD规范,而国产的sea.js遵循自创的CMD规范。最近,又有大牛提出了更符合面向对象写法,以杀死AMD与CMD规范为己任,以JS工程化终极解决方案为目标的KMD规范。
作者有一篇介绍其内部的内核依赖的实现原理的文章。
从作者的博客里我们可以知道,像是下面的函数里的依赖关系中:
第一个函数里依赖了User,而第二个函数里则没有依赖。我们的目标就是找到像是User这样的依赖,从而可以去单独加载该模块的js文件,从而减少不必要的依赖加载,提升模块依赖加载性能。
作者用到了用于js代码解析、压缩、优化等的Uglify2.js库(用nodeJS实现压缩等)。在看到了其实现原理后,大概了解了其实现。但是作者实现的依赖里只有new一个类形式以及调用某对象的方法形式的依赖,我添加了单纯函数调用形式的依赖。代码如下:
结果已经很明显。当然,对于Array,document这些js自带的存在于全局变量中的属性我们可以过滤掉。
这个操作在代码分析、模块加载分析(比如define一个模块的时候写依赖了一堆模块,但并没有全部使用的情形)是很有用的,记录在此。
作者有一篇介绍其内部的内核依赖的实现原理的文章。
从作者的博客里我们可以知道,像是下面的函数里的依赖关系中:
function test() { var user = new User(); } function test() { var vp = new Array(); var el = document.getElementById("xx"); }
第一个函数里依赖了User,而第二个函数里则没有依赖。我们的目标就是找到像是User这样的依赖,从而可以去单独加载该模块的js文件,从而减少不必要的依赖加载,提升模块依赖加载性能。
作者用到了用于js代码解析、压缩、优化等的Uglify2.js库(用nodeJS实现压缩等)。在看到了其实现原理后,大概了解了其实现。但是作者实现的依赖里只有new一个类形式以及调用某对象的方法形式的依赖,我添加了单纯函数调用形式的依赖。代码如下:
<script src="uglify2.js"></script> <script> var U2 = UglifyJS; // test it function test() { if (foo) throw bar; if (moo /* foo */) { throw "foo"; } throw "bar"; u.a(); uu(); new User(); return ; } function test1() { var vp = new Array(); var el = document.getElementById("xx"); } function getRef(fn) { var U2 = UglifyJS; var ast = U2.parse(fn.toString()); ast.figure_out_scope(); var result = []; console.log(U2.AST_Dot,U2.AST_New); // for(var p in U2){console.log(p);} ast.walk(new U2.TreeWalker(function (node) { if (node instanceof U2.AST_New || node instanceof U2.AST_Dot || node instanceof U2.AST_Call) { var ex = node.expression; var name = ex.name; if (ex.scope && name && !isInScopeChainVariables(ex.scope, name)) { result.push(name); } } })); return result; } function isInScopeChainVariables(scope, name) { var vars = scope.variables._values; if (Object.prototype.hasOwnProperty.call(vars, "$" + name)) { return true; } if (scope.parent_scope) { return isInScopeChainVariables(scope.parent_scope, name); } return false; } console.info(getRef(test),getRef(test1));// ["u", "uu", "User"] ["Array", "document"] </script>
结果已经很明显。当然,对于Array,document这些js自带的存在于全局变量中的属性我们可以过滤掉。
这个操作在代码分析、模块加载分析(比如define一个模块的时候写依赖了一堆模块,但并没有全部使用的情形)是很有用的,记录在此。
相关文章推荐
- 如何使用Oracle的分析函数ROW_NUMBER、DENSE_RANK、RANK
- 如何使用ProcessMonitor进行application 依赖分析
- 使用Oracle的分析函数ROW_NUMBER、DENSE_RANK、RANK
- Oracle 分析函数的使用
- Oracle分析函数RANK(),ROW_NUMBER(),LAG()等的使用方法(转载)
- 使用分析函数进行行列转换
- sql server 关于函数中如何使用Getdate() (转贴)
- 使用Oracle的分析函数ROW_NUMBER、DENSE_RANK、RANK
- java中如何使用JNI调用C++写的函数
- Oracle 分析函数的使用
- 如何对电子表格组件使用自定义函数
- Oracle 分析函数的使用
- Oracle分析函数的使用
- Oracle 分析函数使用介绍
- .NET如何使用内存---餐馆案例分析[转载]
- 如何使用SetWindowRgn函数创建异形窗口
- 如何在Vb.NET中使用带返回的函数作为委托?
- Oracle 分析函数的使用
- 如何使用select()函数
- 如何使HTML元素的事件,使用我们封装类的成员函数作为处理函数