3 回答
TA贡献1993条经验 获得超5个赞
这是可能的,事实证明,这并不困难。
解决方案之所以不明显是因为Typescript依赖rootDir
来决定输出的目录结构(请参阅Typescript的bossman中的此注释),并且只能导入输出或包依赖项中包含的代码。
如果设置
rootDir
为项目的根目录,则将其package.json
发射到的根目录outDir
并可以将其导入。但是随后,您的编译src
文件将写入outDir/src
。如果设置
rootDir
为src
,则其中的文件将编译为的根outDir
。但是现在编译器将无处可放package.json
,因此它发出“错误,因为项目似乎配置错误”(老板的话)。
解决方案:使用单独的Typescript子项目
一个打字稿项目被规定tsconfig文件,是自包含的,并有效地通过它的边界rootDir
。这是一件非常好的事情,因为它符合封装原则。
您可以在各自的目录中和各自的tsconfig中拥有多个项目(例如,主库和一组lib)。它们之间的依赖关系使用Typescript项目引用在tsconfig文件中声明。
我承认,术语“项目”是一个可怜的项目,直觉上是指整个项目,但是在这种情况下已经采用了“模块”和“包”。将它们视为“子项目”,这将更有意义。
我们将src
目录和包含的根目录package.json
视为单独的项目。每个tsconfig
文件都有其自己的文件。
给src 目录自己的项目。
./src/tsconfig.json:
{
"compilerOptions": {
"rootDir": ".",
"outDir": "../dist/",
"resolveJsonModule": true
},
"references": [ // this is how we declare a dependency from
{ "path": "../" } // this project to the one at the root dir`
]
}
给根目录自己的项目。
./tsconfig.json:
{
"compilerOptions": {
"rootDir": ".",
"outDir": ".", // if out path for a file is same as its src path, nothing will be emitted
"resolveJsonModule": true,
"composite": true // required on the dependency project for references to work
},
"files": [ // by whitelisting the files to include, TS won't automatically
"package.json" // include all source below root, which is the default.
]
}
跑去tsc --build src 瞧瞧!
这将构建src项目。因为它声明了对根项目的引用,所以它也会构建该项目,但前提是该项目已过时。因为根tsconfig与dir具有相同的目录,所以outDirtsc只会对package.json配置为编译的一个文件不执行任何操作。
这对于monorepos来说很棒
您可以通过将模块/库/子项目放在它们自己的子目录中并为其提供自己的tsconfig来隔离它们。
您可以使用Project References显式管理依赖项,也可以模块化构建:
从链接的文档中:
您可以大大缩短构建时间
期待已久的功能是用于TypeScript项目的智能增量构建。在3.0中,您可以将--build标志与一起使用tsc。实际上,这是一个新的入口点,tsc它的行为更像是构建协调器,而不是简单的编译器。
运行tsc --build(tsc -b简称)将执行以下操作:
查找所有引用的项目
检测它们是否最新
以正确的顺序构建过时的项目
不必担心对在命令行上传递的文件进行排序-tsc如果需要,将对它们进行重新排序,以便始终先构建依赖项。
强制组件之间的逻辑分离
以更好的新方式组织代码。
这也很容易:
src/tsconfig.json
即使您根本没有代码,此tsconfig仍可以放在所有常用设置中(其他设置将从那里继承),并且将使您可以轻松tsc --build src地构建整个项目(并--force从头开始构建它)。
{
"compilerOptions": {
"rootDir": ".",
"outDir": "../build/",
"resolveJsonModule": true,
"composite": true
},
// this root project has no source of its own
"files": [],
// but building this project will build all of the following:
"references": [
{ "path": "./common" }
{ "path": "./projectA" }
// include all other sub-projects here
]
}
src/common/tsconfig.json
由于common没有引用,因此导入仅限于其目录和中的目标npm_modules。我相信,您甚至可以通过赋予它自己来限制后者package.json。
{
"compilerOptions": {
"rootDir": ".",
"outDir": "../../build/common",
"resolveJsonModule": true,
"composite": true
}
}
src/projectA/tsconfig.json
由于声明了引用,所以projectA可以导入common。
{
"compilerOptions": {
"rootDir": ".",
"outDir": "../../build/libA",
"resolveJsonModule": true,
"composite": true
},
"references": [
{ "path": "../common" }
]
}
TA贡献1780条经验 获得超5个赞
目前不可能。Typescript编译器尝试保留您的目录结构。
例如,您的项目如下所示:
src/
shared/
index.ts
index.ts
package.json
tsconfig.json
您tsconfig.json包含:
{
"compilerOptions": {
"outDir": "./build",
"module": "commonjs",
"target": "es6",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true
},
"include": [
"src/**/*"
]
}
如您所见,该文件不包含rootDir属性,但是当您调用tsc命令编译该项目时,输出将如下所示:
build/
shared/
index.js
index.js
输出不包含src文件夹,因为在我的代码中,我只是导入并在src文件夹内部使用,例如:
src/index.ts
import someName from './shared';
然后,build/index.js将如下所示:
...
const shared_1 = __importDefault(require("./shared"));
...
如您所见- require("./shared"),这意味着它可以很好地与build文件夹结构配合使用。
导入“外部”模块时出现“问题”
import packageJson from '../package.json';
那么,“后退”动作-“ ../”会发生什么?如果您希望您的输出结构为:
build/
package.json
index.js
然后,他们如何配合使用const packageJson = __importDefault(require("../package.json"));。然后,Typescript编译器尝试保持项目结构:
build/
package.json
src/
index.js
对于monorepo项目,我认为您需要为每个库创建声明文件,然后references在tsconfig文件中使用设置结束。前任:
在该./lib01文件夹中,lib导入./lib02其代码。Tsconfig文件将类似于:
{
"compilerOptions": {
"declarationDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"],
"references": [ // here
{
"path": "../lib02"
}
]
}
lib02的 tsconfig.json
{
"compilerOptions": {
"declarationDir": "dist",
"rootDir": "src",
"composite": true // importance.
}
}
添加回答
举报