2014-01-20 33 views
24

是否可以在两个TypeScript项目之间进行引用?假设我们有以下项目结构:两个项目之间的跨项目引用

Structure

Module1.ts包含:

module TestModule { 
    export interface Interface1 { 
    } 
} 

Module2.ts包含:

module TestModule { 
    export interface Interface2 extends Interface1 { 
    } 
} 

Test1Test2被引用。我在Module2.ts中收到错误Could not find symbol 'Interface1'。它在一个项目中工作,但我不知道如何使其从另一个项目中可见...也许现在是不可能的。

[编辑1]
当我尝试使用TestModule.Interface1模式,我得到了同样的错误(以不同的方式表示)。但是,智能感知看到我Interface1

IntelliSense

[编辑2]
我注意到我不能从其他项目中使用的文件。即使我有一个正确的参考(/// <reference ...)添加并链接了我的第一个项目中的所有文件。

回答

17

有很多方法可以做到这一点。

选项1 - 构建脚本

使用类似gulp-typescriptgrunt-ts,或者只是一个批处理脚本文件在复制到文件夹中的主要项目。

或者,在Visual Studio中将run a build event复制到主项目的文件。

选择2 - NPM包

如果您使用NPM,你可以为你的其他项目中创建一个包。然后你可以在你的主项目中使用你的软件包。 Specifying a local dependency是一个很好的方法来做到这一点,或使用sinopia这是一个私人存储库服务器。我从来没有使用它,但它看起来会很好。

选择3 - NuGet包

你可以看看creating a nuget package,然后installing it locally

选项4 - --declaration --outDir编译器选项

可以设置--outDir编译器选项或outDir财产tsconfig.json与目录到其他项目,然后还与--declaration,使其生成申报文件进行编译( .d.ts)。例如:--declaration --outDir ../Test1/External

原来的答案(使用--out

你可以在Visual Studio中类似的东西,如果你就在您的库项目,然后单击属性。在TypeScript Build选项卡中,勾选Combine JavaScript output into file选项,并指定您想要的主项目中的位置(例如,$(SolutionDir)/TypedApp/External/TypedLibrary.js)。然后还请检查关闭Generate declaration files以生成.d.ts文件。

Setting up project for automated builds

一旦做到这一点,你建库项目,然后在您的主项目的.js,和.d.ts。在您的HTML中包含.js文件,并在打字稿文件中引用.d.ts

Include files in main project

每次重新编译库项目,它会自动更新与变化的主要项目。

+1

正是我想要做的!:)在19h奖励,因为现在不能授予它: S – Nickon

+2

太好了,我很高兴能帮到你!只是一个附加说明...说你有一个情况,你想跨多个项目共享一个“打字稿库”。为此,您需要提出自己的构建方法,包括生成'.js','.d.ts'和'.js.map'文件(如上所示),然后将这些文件复制到每个项目需要它。在生成文件('Project> Properties> Build Events> Post-build event command line')后,您可以使用Post-build事件进行复制。 –

+0

是的,我发现它,当你给我第一个答案:) – Nickon

1

如果与--out参数编制可以简单地从Module2.ts使用/// <reference要了解更多关于打字稿代码组织模式参考Module1.ts看到http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1

什么的Visual Studio语言服务可看到(这是所有内容)与您编译的内容不同,并且在运行时实际可用。

+1

我知道我可以使用'/// Nickon

10

@dhsto建议的解决方案有效,但我找到了使用链接文件夹的替代方案。我有written about it in detail in this article,这里是它如何实现:

它可以通过创建一个文件夹来保存您的引用,我喜欢命名这个“_referencesTS”,该文件夹将包含所有从Test1文件的链接。这可以单独完成,但如果必须为每个新的TS文件完成,将变得非常麻烦。然而,链接文件夹会链接下面的所有文件,这可以通过编辑csproj文件来完成。

要编辑文件,请右键单击Test2项目,然后单击“Unload Project”,然后右键单击该项目并单击“Edit Test2.csproj”。导航到<ItemGroup>包含<TypeScriptCompile>标签并插入下面的代码:

<TypeScriptCompile Include="..\Test1\**\*.ts"> 
    <Link>_referencesTS\%(RecursiveDir)%(FileName)</Link> 
</TypeScriptCompile> 

替换到您的Test1 TS文件的位置的相对路径,这个使用通配符(*),以连接所有.ts文件(由*.ts指定)(由\**\指定)。

这些文件夹中的TS文件现在将显示在Test2中链接,允许自动键入打印引用。

注意:这种方法唯一的缺点是,当一个新文件被添加到链接文件夹中的Test1时,用户必须卸载并加载项目或关闭并打开解决方案,以使其出现在Test2中。

+0

这个解决方案看起来很棒!我可以在我的projectA资源管理器树中看到我的projectB的链接文件,但是我无法导入此引用以用于在projectA中定义的类中。任何想法? – Aebsubis

+0

如果这些文件真的存在,但是与您在此建议的链接解决方案不同,它似乎对.ts和.d.ts起作用。 – Aebsubis

+0

这很好。我只是包括.. \ Source \ ** \ *。*,因为我想为nuget创建两个相同的静态文件项目。一个以源代码作为内容,另一个嵌入所有的静态文件。优秀! – reckface

4

