如何使用带有 typescript 和 out 文件夹的纱线工作区?
How to use yarn workspaces with typescript and out folders?
我正在尝试使用 yarn 设置一个 monorepo。我对如何使用项目引用设置打字稿以使事情正确解决感到困惑。
例如,如果我有这样的文件夹结构
/cmd
/client
我希望 cmd
依赖于 client
我可以:
cmd/tsconfig.json
:
{
"compilerOptions": {
"types": ["reflect-metadata", "jest"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"declaration": true,
"importHelpers": true,
"composite": true,
"target": "esnext"
"sourceRoot": "src",
"outDir": "dist"
},
"references": [
{
"path": "../client"
}
],
"include": [
"src/**/*"
]
}
有 package.json
{
"name": "cmd",
"version": "1.0.0",
"dependencies": {
"client": "^1.0.0",
}
}
在此模型中,cmd
和 client
都在其 tsconfig 中使用 outDir
和 sourceRoot
字段集进行编译。这意味着他们所有编译的 javascript 进入 cmd/dist
和 client/dist
的 dist/
子文件夹
如果现在我尝试将 client
中的 class 引用到 cmd
中,例如
import Foo from 'client/src/foo'
IDE 非常乐意解决这个问题,因为它似乎是通过打字稿 references
属性.
映射的
然而,编译后的 javascript 归结为
const foo_1 = require("client/src/foo");
然而,实际构建的 javascript 在 client/dist/src/foo
中,因此在运行时这永远不会起作用。
另一方面,如果我不使用 sourceRoots 和 outDirs,并且将 javascript 与同一文件夹中的打字稿文件内联,一切正常(但会使回购变脏并需要自定义 gitignores 来排除事物)
任何人都可以阐明如何使用 yarn 工作区正确设置 typescript 3.x monorepo 以便一切正常吗?
我已经设置了一个 monorepo I,其中包含我在 this repository.
中使用 Yarn Workspaces 和 Typescript 在我的项目中经常使用的一些配置
我不知道这个设置是否解决了你的问题,但你不需要在 Typescript 配置中指定你的包。当您使用 Yarn Workspaces 时,它会将您在根 node_modules
中定义的所有包链接到您在根 package.json
中定义的工作区包 属性:
"workspaces": {
"packages": [
"packages/**/*"
],
"nohoist": []
}
在 yarn install
之后,根 node_modules
有 client
和 cmd
作为链接文件夹。
使用此配置,您可以简单地在工作区内的任何包中导入任何包。例如:
// cmd/src/index.ts
import { name } from 'client';
const otherName = 'cmd' + name;
console.log(otherName);
我创建了一个 Github Repository 以便更容易遵循以下代码说明:
代码说明
TypeScript Project References
可以编译由多个较小的 TypeScript 项目组成的 TypeScript 项目,每个项目都有一个 tsconfig.json
文件。 (来源:Project References Documentation)
TypeScript 设置
我们有一个仅管理其子项目的根 tsconfig.json
文件。 references
属性 指定每个包含有效 tsconfig.json
文件的目录。如果我们现在使用 --build
选项 (tsc --build tsconfig.json
) 构建项目,那么我们指定了应该编译的项目,但我们没有指定 构建顺序 应在其中编译项目。
{
"references": [
{ "path": "./client" },
{ "path": "./cmd" }
],
"files": [],
"include": [],
"exclude": ["**/node_modules"]
}
要正确指定 构建顺序,我们需要将 references
属性 添加到 cmd/tsconfig.json
文件。这告诉编译器在我们编译 cmd/
:
之前它首先需要编译 client/
cmd/tsconfig.json
:
{
"extends": "../tsconfig.packages.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"
},
"references": [
{
"path": "../client"
}
]
}
构建顺序
client/
^
|
|
cmd/
节点设置
最佳做法是每个子项目都有自己的 package.json
文件和 main
property and the name
set. In our example both packages (cmd/
and client/
) have a main
property pointing to the index.js
file in the TypeScript outDir
目录(cmd/dist/index.js
和 client/dist/index.js
)。
项目结构:
tsconfig.json
cmd/
tsconfig.json
package.json
src/
index.ts
dist/ #artifacts
index.js
client/
tsconfig.json
package.json
src/
index.ts
dist/ #artifacts
index.js
client/packages.json
{
"name": "client",
"version": "1.0.0",
"main": "dist/index",
...
}
重要 我们添加 client/
作为对 [=42= 的依赖] 这样当我们在 TypeScript 代码中导入它时,模块解析算法可以找到 client/dist/index.js
import Foo from 'client';
:
cmd/packages.json
{
"name": "cmd",
"version": "1.0.0",
"main": "dist/index",
"dependencies": {
"client": "1.0.0" // important
}
}
cmd/src/index.ts
import Foo from 'client';
console.log(Foo())
纱线设置
纱线设置很简单。 Yarn 添加 node_modules
下的所有包,而不是:
cmd/node_modules
client/node_modules
要启用 yarn workspaces 添加 workspaces
属性 和 private: true
属性 到 <root>/package.json
文件。
<root>/package.json
{
"private": true,
"workspaces": [
"cmd",
"client"
],
"name": "yarn_workplace",
"version": "1.0.0"
...
}
cmd/
和client/
包在<root>/node_modules/
目录下symlinked
:
备注
- 要启用代码导航,必须先构建项目
- 每个包都独立存在。
cmd/
包使用定义文件 client/dist/index.d.ts
来获取类型信息,而不是直接使用 TypeScript 文件。
我正在尝试使用 yarn 设置一个 monorepo。我对如何使用项目引用设置打字稿以使事情正确解决感到困惑。
例如,如果我有这样的文件夹结构
/cmd
/client
我希望 cmd
依赖于 client
我可以:
cmd/tsconfig.json
:
{
"compilerOptions": {
"types": ["reflect-metadata", "jest"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"declaration": true,
"importHelpers": true,
"composite": true,
"target": "esnext"
"sourceRoot": "src",
"outDir": "dist"
},
"references": [
{
"path": "../client"
}
],
"include": [
"src/**/*"
]
}
有 package.json
{
"name": "cmd",
"version": "1.0.0",
"dependencies": {
"client": "^1.0.0",
}
}
在此模型中,cmd
和 client
都在其 tsconfig 中使用 outDir
和 sourceRoot
字段集进行编译。这意味着他们所有编译的 javascript 进入 cmd/dist
和 client/dist
dist/
子文件夹
如果现在我尝试将 client
中的 class 引用到 cmd
中,例如
import Foo from 'client/src/foo'
IDE 非常乐意解决这个问题,因为它似乎是通过打字稿 references
属性.
然而,编译后的 javascript 归结为
const foo_1 = require("client/src/foo");
然而,实际构建的 javascript 在 client/dist/src/foo
中,因此在运行时这永远不会起作用。
另一方面,如果我不使用 sourceRoots 和 outDirs,并且将 javascript 与同一文件夹中的打字稿文件内联,一切正常(但会使回购变脏并需要自定义 gitignores 来排除事物)
任何人都可以阐明如何使用 yarn 工作区正确设置 typescript 3.x monorepo 以便一切正常吗?
我已经设置了一个 monorepo I,其中包含我在 this repository.
中使用 Yarn Workspaces 和 Typescript 在我的项目中经常使用的一些配置我不知道这个设置是否解决了你的问题,但你不需要在 Typescript 配置中指定你的包。当您使用 Yarn Workspaces 时,它会将您在根 node_modules
中定义的所有包链接到您在根 package.json
中定义的工作区包 属性:
"workspaces": {
"packages": [
"packages/**/*"
],
"nohoist": []
}
在 yarn install
之后,根 node_modules
有 client
和 cmd
作为链接文件夹。
使用此配置,您可以简单地在工作区内的任何包中导入任何包。例如:
// cmd/src/index.ts
import { name } from 'client';
const otherName = 'cmd' + name;
console.log(otherName);
我创建了一个 Github Repository 以便更容易遵循以下代码说明:
代码说明
TypeScript Project References
可以编译由多个较小的 TypeScript 项目组成的 TypeScript 项目,每个项目都有一个 tsconfig.json
文件。 (来源:Project References Documentation)
TypeScript 设置
我们有一个仅管理其子项目的根 tsconfig.json
文件。 references
属性 指定每个包含有效 tsconfig.json
文件的目录。如果我们现在使用 --build
选项 (tsc --build tsconfig.json
) 构建项目,那么我们指定了应该编译的项目,但我们没有指定 构建顺序 应在其中编译项目。
{
"references": [
{ "path": "./client" },
{ "path": "./cmd" }
],
"files": [],
"include": [],
"exclude": ["**/node_modules"]
}
要正确指定 构建顺序,我们需要将 references
属性 添加到 cmd/tsconfig.json
文件。这告诉编译器在我们编译 cmd/
:
client/
cmd/tsconfig.json
:
{
"extends": "../tsconfig.packages.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"
},
"references": [
{
"path": "../client"
}
]
}
构建顺序
client/
^
|
|
cmd/
节点设置
最佳做法是每个子项目都有自己的 package.json
文件和 main
property and the name
set. In our example both packages (cmd/
and client/
) have a main
property pointing to the index.js
file in the TypeScript outDir
目录(cmd/dist/index.js
和 client/dist/index.js
)。
项目结构:
tsconfig.json
cmd/
tsconfig.json
package.json
src/
index.ts
dist/ #artifacts
index.js
client/
tsconfig.json
package.json
src/
index.ts
dist/ #artifacts
index.js
client/packages.json
{
"name": "client",
"version": "1.0.0",
"main": "dist/index",
...
}
重要 我们添加 client/
作为对 [=42= 的依赖] 这样当我们在 TypeScript 代码中导入它时,模块解析算法可以找到 client/dist/index.js
import Foo from 'client';
:
cmd/packages.json
{
"name": "cmd",
"version": "1.0.0",
"main": "dist/index",
"dependencies": {
"client": "1.0.0" // important
}
}
cmd/src/index.ts
import Foo from 'client';
console.log(Foo())
纱线设置
纱线设置很简单。 Yarn 添加 node_modules
下的所有包,而不是:
cmd/node_modules
client/node_modules
要启用 yarn workspaces 添加 workspaces
属性 和 private: true
属性 到 <root>/package.json
文件。
<root>/package.json
{
"private": true,
"workspaces": [
"cmd",
"client"
],
"name": "yarn_workplace",
"version": "1.0.0"
...
}
cmd/
和client/
包在<root>/node_modules/
目录下symlinked
:
备注
- 要启用代码导航,必须先构建项目
- 每个包都独立存在。
cmd/
包使用定义文件client/dist/index.d.ts
来获取类型信息,而不是直接使用 TypeScript 文件。