typescript 两个项目之间的跨项目引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21233108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cross-project references between two projects
提问by Nickon
Is it possible to make a reference between two TypeScript projects? Assume we have the following project structure:
是否可以在两个 TypeScript 项目之间进行引用?假设我们有以下项目结构:
Module1.ts
contains:
Module1.ts
包含:
module TestModule {
export interface Interface1 {
}
}
Module2.ts
contains:
Module2.ts
包含:
module TestModule {
export interface Interface2 extends Interface1 {
}
}
Test1
is referenced in Test2
. I get an error Could not find symbol 'Interface1'
in Module2.ts
. It works within one project, but I don't know how to make it visible from the other project... Maybe it's not possible for now.
Test1
中引用Test2
。我Could not find symbol 'Interface1'
在Module2.ts
. 它在一个项目中工作,但我不知道如何让它从另一个项目中可见......也许现在不可能。
[Edit 1.]
When I try to use TestModule.Interface1
pattern, I get the same error (said in different way). But the IntelliSense sees my Interface1
:
[编辑 1.]
当我尝试使用TestModule.Interface1
模式时,我得到相同的错误(以不同的方式说)。但是 IntelliSense 看到了我的Interface1
:
[Edit 2.]
I have noticed I can't use files from the other project. Even if I have a correct reference (/// <reference ...
) added and linked all the files in my 1st project.
[编辑 2.]
我注意到我不能使用其他项目中的文件。即使我/// <reference ...
添加了正确的参考 ( ) 并链接了我的第一个项目中的所有文件。
采纳答案by David Sherret
There's lots of ways you can do this.
有很多方法可以做到这一点。
Option 1 - Project References (TypeScript 3.0+)
选项 1 - 项目参考(TypeScript 3.0+)
If you are using TypeScript 3.0 then look at using project references. Read more here.
如果您使用的是 TypeScript 3.0,请查看使用项目引用。在这里阅读更多。
Option 2 - Build script
选项 2 - 构建脚本
Use something like gulp-typescript, grunt-ts, or just a batch script to copy the files over into a folder in the main project.
使用gulp-typescript、grunt-ts 之类的东西,或者只是一个批处理脚本来将文件复制到主项目的文件夹中。
Alternatively, run a build eventin Visual Studio that will copy the files over to the main project.
或者,在 Visual Studio 中运行生成事件,将文件复制到主项目。
Option 3 - npm package
选项 3 - npm 包
If you use npm, you could create a package for your other project. Then you can use your package in your main project. Specifying a local dependencyis a good way to do this or by using something like sinopia, which is a private repository server. I've never used it, but it looks like it would work well.
如果你使用 npm,你可以为你的其他项目创建一个包。然后你可以在你的主项目中使用你的包。指定本地依赖项是实现此目的的好方法,或者使用诸如sinopia 之类的东西,它是一个私有存储库服务器。我从来没有用过它,但看起来它会很好用。
Option 4 - NuGet package
选项 4 - NuGet 包
You could look into creating a nuget packageand then installing it locally.
您可以考虑创建一个 nuget 包,然后在本地安装它。
Option 5 - --declaration --outDir
compiler option
选项 5 ---declaration --outDir
编译器选项
You can set the --outDir
compiler option or the outDir
property in tsconfig.json
with the directory to your other project then also compile it with --declaration
so that it generates the declaration files (.d.ts
) too. For example: --declaration --outDir ../Test1/External
.
您可以将目录中的--outDir
编译器选项或outDir
属性设置tsconfig.json
为您的其他项目,然后也可以编译它,--declaration
以便它也生成声明文件 ( .d.ts
)。例如:--declaration --outDir ../Test1/External
。
Original Answer (Using --out
)
原始答案(使用--out
)
You can do something similar in Visual Studio if you right click on your library project and click properties. In the TypeScript Build
tab, check off the option to Combine JavaScript output into file
and specify the location in your main project you want it to go (Ex. $(SolutionDir)/TypedApp/External/TypedLibrary.js
). Then also check off Generate declaration files
in order to generate a .d.ts
file.
如果您右键单击您的库项目并单击属性,您可以在 Visual Studio 中执行类似的操作。在TypeScript Build
选项卡中,勾选选项Combine JavaScript output into file
并指定您希望它在主项目中的位置(例如$(SolutionDir)/TypedApp/External/TypedLibrary.js
)。然后还要检查Generate declaration files
以生成.d.ts
文件。
Once this is done, build your library project and then include the .js
, and .d.ts
in your main project. Include the .js
file in your html and reference the .d.ts
in your typescript files.
完成此操作后,构建您的库项目,然后将.js
, 和包含.d.ts
在您的主项目中。将该.js
文件包含在您的 html 中并.d.ts
在您的打字稿文件中引用。
Each time you rebuild the library project, it will automatically update the main project with the changes.
每次重建库项目时,它都会自动更新主项目的更改。
回答by Martyn0627
The solution suggested by @dhsto works but I have found an alternative using linked folders. I have written about it in detail in this article, here is how it can be implemented:
@dhsto 建议的解决方案有效,但我找到了使用链接文件夹的替代方法。我在本文中详细介绍了它,以下是它的实现方式:
It can be achieved by creating a folder to hold your references, I like to name this “_referencesTS”, the folder will contain all of the links to files from Test1. This can be done individually but would become very cumbersome if it had to be done for each new TS file. Linking a folder however will link all of the files beneath it, this can be done by editing the csproj file.
可以通过创建一个文件夹来保存您的引用来实现,我喜欢将其命名为“_referencesTS”,该文件夹将包含来自 Test1 的所有文件链接。这可以单独完成,但如果必须为每个新的 TS 文件完成,就会变得非常麻烦。然而,链接一个文件夹将链接它下面的所有文件,这可以通过编辑 csproj 文件来完成。
To edit the file right click the Test2 project and click “Unload Project
”, then right click the project and click “Edit Test2.csproj
”. Navigate to the <ItemGroup>
that contains the <TypeScriptCompile>
tags and insert the code below:
要编辑文件,请右键单击Test2 项目并单击“ Unload Project
”,然后右键单击该项目并单击“ Edit Test2.csproj
”。导航到<ItemGroup>
包含<TypeScriptCompile>
标签的 并插入以下代码:
<TypeScriptCompile Include="..\Test1\**\*.ts">
<Link>_referencesTS\%(RecursiveDir)%(FileName)</Link>
</TypeScriptCompile>
Replace the relative path to the location of your TS files in Test1, this uses the wildcarding (*) to link all .ts files (dictated by the *.ts
) within all sub folders (dictated by the \**\
)..
替换 Test1 中 TS 文件位置的相对路径,这使用通配符 (*) 链接*.ts
所有子文件夹(由指示)中的所有 .ts 文件(由指示\**\
)。
The TS files within these folders will now appear linked within Test2, allowing for automatic typescript referencing.
这些文件夹中的 TS 文件现在将在 Test2 中显示为链接,允许自动打字稿引用。
Note: The only downside to this approach is that when a new file is added to Test1 within a linked folder, the user has to unload and load the project or close and open the solution for it to appear in Test2.
注意:这种方法的唯一缺点是,当一个新文件被添加到链接文件夹中的 Test1 时,用户必须卸载和加载项目或关闭并打开解决方案以使其出现在 Test2 中。
回答by Micah Zoltu
Frustrated with the state of affairs, I wrote a NuGet package that mostly solves this problem. Using the NuGet package you can just add a reference from one project to another and it will do the work of copying files around in a way that is safe from accidentally editing the wrong file and still gives intellisense and debugging.
对现状感到沮丧,我编写了一个 NuGet 包,主要解决了这个问题。使用 NuGet 包,您只需将一个项目的引用添加到另一个项目,它将以一种安全的方式复制文件,避免意外编辑错误的文件,并且仍然提供智能感知和调试。
Details can be found in the Readme.md, or you can just install the NuGet package and run (I recommend at least reading the how to use section).
详细信息可以在 Readme.md 中找到,或者您可以只安装 NuGet 包并运行(我建议至少阅读如何使用部分)。
https://github.com/Zoltu/BuildTools.TypeScript.FromReferences
https://github.com/Zoltu/BuildTools.TypeScript.FromReferences
回答by Allan.C
I just want to add to the answer of David Sherret that the lib files to the TypedApp project could be added as Link files instead of depending on post build events. I'm having some issues with post build events in big solutions with a lot of projects, and the link files are now working ok for me. (I cannot add a comment to the answer because I only have 35 reputation points).
我只想补充一下 David Sherret 的答案,TypedApp 项目的 lib 文件可以作为链接文件添加,而不是依赖于构建后事件。我在有很多项目的大型解决方案中遇到了一些后期构建事件的问题,并且链接文件现在对我来说可以正常工作。(我无法在答案中添加评论,因为我只有 35 个声望点)。
回答by Aebsubis
If you need to share the code between multiple projects you can always create a symbolic link on each project where you need it. http://en.wikipedia.org/wiki/Symbolic_link
如果您需要在多个项目之间共享代码,您始终可以在需要的每个项目上创建一个符号链接。 http://en.wikipedia.org/wiki/Symbolic_link
回答by lightmotive
basarat's answer is the closest to being the most reliable solution for cross-project TypeScript references. However, when merging shared TypeScript code with a referencing project's TypeScript (important, for example, if you need to target different ECMAScript versions), the Source Map file doesn't resolve to the shared project's directories, so debugging won't work (in fact, Visual Studio often crashes after adding breakpoints to the files referenced in another project).
basarat 的答案最接近于成为跨项目 TypeScript 引用的最可靠解决方案。但是,当将共享 TypeScript 代码与引用项目的 TypeScript 合并时(很重要,例如,如果您需要针对不同的 ECMAScript 版本),Source Map 文件不会解析到共享项目的目录,因此调试将不起作用(在事实上,Visual Studio 经常在向另一个项目中引用的文件添加断点后崩溃)。
Linked files of any kind (Visual Studio links and symbolic links) don't work with debugging in any system (Visual Studio, Chrome, WebStorm, etc.)--linked files essentially don't exist to the ASP.NET debugger, nor any other debugger; they exist only in Visual Studio.
任何类型的链接文件(Visual Studio 链接和符号链接)都不适用于任何系统(Visual Studio、Chrome、WebStorm 等)中的调试——ASP.NET 调试器基本上不存在链接文件,也不存在任何其他调试器;它们仅存在于 Visual Studio 中。
Please see this question/answer indicating what has worked great for both solid code maintenance and debugging in Visual Studio, Chrome, and Firefox, while still retaining the ability to combine shared code with the referencing projects' code (important, for example, if you need to target different ECMAScript versions): Visual Studio: How to debug TypeScript in a shared project using IIS Express and cross-project references (no linking or duplicating files)
请参阅此问题/答案,指出哪些对 Visual Studio、Chrome 和 Firefox 中的可靠代码维护和调试非常有效,同时仍保留将共享代码与引用项目代码相结合的能力(例如,重要的是,如果您需要针对不同的 ECMAScript 版本):Visual Studio:如何使用 IIS Express 和跨项目引用在共享项目中调试 TypeScript(无链接或复制文件)
回答by basarat
If you are compiling with the --out
parameter you can simply reference Module1.ts from Module2.ts using /// <reference
To learn more about code organization patterns in TypeScript see http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1
如果您使用--out
参数进行编译,您可以简单地使用 Module2.ts 引用 Module1.ts/// <reference
要了解有关 TypeScript 中代码组织模式的更多信息,请参阅http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1
What visual studio language services sees available (which is everything) is different from what you compile and actually have available at runtime.
Visual Studio 语言服务看到的可用(即一切)与您编译的和在运行时实际可用的不同。
回答by Ron Newcomb
The accepted answer disallows debugging in Visual Studio when a breakpoint is set in the Sharedproject. (At best the debugger will stop on a line in the compiled javascript, but not the original Typescript and certainly not in its original project location.)
当在共享项目中设置断点时,接受的答案不允许在 Visual Studio 中进行调试。(充其量调试器将停在已编译的 javascript 中的一行上,但不会停在原始 Typescript 上,当然也不会停在其原始项目位置。)
In the Shared project's properties, let's say that Combine Javascript output into [a single] fileis checked and set to AllShared.js
, which also makes a AllShared.d.ts
file because Generate declaration filesis checked, and also makes a AllShared.js.map
because Generate source mapsis checked.
在 Shared 项目的属性中,假设将Combine Javascript output into [a single] file选中并设置为AllShared.js
,这也会生成一个AllShared.d.ts
文件,因为选中了Generate declaration files,也生成了一个AllShared.js.map
因为选中了Generate source maps。
The referencing project should NOT copy or link these files in the way the accepted solution does. Instead:
引用项目不应以已接受的解决方案的方式复制或链接这些文件。反而:
Part 1, in the referencing project, create /typings/tsd.d.ts
if it doesn't already exist, and append to the bottom of that file the line ///<reference path="../../SharedProject/AllShared.d.ts" />
. Once this is done, (and at least one successful compile of SharedProject is done), Intellisense and the Typescript compiler should see Interface1 etc. (You'll likely get a red squiggly line underlining the statement if the path/file doesn't exist, which is nice.)
第 1 部分,在引用项目中,/typings/tsd.d.ts
如果尚不存在则创建,然后在该文件的底部附加行///<reference path="../../SharedProject/AllShared.d.ts" />
. 完成此操作后(并且至少成功编译了一次 SharedProject),Intellisense 和 Typescript 编译器应该会看到 Interface1 等(如果路径/文件不存在,您可能会看到一条红色波浪线在该语句下划线) ,这很好。)
Part 2, in the referencing project's index.html
, add the line <script src="http://localhost:29944/AllShared.js"></script>
before that project's own script tags. The localhost part comes from the Shared project's Properties, Web tab, Project Url. (Both 'IIS Express' and 'Local IIS' work.)
第 2 部分,在引用项目的 中index.html
,<script src="http://localhost:29944/AllShared.js"></script>
在该项目自己的脚本标记之前添加一行。本地主机部分来自共享项目的属性、Web 选项卡、项目 URL。(“IIS Express”和“本地 IIS”都可以工作。)
Now when you run the referencing project, you should see Internet Explorer** request the relevant files from their respective "websites". Visual Studio breakpoints should be hit regardless whether they're in SharedProject or the referencing project.
现在,当您运行引用项目时,您应该看到 Internet Explorer** 从它们各自的“网站”请求相关文件。无论 Visual Studio 断点是在 SharedProject 中还是在引用项目中,都应该被命中。
. Although this solution works without gulp/grunt/powershell, Visual Studio's Combine Javascript output into one filedoesn't glue together the files in any particular order, and it will eventually break your code. Then you'll need to add Gulp/etc. to the referencing project to insert a <script src="http://localhost:29944...
tag for each file in Shared***, because keeping index.html
updated by hand is a poor option. (Adding Gulp to the Shared project, to concat the .js and .d.ts files into singles runs into an issue with .js.map files, which can't be simply concatted.)
. 尽管此解决方案无需 gulp/grunt/powershell 即可工作,但 Visual Studio 的将Javascript 输出合并到一个文件中不会以任何特定顺序将文件粘合在一起,并且最终会破坏您的代码。然后你需要添加 Gulp/etc. 到引用项目为<script src="http://localhost:29944...
Shared*** 中的每个文件插入一个标签,因为index.html
手动保持更新是一个糟糕的选择。(将 Gulp 添加到 Shared 项目,将 .js 和 .d.ts 文件合并为单个文件会遇到 .js.map 文件的问题,不能简单地合并。)
** IE and VS are both Microsoft products, so IE really works better if you want to use VS's breakpoints and debugger instead of a web browser's.
** IE 和 VS 都是 Microsoft 产品,因此如果您想使用 VS 的断点和调试器而不是 Web 浏览器的断点和调试器,则 IE 确实能更好地工作。
*** Gulp doesn't like injecting urls, only filepaths. Given HTML comments in index.html
like <!-- SharedStuff:js --><!-- endinject -->
, circumvent this like so:
*** Gulp 不喜欢注入 url,只注入文件路径。给定 HTML 注释index.html
like <!-- 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('./'));
});