JavaScript 依赖管理

我目前正在维护大量的 JS 文件,并且依赖问题越来越严重.现在我将每个函数放在一个单独的文件中,并且我手动维护一个数据库来计算函数之间的依赖关系.

I am currently maintaining a large number of JS files and the dependency issue is growing over my head. Right now I have each function in a separate file and I manually maintain a database to work out the dependencies between functions.

这我想自动化.例如,如果我有函数 f

This I would like to automate. For instance if I have the function f

Array.prototype.f = function() {};

在另一个函数 g 中被引用

which is referenced in another function g

MyObject.g = function() {
    var a = new Array();
    a.f();
};

我希望能够检测到 g 正在引用 f.

I want to be able to detect that g is referencing f.

我该怎么做?我从哪里开始?我是否需要实际编写一个编译器,或者我可以调整 Spidermonkey 吗?其他人已经这样做了吗?

How do I go about this? Where do I start? Do I need to actually write a compiler or can I tweak Spidermonkey for instance? Did anyone else already do this?

非常感谢任何让我入门的指针

Any pointers to get me started is very much appreciated

谢谢多克

推荐答案

虽然理论上你可以编写一个静态分析工具来检测其他文件中定义的全局变量的使用,例如 MyObject 的使用,但你无法实际跟踪 prototype 扩展方法的使用情况.

Whilst you could theoretically write a static analysis tool that detected use of globals defined in other files, such as use of MyObject, you couldn't realistically track usage of prototype extension methods.

JavaScript 是一种动态类型的语言,因此任何工具都无法知道 a,如果从 g 函数传递出来,是一个 Array,因此如果在其上调用 f(),则存在依赖关系.它只会在运行时确定哪些变量包含哪些类型,因此要找出您需要一个解释器并且您已经让自己成为一个图灵完备的问题.

JavaScript is a dynamically-typed language so there's no practical way for any tool to know that a, if passed out of the g function, is an Array, and so if f() is called on it there's a dependency. It only gets determined what variables hold what types at run-time, so to find out you'd need an interpreter and you've made yourself a Turing-complete problem.

更不用说 JavaScript 的其他动态方面完全无视静态分析,例如通过方括号表示法获取属性、可怕的 eval 或超时字符串或事件处理程序属性.

Not to mention the other dynamic aspects of JavaScript that completely defy static analysis, such as fetching properties by square bracket notation, the dreaded eval, or strings in timeouts or event handler attributes.

我认为这真的有点不适合.您可能最好手动跟踪依赖项,但通过将相关功能分组到模块中来简化它,这将是您的依赖项跟踪的基本单元.好的,您将引入更多技术上需要的功能,但希望不要太多.

I think it's a bit of a non-starter really. You're probably better of tracking dependencies manually, but simplifying it by grouping related functions into modules which will be your basic unit of dependency tracking. OK, you'll pull in a few more functions that you technically need, but hopefully not too much.

为每个模块命名也是一个好主意,因此每个调用的去向非常清晰,从而可以轻松地手动控制依赖关系(例如,通过 //使用:ThisModule, ThatModule 顶部注释).

It's also a good idea to namespace each module, so it's very clear where each call is going, making it easy to keep the dependencies in control manually (eg. by a // uses: ThisModule, ThatModule comment at the top).

由于内置原型的扩展更难跟踪,因此请将它们保持在最低限度.扩展例如.Array 在浏览器上包含 ECMAScript 第五版方法(如 indexOf)是一件好事,作为所有脚本都将使用的基本修复.向现有原型添加全新的任意功能是值得怀疑的.

Since extensions of the built-in prototypes are trickier to keep track of, keep them down to a bare minimum. Extending eg. Array to include the ECMAScript Fifth Edition methods (like indexOf) on browsers that don't already have them is a good thing to do as a basic fixup that all scripts will use. Adding completely new arbitrary functionality to existing prototypes is questionable.

相关文章