假设我有两个具有以下文件结构的项目
/my-projects/
/project-a/
lib.ts
app.ts
tsconfig.json
/project-b/
app.ts // import '../project-a/lib.ts'
tsconfig.json
Run Code Online (Sandbox Code Playgroud)
我想消费也lib.ts
位于.怎么做?project-a
project-b
将其作为NPM模块发布 - 绝对不希望如此,对于这样一个简单的用例来说,这是一种过度杀伤力.我只想在两个项目之间共享一个文件.
使用import '../project-a/lib.ts'
- 不起作用,TypeScript抱怨
'lib.ts' is not under 'rootDir'. 'rootDir' is expected to contain all source files.
tsconfig.json
一个级别,因此将涵盖project-a
和project-b
-不能做到这一点,打字稿配置是这些项目略有不同.它也不是很方便,不想这样做.还有其他方法吗?
Thd*_*hdK 17
Since Typescript 3.0 this can be done with Project References.
Typescript docs: https://www.typescriptlang.org/docs/handbook/project-references.html
I believe you would have to move lib.ts into a small ts project called something like 'lib'
The lib project should have a tsconfig containing:
// lib/tsconfig.json
{
"compilerOptions": {
/* Truncated compiler options to list only relevant options */
"declaration": true,
"declarationMap": true,
"rootDir": ".",
"composite": true,
},
"references": [] // * Any project that is referenced must itself have a `references` array (which may be empty).
}
Run Code Online (Sandbox Code Playgroud)
Then in both project-a and project-b add the reference to this lib project into your tsconfig
// project-a/ts-config.json
// project-b/ts-config.json
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node"
// ...
},
"references": [
{ "path": "../lib" }
]
}
Run Code Online (Sandbox Code Playgroud)
In the lib project. Create a file index.ts which should export all your code you want to share with other projects.
// lib/index.ts
export * from 'lib.ts';
Run Code Online (Sandbox Code Playgroud)
Now, let's say lib/lib.ts looks like this:
// lib/lib.ts
export const log = (message: string) => console.log(message);
Run Code Online (Sandbox Code Playgroud)
You can now import the log function from lib/lib.ts in both project-a and project-b
// project-a/app.ts
// project-b/app.ts
import { log } from '../lib';
log("This is a message");
Run Code Online (Sandbox Code Playgroud)
Before your intelissense will work, you now need to build both your project-a and project-b using:
tsc -b
Run Code Online (Sandbox Code Playgroud)
Which will first build your project references (lib in this case) and then build the current project (project-a or project-b).
The typescript compiler will not look at the actual typescript files from lib. Instead it will only use the typescript declaration files (*.d.ts) generated when building the lib project.
That's why your lib/tsconfig.json file must contain:
"declaration": true,
Run Code Online (Sandbox Code Playgroud)
However, if you navigate to the definition of the log function in project-a/app.ts using F12 key in Visual Studio code, you'll be shown the correct typescript file. At least, if you have correctly setup your lib/tsconfig.json with:
"declarationMap": true,
Run Code Online (Sandbox Code Playgroud)
I've create a small github repo demonstrating this example of project references with typescript:
https://github.com/thdk/TS3-projects-references-example
Ole*_*zky 10
这可以通过使用tsconfig.json中'CompilerOptions'的'paths'属性来实现
{
"compilerOptions": {
"paths": {
"@otherProject/*": [
"../otherProject/src/*"
]
}
},
}
Run Code Online (Sandbox Code Playgroud)
下面是文件夹结构的屏幕截图。
以下是引用其他ts-project的tsconfig.json的内容
{
"compilerOptions": {
"baseUrl": "./",
"outDir": "./tsc-out",
"sourceMap": false,
"declaration": false,
"moduleResolution": "node",
"module": "es6",
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2017",
"dom"
],
"paths": {
"@src/*": [ "src/*" ],
"@qc/*": [
"../Pti.Web/ClientApp/src/app/*"
]
}
},
"exclude": [
"node_modules",
"dist",
"tsc-out"
]
}
Run Code Online (Sandbox Code Playgroud)
以下是引用其他项目的出口的进口声明。
import { IntegrationMessageState } from '@qc/shared/states/integration-message.state';
Run Code Online (Sandbox Code Playgroud)
小智 6
我认为@qqilihq 的回应是正确的 - 尽管手动维护node_modules
目录的内容存在明显的潜在问题。
我通过使用lerna 来管理这个很幸运(尽管那里有许多其他类似的工具,例如纱线工作区似乎有些相似,尽管我自己没有使用过它们)。
我只是事先声明,这对于您所谈论的内容来说可能有点重量级,但它确实为您的项目提供了很大的灵活性,可以在未来发展。
使用此模式,您的代码最终将类似于:
/my-projects/
/common-code/
lib.ts
tsconfig.json
package.json
/project-a/
app.ts (Can import common-code)
tsconfig.json
package.json (with a dependency on common-code)
/project-b/
app.ts (Can import common-code)
tsconfig.json
package.json (with a dependency on common-code)
Run Code Online (Sandbox Code Playgroud)
这里的一般理论是该工具在您的内部库node_modules
与其依赖包的目录之间创建符号链接。
我在这样做时遇到的主要陷阱是
common-code
必须在其文件中同时设置amain
和types
属性package.json
common-code
必须先编译它的任何依赖项才能依赖它common-code
必须declaration
在其设置为 truetsconfig.json
我在这方面的总体经验非常积极,因为一旦您理解了基本思想,其中就没有什么“魔法”,它只是一组碰巧共享一个目录的标准节点包。
qqi*_*ihq -5
在类似的场景中,我也想避免必须执行 NPM 发布的开销,我采用了以下结构(经过大量的尝试、错误和失败的尝试):
\n\n/my-projects/\n\n /node_modules/\n /my-lib/\n lib.ts\n tsconfig.json\n package.json\n\n /project-a/\n app.ts\n tsconfig.json\n\n /project-b/\n app.ts \n tsconfig.json\n
Run Code Online (Sandbox Code Playgroud)\n\n中心思想是将共享内容移动到node_modules
各个项目上方的目录(这利用了 NPM 加载机制,该机制将开始在当前目录中查找依赖项,然后向上移动)。
因此,project-a
现在project-b
可以通过import { Whatever } from \'my-lib\'
.
笔记:
\n\n就我而言,my-lib
实际上仅适用于共享类型(即子目录.d.ts
中的文件lib
)。这意味着,我不需要明确地构建my-lib
,我的my-lib/package.json
外观如下:
{\n "name": "my-types",\n "version": "0.0.0",\n "private": true,\n "types": "lib/index"\n}\n
Run Code Online (Sandbox Code Playgroud)如果my-lib
包含可运行的代码,您\xe2\x80\x99显然需要构建my-lib
,以便.js
生成文件,并向公开主文件的"main"
属性添加一个属性。package.json
.js
最重要的是:尽管它的名称如此,/my-projects/node_modules
但仅包含自定义代码,没有安装的依赖项(它们实际上位于各个项目project-a/node_modules
和中project-b/node_modules
)。这意味着,\xe2\x80\x99 有一个显式的 git 忽略设置,该设置会忽略/node_modules
提交的目录。
这是一个干净的解决方案吗?也许不是。它解决了我的问题吗?是的。我很高兴听到改进建议吗?绝对地!
\n 归档时间: |
|
查看次数: |
4960 次 |
最近记录: |