我只想添加David Sherret的答案,即TypedApp项目的lib文件可以作为链接文件添加,而不是依赖于发布后生成事件。我在使用大量项目的大型解决方案中发布构建事件时遇到了一些问题,现在链接文件对我来说工作正常。 (我不能给答案添加评论,因为我只有35点声望点)。

1

basarat的答案是最接近跨项目TypeScript参考的最可靠的解决方案。但是,将共享的TypeScript代码与引用项目的TypeScript合并(例如,如果您需要定位不同的ECMAScript版本时很重要),源代码映射文件不会解析为共享项目的目录,因此调试将不起作用(在事实上,在将断点添加到另一个项目中引用的文件后,Visual Studio经常崩溃)。

任何类型的链接文件(Visual Studio链接和符号链接)都不适用于任何系统(Visual Studio,Chrome,WebStorm等)中的调试 - 链接文件基本上不存在于ASP中。 NET调试器,也没有任何其他调试器;它们只存在于Visual Studio中。

请参阅此问题/答案,指出在Visual Studio,Chrome和Firefox中对固体代码进行维护和调试的优点,同时仍保留将共享代码与引用项目代码结合的功能(重要的例如,如果您需要针对不同的ECMAScript版本):Visual Studio: How to debug TypeScript in a shared project using IIS Express and cross-project references (no linking or duplicating files)

6

我对事态感到沮丧,于是我写了一个NuGet包来解决这个问题。使用NuGet软件包,您可以将一个项目的引用添加到另一个项目中,并且它会以避免意外编辑错误文件并仍然提供智能感知和调试的安全方式执行复制文件的工作。

详细信息可在Readme.md找到,或者你可以安装NuGet包和运行(我建议至少阅读如何使用部分)。当一个断点在共享项目设置

https://github.com/Zoltu/BuildTools.TypeScript.FromReferences

+1

+1这似乎很好。非常感谢你创造它。如果您可以选择不通过js.map和.ts文件进行复制,那么我会更喜欢它,因为在我的用例中我不需要这些文件。 – soupy1976

+0

@ soupy1976我不介意添加这些东西作为选项,但由于我不使用VS来编写TypeScript(我现在使用VSCode),我可能不会自己做出这些改变。我鼓励尽管提交PR!这是复制发生的地方,您需要获得一些配置,然后将它们包装在if块中:https://github.com/Zoltu/BuildTools.TypeScript.FromReferences/blob/master/code/FromReferencesTask。cs#L62-L65 –

+0

这真的很好,不幸的是我的Visual Studio来抱怨说,当我为.ts文件生成一个d.ts文件时,我有重复的声明。当我不在源代码控制中包含文件时,tfsbuilds会抱怨你的nuget找不到所需的d.ts. 呃,我很困惑! – Schoof

0

接受的答案不允许调试在Visual Studio。 (充其量,调试器将停止在编译后的javascript中的一行,但不是原始的Typescript,当然也不在其原始的项目位置。)

在共享项目的属性中,我们假设将结合到[a单]文件检查并设置为AllShared.js,这也使得AllShared.d.ts文件,因为生成申报文件被选中,并且也使得AllShared.js.map因为生成源映射检查。

引用项目不应以接受的解决方案的方式复制或链接这些文件。相反:

第1部分在引用项目中创建/typings/tsd.d.ts(如果它尚不存在),并在该文件的底部追加行///<reference path="../../SharedProject/AllShared.d.ts" />。一旦完成(至少一次SharedProject的成功编译完成),Intellisense和Typescript编译器应该看到Interface1等等(如果路径/文件不存在,您可能会得到一条红色的波浪线,这很好。)

第2部分,在参考项目的index.html中,在该项目自己的脚本标记之前添加行<script src="http://localhost:29944/AllShared.js"></script>。localhost部分来自Shared项目的Properties,Web选项卡Project Url。 (“IIS Express”和“本地IIS”均可用)。

现在,当您运行引用项目时,您应该看到Internet Explorer **从各自的“网站”请求相关文件。不管它们是在SharedProject还是在引用项目中,都应该命中Visual Studio断点。


。尽管此解决方案没有使用gulp/grunt/powershell,但Visual Studio的将Javascript输出合并到一个文件中并不会将文件按任何特定顺序粘合在一起,并且最终会破坏您的代码。然后你需要添加Gulp/etc。在参考项目中为共享***中的每个文件插入一个<script src="http://localhost:29944...标记,因为手动更新index.html是一个糟糕的选项。 (将Gulp添加到共享项目中,将.js和.d.ts文件连接成单曲会遇到无法简单连接的.js.map文件的问题。)

** IE和VS都是微软的产品,所以如果你想使用VS的断点和调试器代替Web浏览器,那么IE的效果会更好。

*** Gulp不喜欢注入URL,只有文件路径。由于HTML注释中index.html<!-- SharedStuff:js --><!-- endinject -->,绕过这个像这样:

gulp.task('insert-into-html', [], function() { 
    var common = gulp.src(['../SharedProject/**/*.js'], { read: false }); 
    return gulp.src('./index.html') 
      .pipe(inject(common, { 
       relative: true, 
       name: "SharedStuff", 
       transform: function (filepath) { 
        return '<script src="http://localhost:29944/'+filepath+'"></script>'; 
       } 
      })) 
      .pipe(gulp.dest('./')); 
}); 
+0

没有推荐的解决方案的作品,他们都不能用在我的情况:( – Fis