如何使用带有打字稿和出文件夹的毛线工作区? [英] How to use yarn workspaces with typescript and out folders?
问题描述
我正在尝试使用纱线建立一个单体仓库.我对如何使用项目引用设置打字稿感到困惑,以便正确解决问题.
I'm trying to set up a monorepo using yarn. I'm confused as to how to set up typescript with project references such that things resolve properly.
例如,如果我有类似的文件夹结构
For example, if I have a folder structure like
/cmd
/client
我希望cmd
依赖于我可能拥有的client
:
And I want cmd
to depend on client
I could have:
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
In this model both cmd
and client
get compiled with an outDir
and sourceRoot
field set in their tsconfig. This means all their compiled javascript goes into the dist/
subfolder of cmd/dist
and client/dist
如果现在我尝试将client
中的类引用到cmd
中,例如
If now I try and reference a class from client
into cmd
like
import Foo from 'client/src/foo'
IDE很高兴解决此问题,因为它似乎是通过typescript references
属性映射的.
The IDE is perfectly happy to resolve this since it seems that its mapped via the typescript references
property.
但是,已编译的javascript可以归结为
However, the compiled javascript boils down to a
const foo_1 = require("client/src/foo");
但是,实际内置的javascript是在client/dist/src/foo
中,因此在运行时这永远行不通.
However, the actual built javascript is in client/dist/src/foo
, so at runtime this never works.
另一方面,如果我不使用sourceRoots和outDirs并将javascript与打字稿文件内联在同一文件夹中,则一切正常(但使存储库变脏,并且需要自定义gitignores排除事物)
On the flip side, if I don't use sourceRoots and outDirs and have the javascript inlined with the typescript files at the same folder everything does work (but makes the repo dirty and requires custom gitignores to exclude things)
任何人都无法阐明如何使用纱线工作区正确设置打字稿3.x monorepo以便工作正常吗?
Can anyone shed any light on how to properly set up a typescript 3.x monorepo with yarn workspaces such that things just work?
推荐答案
我创建了一个Github 存储库使其更容易遵循以下代码描述:
I created a Github Repository to make it easier to follow the following code description:
TypeScript Project References
使编译由多个较小的TypeScript项目组成的TypeScript项目成为可能,每个项目都有一个tsconfig.json
文件. (来源:项目参考文档)
TypeScript Project References
make it possible to compile a TypeScript project that consist of multiple smaller TypeScript projects, each project having a tsconfig.json
file. (Source: Project References Documentation)
我们有一个根tsconfig.json
文件,该文件仅管理其子项目. references
属性指定每个目录都包含有效的tsconfig.json
文件.如果现在使用--build
选项(tsc --build tsconfig.json
)构建项目,则我们指定了应编译的项目,但未指定应在其中编译项目的构建顺序
We have a root tsconfig.json
file that only manages its sub-projects. The references
property specifies the directories that each contain a valid tsconfig.json
file. If we now build the project with the --build
option (tsc --build tsconfig.json
) then we specified the projects which should be compiled, but we didn't specified the build order in which the projects should be compiled.
{
"references": [
{ "path": "./client" },
{ "path": "./cmd" }
],
"files": [],
"include": [],
"exclude": ["**/node_modules"]
}
要正确指定构建顺序,我们需要在 cmd/tsconfig.json
文件中添加references
属性.这告诉编译器在我们编译cmd/
之前首先需要编译client/
:
To correctly specify the build order we need to add a references
property to the cmd/tsconfig.json
file. This tells the compiler that it first needs to compile client/
before we compile cmd/
:
cmd/tsconfig.json
:
{
"extends": "../tsconfig.packages.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"
},
"references": [
{
"path": "../client"
}
]
}
构建订单
client/
^
|
|
cmd/
节点设置
最佳做法是每个子项目都有自己的package.json
文件,其中 strong> main
属性和 cmd/
和client/
)都具有main
属性,该属性指向TypeScript
Node Setup
Best practice is that each sub-project has its own package.json
file with the 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
directory (cmd/dist/index.js
and 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/
作为依赖项添加到 cmd/packages.json
,以便模块解析算法可以找到client/dist/index.js
当我们在TypeScript代码import Foo from 'client';
中导入它时:
It is important that we add the client/
as dependency to the cmd/packages.json
so the module resolution algorithm can find the client/dist/index.js
when we import it in our TypeScript code 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
下,而不是:
Yarn Setup
The yarn setup is easy. Yarn adds all packages under node_modules
instead of:
-
cmd/node_modules
-
client/node_modules
cmd/node_modules
client/node_modules
要启用纱线工作区,请添加workspaces
属性和private: true
属性设置为<root>/package.json
文件.
To enable yarn workspaces add the workspaces
property and the private: true
property to the <root>/package.json
file.
<root>/package.json
{
"private": true,
"workspaces": [
"cmd",
"client"
],
"name": "yarn_workplace",
"version": "1.0.0"
...
}
cmd/
和client/
软件包位于<root>/node_modules/
目录下的symlinked
:
The cmd/
and client/
packages are symlinked
under the <root>/node_modules/
directory:
- 要启用代码导航,必须首先构建项目
- 每个包裹都独立存在.
cmd/
包将定义文件client/dist/index.d.ts
用于类型信息,而不是直接使用TypeScript文件.
- To enable code navigation one has to first build the project
- Every package lives on its own. The
cmd/
package uses the definition fileclient/dist/index.d.ts
for type information instead of using the the TypeScript files directly.
这篇关于如何使用带有打字稿和出文件夹的毛线工作区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!