如何通过不同的项目共享Typescript模块而不复制共享模块?

如何通过不同的项目共享Typescript模块而不复制共享模块?,typescript,Typescript,我有两个文件夹:shared和project1在文件夹节点中。我正在开发位于节点文件夹中的几个独立节点项目 在共享的中,我有一个index.ts,它包含一个默认导出。tsconfig.json中的outdir参数是/dist。构建时,目录如下所示: node/shared/ src/ index.ts dest/ index.js tsconfig.json

我有两个文件夹:
shared
project1
在文件夹
节点中。我正在开发位于
节点
文件夹中的几个独立节点项目

在共享的
中,我有一个index.ts,它包含一个默认导出。tsconfig.json中的
outdir
参数是
/dist
。构建时,目录如下所示:

node/shared/
           src/
              index.ts
           dest/
               index.js
           tsconfig.json
           ...
node/project1/
             src/
                index.ts
             dist/
                 index.js
在project1中,我有index.ts,在“正常”情况下,在构建时,目录如下所示:

node/shared/
           src/
              index.ts
           dest/
               index.js
           tsconfig.json
           ...
node/project1/
             src/
                index.ts
             dist/
                 index.js
我的意图是使用
shared
来包含可由
节点
文件夹中的不同项目使用的共享实用程序

当我在
project1/src/index.ts
中的“./../shared/src/index.js”中有一条语句
import shared from./../shared/src/index.js”时,
dest
文件夹中的编译输出会变得疯狂:

node/project1/
             src/
                index.js
             dest/
                 shared/
                       src/
                          index.js  <- copied from the shared project
                 project1/
                         src/
                            index.js
这可能吗?或者将共享模块转换为NPM包是唯一的方法吗?

您可以使用

节点/
项目1/
距离/
index.js
src/
索引
tsconfig.json
共享/
距离/
index.js
索引d.ts
src/
索引
package.json
tsconfig.json
共享 该设置与普通项目类似,只是必须启用该设置

shared/tsconfig.json

{
“编译器选项”:{
//引用的项目必须启用复合标志
“复合”:没错,
“rootDir”:“/src”,
“outDir”:“/dist”,
“模块”:“commonjs”
}
}
shared/package.json

{
“名称”:“共享”,
“版本”:“0.0.1”,
“主要”:“/dist”,
“脚本”:{
“构建”:“tsc”
},
“依赖性”:{
“类型脚本”:“^4.0.3”
}
}
shared/src/index.ts

export default 'foo'
declare const _default: "foo";
export default _default;
输出
shared/dist/index.js
不太令人兴奋:

“严格使用”;
导出。u_esModule=true;
导出[“默认”]=“foo”;
由于
composite
编译器标志,还将生成类型定义:

shared/dist/index.d.ts

export default 'foo'
declare const _default: "foo";
export default _default;
项目
project1/tsconfig.json

在这里,您指定您正在引用
共享
模块

{
“编译器选项”:{
“rootDir”:“/src”,
“outDir”:“../dist”
},
“参考资料”:[
{“路径”:“./共享”}
]
}
project1/package.json

您可以使用
tsc--build
tsc-b
)。如果引用的项目已过期,则会自动重建这些项目。但是,请注意,有一些特定的仅生成标志和

{
“名称”:“项目1”,
“版本”:“0.0.1”,
“主要”:“/dist”,
“脚本”:{
“构建”:“tsc-b”
},
“依赖性”:{
“类型脚本”:“^4.0.3”
}
}
project1/src/index.ts

export default 'foo'
declare const _default: "foo";
export default _default;
像平常一样使用共享模块

import foo from '../../shared'

console.log(foo)
project1/dist/index.js

源代码编译如下:

“严格使用”;
导出。u_esModule=true;
var shared_1=需要(“..../shared”);
console.log(shared_1[“default”]);
如您所见,它正确地从
节点/shared
目录导入共享模块,而不是将文件复制到
dist

您不需要指定文件的完整路径(
。/../shared/dist/index.js
),因为共享项目的
package.json
main
字段设置为
/dist
,解析为
/dist/index.js
。TypeScript知道Node.js将把
require
解析为适当的文件,因此知道
共享的
模块的类型


如果您没有在
package.json
中提供
main
条目,则需要使用
import foo from'../../shared/dist'

谢谢,这很有趣。我有一些问题。为什么
import
语句不必指定文件,即index.js?它如何推断index.ts中的模块定义?共享模块不是位于
。/../shared/dist
(从
project1/dist
)中吗?@OldGeezer我编辑了我的答案以澄清这一点。这是因为
package.json
中指定了模块的入口点,TypeScript知道并使用它来定位类型定义。