我正在重构我的JavaScript库以利用单个命名空间。我们有~200个模块,以前将它们自己注册为jQuery插件或全局对象(坏)。在过去的分配中,为了让Intellisense工作,我为每个模块添加了模块引用(我想从中获取Intellisense)
/// <reference path="" />
到每个模块文件的顶部。
关于之前任务的一切都是有缺陷的,脆弱的和不优雅的。
我希望在新的时代解决这个问题。这种重构的主要目标之一是让新开发人员可以轻松地开始在库中工作,而Intellisense非常有用。
目前,我将所有* .js文件连接到一个nameSpace-vsdoc.js文件中。使用vsdoc语法记录每个类的每个方法。每个模块都使用单个vsdoc引用。这样可行,但它很笨拙。智能感知比以前好300%,但仍然不够准确。它错过了很多我的xml文档,并且它没有很好地递归到返回甚至稍微复杂的对象的方法/类中。
YUI Doc提供了一种从JsDoc语法构建文档的方法,但这对Intellisense没有帮助。深刻的灵魂 - 谷歌搜索未能揭示任何第三方解决方案。
是否有任何工具以更智能的智能方式生成VsDocs?
更新:
经过一些广泛的思考,测试和渐进式重构,我有一个looks like this jsFiddle的基本命名空间。
这使我能够在自执行函数中编写松散耦合的模块,这些函数在命名空间中注册所需的方法。所有模块都以:
开头/// <reference path="~/js/NameSpace-vsdoc.js" />
我使用一个简单的Perl脚本生成这个vsdoc,我已将其附加到VS 2010构建事件:
use strict;
my $dir = $ARGV[0];
my $destfile = "$dir\\js\\NameSpace-vsdoc.js";
unlink($destfile);
my $js = "";
$js .= extractFile("$dir\\js\\_first-vsdoc.js");
$js .= extractFile("$dir\\js\\NameSpace.js");
$js .= extract("$dir\\js\\modules");
#Add additional directories as needed
$js .= extractFile("$dir\\js\\_last-vsdoc.js");
open(VSDOC, "> $destfile") or die("Cannot open vsdoc file: $destfile ; $!");
print VSDOC $js;
close(VSDOC);
sub extract
{
my $ret = "";
my $path = $_[0];
opendir(JSDIR, $path) or die("Cannot open js directory: $path ; $!");
while((my $filename = readdir(JSDIR)))
{
if($filename =~ /.*\.js$/ &&
$filename !~ /-vsdoc/ &&
$filename !~ /_first/ &&
$filename !~ /_last/ &&
$filename !~ /.min\.js/)
{
$ret .= extractFile("$path\\$filename");
}
}
closedir(JSDIR);
return $ret;
}
sub extractFile
{
my $ret = "";
my $filename = $_[0];
open(JSFILE, "$filename") or die("Cannot open js file: $filename ; $!");
while((my $line = <JSFILE>))
{
if($line !~ m/-vsdoc\.js/ )
{
$ret .= $line;
}
}
close(JSFILE);
return $ret;
}
printf("Finished generating NameSpace vsdoc.\n");
_first-vsdoc.js和_last-vsdoc.js文件将整个内容包装在一个自执行的函数中。然后我根据需要/适当将结果vsdoc传递给Closure Compiler,YUI Compressor和Uglify。
这个过程比以前好多了,但它仍然没有缺陷。
从头开始,在引用NameSpace-vsdoc.js的NewModule.js中,我得到了正确的Intellisense:
Ns.register() //visible
Ns.controls.register() //visible
Ns.actions.register() //visible
但是,当我将NewModule.js定义为(并编译)时:
(function _alertClosure() {
Ns.register('alert', function alert(someText) {
///insert proper vsdoc style comment
});
}());
我没有获得适当的Intellisense:
Ns.alert() //no Intellisense help
这令人困惑,因为它在子命名空间上运行良好。我不得不这样做:
Ns.alert = Ns.alert || Ns.register('alert', function ....
编译,突然(显然)智能感知按预期工作。
Intellisense使用链接方法使用jQuery的vsdoc(我在构建这个过程时已经仔细研究过)并且jQuery不依靠y.x = y.x || new x()
技巧来实现它。
所以这是修改后的问题:从结构的角度来看,我可以在jQuery的vsdoc和我自己之间看到的唯一可辨别的差异是jQuery在中组装整个命名空间关闭。我的命名空间和每个模块都包含在各个闭包中。相比之下,我的vsdoc看起来像是一串很长的自执行函数。
与放弃封闭/模块模式相关的风险太大;而且很难孤立地检验这个假设。当库很小时Intellisense运行良好,因此无法生成数千个“Javascript Intellisense消息:C:\\ js \ NameSpace-vsdoc.js(40:16):对象需要”错误。
想法?
答案 0 :(得分:1)
我同意@Ilya Volodin。 ReSharper是视觉工作室的绝佳工具。 我只使用它一个月,我不能没有。
这不能回答你的问题,但对你来说非常有用。
这是一个很好的总结,可以在官方网站上找到:
“ReSharper是一款着名的Productivité工具,它使Microsoft Visual Studio IDE更加出色。全球数以千计的.NET开发人员不知道他们是如何在没有ReSharper的代码检查,自动重构,快速发货和编码协助的情况下实现的。”