use*_*508 26 javascript dependencies dependency-management
我目前正在维护大量的JS文件,并且依赖性问题越来越多.现在我将每个函数放在一个单独的文件中,我手动维护一个数据库来计算函数之间的依赖关系.
这我想自动化.例如,如果我有函数f
Array.prototype.f = function() {};
Run Code Online (Sandbox Code Playgroud)
在另一个函数g中引用
MyObject.g = function() {
var a = new Array();
a.f();
};
Run Code Online (Sandbox Code Playgroud)
我希望能够检测到g正在引用f.
我该怎么做?我从哪里开始?我是否需要实际编写编译器,或者我可以调整Spidermonkey吗?还有其他人已经这样做了吗?
任何指示让我开始非常感谢
谢谢Dok
bob*_*nce 18
虽然理论上可以编写一个静态分析工具来检测其他文件中定义的全局变量的使用,例如使用MyObject,但您无法真实地跟踪prototype扩展方法的使用情况.
JavaScript是一种动态类型的语言,所以没有任何实用的方法可以让任何工具知道a,如果传递出g函数,它是一个Array,所以如果f()在它上面调用它就有一个依赖.它只能在运行时确定哪些变量包含哪些类型,因此要找出你需要一个解释器并且你已经完成了一个图灵完备的问题.
更不用说完全违反静态分析的JavaScript的其他动态方面,例如通过方括号表示法获取属性,可怕的eval或超时中的字符串或事件处理程序属性.
我认为这真的是一个非首发.您可能更好地手动跟踪依赖关系,但通过将相关函数分组到模块中来简化它,这些模块将成为依赖关系跟踪的基本单元.好的,你会提供一些技术上需要的功能,但希望不要太多.
命名每个模块也是一个好主意,因此每个调用的位置非常清楚,可以很容易地手动控制依赖关系(例如,通过// uses: ThisModule, ThatModule顶部的注释).
由于内置原型的扩展更难以跟踪,因此将它们保持在最低限度.扩展例如.Array在indexOf没有它们的浏览器中包含ECMAScript第五版方法(例如)作为所有脚本将使用的基本修正是一件好事.向现有原型添加全新的任意功能是值得怀疑的.
Chr*_*ris 10
您是否尝试过使用RequireJS或LabJS等依赖管理器?我注意到在这个帖子中没有人提到它们.
来自http://requirejs.org/docs/start.html:
在main.js中,您可以使用require()来加载您需要运行的任何其他脚本:
require(["helper/util"], function(util) {
//This function is called when scripts/helper/util.js is loaded.
//If util.js calls define(), then this function is not fired until
//util's dependencies have loaded, and the util argument will hold
//the module value for "helper/util".
});
Run Code Online (Sandbox Code Playgroud)
您也可以嵌套这些依赖项,因此helper/util可能需要其他一些文件.
正如@bobince已经建议的那样,对JavaScript程序进行静态分析是一个几乎不可能解决的问题.谷歌Closure编译器在某种程度上做到了这一点,但它也依赖于JSDoc评论的外部帮助.
我有一个类似的问题,即找到JS文件应该在之前的项目中连接的顺序,并且因为有大量的JS文件,手动更新包含顺序似乎太乏味了.相反,为了我的目的,我坚持使用某些约定构成依赖关系,并基于此并使用简单的正则表达式 :)我能够生成正确的包含顺序.
该解决方案使用拓扑排序算法生成依赖关系图,然后按顺序列出文件,以满足所有依赖关系.由于每个文件基本上都是使用MooTools语法的伪类,因此只有3种方法可以为我的情况创建依赖项.
new关键字实例化某个其他类的对象时.对于通用目的来说,这是一个简单的,绝对是破碎的解决方案,但它对我很有帮助.如果您对该解决方案感兴趣,可以在此处查看代码 - 它位于Ruby中.
如果您的依赖项更复杂,那么您可以使用注释和一些自行开发的语法手动列出每个JS文件本身的依赖项,例如:
// requires: Array
// requires: view/TabPanel
// requires: view/TabBar
Run Code Online (Sandbox Code Playgroud)
然后读取每个JS文件,解析需求注释,并构建一个依赖图,它将为您提供所需的包含顺序.
有一个工具可以自动检测这些依赖项并选择它们的加载方式,这将是一件好事.今天最好的解决方案有点粗糙.我为我的特殊需求创建了一个依赖管理器,我想将其添加到列表中(Pyramid Dependency Manager).它具有一些解决一些独特用例的关键功能.
一些示例代码,以显示它在开发过程中的工作原理
文件:dependencyLoader.js
//Set up file dependencies
Pyramid.newDependency({
name: 'standard',
files: [
'standardResources/jquery.1.6.1.min.js'
]
});
Pyramid.newDependency({
name:'lookAndFeel',
files: [
'styles.css',
'customStyles.css',
'applyStyles.js'
]
});
Pyramid.newDependency({
name:'main',
files: [
'createNamespace.js',
'views/buttonView.view', //contains just html code for a jquery.tmpl template
'models/person.js',
'init.js'
],
dependencies: ['standard','lookAndFeel']
});
Run Code Online (Sandbox Code Playgroud)
Html文件
<head>
<script src="standardResources/pyramid-1.0.1.js"></script>
<script src="dependencyLoader.js"></script>
<script type="text/javascript">
Pyramid.load('main');
</script>
</head>
Run Code Online (Sandbox Code Playgroud)
它确实需要您维护单个文件来管理依赖项.我正在考虑创建一个程序,可以根据头中的包含自动为您生成加载器文件,但由于它处理许多不同类型的依赖项,将它们保存在一个文件中可能实际上更好.
| 归档时间: |
|
| 查看次数: |
18650 次 |
| 最近记录: |