dev*_*rts 7 node.js typescript yarnpkg yarn-workspaces
我正在尝试使用纱线建立一个monorepo。我对如何使用项目引用设置打字稿感到困惑,以便正确解决问题。
例如,如果我有一个类似的文件夹结构
/cmd
/client
Run Code Online (Sandbox Code Playgroud)
我想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/**/*"
]
}
Run Code Online (Sandbox Code Playgroud)
与一个 package.json
{
"name": "cmd",
"version": "1.0.0",
"dependencies": {
"client": "^1.0.0",
}
}
Run Code Online (Sandbox Code Playgroud)
在此模型中,cmd并client使用在tsconfig中设置的outDir和sourceRoot字段进行编译。这意味着所有的编译的JavaScript进入dist/的子文件夹cmd/dist和client/dist
如果我现在尝试和引用类client为cmd像
import Foo from 'client/src/foo'
Run Code Online (Sandbox Code Playgroud)
IDE十分乐意解决此问题,因为它似乎是通过typescript references属性进行映射的。
但是,已编译的javascript归结为
const foo_1 = require("client/src/foo");
Run Code Online (Sandbox Code Playgroud)
但是,实际内置的javascript在中client/dist/src/foo,因此在运行时这永远无法工作。
另一方面,如果我不使用sourceRoots和outDirs并将javascript与Typescript文件内联在同一文件夹中,则一切正常(但使存储库变脏,并且需要自定义gitignores以排除事物)
任何人都无法阐明如何正确设置带有纱线工作区的Typescript 3.x monorepo,以使事情正常进行吗?
a13*_*300 55
我创建了一个 Github存储库,以便更容易地遵循以下代码描述:
TypeScriptProject References可以编译由多个较小的 TypeScript 项目组成的 TypeScript 项目,每个项目都有一个tsconfig.json文件。(来源:项目参考文档)
我们有一个tsconfig.json只管理其子项目的根文件。该references属性指定每个包含有效tsconfig.json文件的目录。如果我们现在使用--build选项 ( tsc --build tsconfig.json)构建项目,那么我们指定了应该编译的项目,但我们没有指定应该编译项目的构建顺序。
{
"references": [
{ "path": "./client" },
{ "path": "./cmd" }
],
"files": [],
"include": [],
"exclude": ["**/node_modules"]
}
Run Code Online (Sandbox Code Playgroud)
为了正确指定构建顺序,我们需要向文件添加一个references属性cmd/tsconfig.json。这告诉编译器client/在我们编译之前它首先需要编译cmd/:
cmd/tsconfig.json:
{
"extends": "../tsconfig.packages.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"
},
"references": [
{
"path": "../client"
}
]
}
Run Code Online (Sandbox Code Playgroud)
建造顺序
client/
^
|
|
cmd/
Run Code Online (Sandbox Code Playgroud)
最佳实践是每个子项目都有自己的package.json文件,其中包含main属性和name集合。在我们的示例中,包 (cmd/和client/) 都有一个main属性指向index.jsTypeScriptoutDir目录 (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
Run Code Online (Sandbox Code Playgroud)
client/packages.json
{
"name": "client",
"version": "1.0.0",
"main": "dist/index",
...
}
Run Code Online (Sandbox Code Playgroud)
这是重要的,我们添加client/为依赖于cmd/packages.json这样的模块解析算法可以发现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
}
}
Run Code Online (Sandbox Code Playgroud)
cmd/src/index.ts
import Foo from 'client';
console.log(Foo())
Run Code Online (Sandbox Code Playgroud)
纱线设置很容易。Yarn 将所有包添加到下面node_modules而不是:
cmd/node_modulesclient/node_modules要启用纱线工作区,请将workspaces属性和private: true属性添加到<root>/package.json文件中。
<root>/package.json
{
"private": true,
"workspaces": [
"cmd",
"client"
],
"name": "yarn_workplace",
"version": "1.0.0"
...
}
Run Code Online (Sandbox Code Playgroud)
在cmd/与client/包symlinked下<root>/node_modules/目录:
cmd/包使用定义文件client/dist/index.d.ts获取类型信息,而不是直接使用 TypeScript 文件。