Kou*_*sha 41 javascript typescript
我正在尝试package.json
在我的 TypeScript 应用程序中导入:
import packageJson from '../package.json';
Run Code Online (Sandbox Code Playgroud)
我的tsconfig.json
包含以下内容:
{
"compilerOptions": {
"rootDir": "./src/"
"outDir": "./dist/",
"baseUrl": ".",
"resolveJsonModule": true
}
}
Run Code Online (Sandbox Code Playgroud)
问题是当我编译这个时,我得到
error TS6059: File '/path/to/package.json' is not under 'rootDir' '/path/to/app/src/'. 'rootDir' is expected to contain all source files.
我不知道我理解这个问题,因为这两个./src/
与/.dist
具有相同的父..
,所以打字稿可能只是独自离开import '../package.json'
和它的工作无论从rootDir
或outDir
。
无论如何,我尝试了以下方法,但结果并不令人满意:
rootDir
- 编译有效,但dist
将包含dist/src
我不想要的outDir
- 然后src
被.js
文件污染(.js.map
如果sourceMap
是真的)@ts-ignore
- 编译停止导入的文件../package.json
有什么办法解决这个限制,以保持生成的文件中dist
,并允许从父目录中导入rootDir
?
vas*_*vas 42
这是可能的,事实证明,并不难。
解决方案不明显的原因是因为 typescript 依赖rootDir
来决定输出的目录结构(请参阅来自 Typescript 的 bossman 的评论),并且只能导入包含在输出或包依赖项中的代码。
rootDir
为项目package.json
的根目录,outDir
则会发送到根目录并可以导入。但是随后您编译的src
文件被写入outDir/src
.rootDir
为src
,则其中的文件将编译为outDir
. 但是现在编译器没有地方发出package.json
,所以它发出“一个错误,因为项目似乎配置错误”(老板的话)。一个打字稿项目被规定tsconfig文件,是自包含的,并有效地通过它的边界rootDir
。这是一件非常好的事情,因为它符合封装原则。
您可以拥有多个项目(例如一个主项目和一组库),每个项目都在它们自己的目录中并具有自己的 tsconfig。它们之间的依赖关系在 tsconfig 文件中使用 Typescript Project References 声明。
我承认,术语“项目”是一个糟糕的词,因为它直观地指的是整个shebang,但是在这种情况下已经采用了“模块”和“包”。将它们视为“子项目”,这样会更有意义。
我们将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`
]
}
Run Code Online (Sandbox Code Playgroud)给根目录一个自己的项目。
./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.
]
}
Run Code Online (Sandbox Code Playgroud)奔跑tsc --build src
吧!
这将构建src
项目。因为它声明了对根项目的引用,所以它也会构建那个,但前提是它已经过时了。因为根 tsconfig 与 具有相同的目录,所以outDir
tsc 不会package.json
对它配置编译的一个文件做任何事情。
您可以通过将模块/库/子项目放在自己的子目录中并为其提供自己的 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
]
}
Run Code Online (Sandbox Code Playgroud)
src/common/tsconfig.json
因为common没有引用,所以导入仅限于其目录和npm_modules
. 我相信,您甚至可以通过给它自己的package.json
.
{
"compilerOptions": {
"rootDir": ".",
"outDir": "../../build/common",
"resolveJsonModule": true,
"composite": true
}
}
Run Code Online (Sandbox Code Playgroud)src/projectA/tsconfig.json
由于声明的引用,projectA可以导入common。
{
"compilerOptions": {
"rootDir": ".",
"outDir": "../../build/libA",
"resolveJsonModule": true,
"composite": true
},
"references": [
{ "path": "../common" }
]
}
Run Code Online (Sandbox Code Playgroud)Chr*_*ras 17
我们可以设置resolveJsonModule
为 false 并*.json
在内部声明一个模块typings.d.ts
,该模块需要 JSON 文件作为模块,并且它将生成dist
目录内没有任何目录结构的文件。
monorepo\
?? app\
? ?? src\
? ? ?? index.ts
? ?? package.json
? ?? tsconfig.json
? ?? typings.d.ts
?? lib\
?? package.json
Run Code Online (Sandbox Code Playgroud)
app/typings.d.ts
monorepo\
?? app\
? ?? src\
? ? ?? index.ts
? ?? package.json
? ?? tsconfig.json
? ?? typings.d.ts
?? lib\
?? package.json
Run Code Online (Sandbox Code Playgroud)
app/src/index.ts
declare module "*.json";
Run Code Online (Sandbox Code Playgroud)
app/package.json
内容// Import from app/package.json
import appPackageJson from '../package.json';
// Import from lib/package.json
import libPackageJson from '../../lib/package.json';
export function run(): void {
console.log(`App name "${appPackageJson.name}" with version ${appPackageJson.version}`);
console.log(`Lib name "${libPackageJson.name}" with version ${libPackageJson.version}`);
}
run();
Run Code Online (Sandbox Code Playgroud)
lib/package.json
内容{
"name": "my-app",
"version": "0.0.1",
...
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们使用 编译项目tsc
,我们将得到以下dist
目录结构:
app\
?? dist\
?? index.d.ts
?? index.js
Run Code Online (Sandbox Code Playgroud)
如果我们使用 运行它,我们将从和信息node ./dist
中获得输出:app
lib
package.json
$ node ./dist
App name "my-app" with version 0.0.1
Lib name "my-lib" with version 1.0.1
Run Code Online (Sandbox Code Playgroud)
您可以在这里找到项目存储库:https ://github.com/clytras/typescript-monorepo
ide*_*ide 10
对于使用ES 模块而不是 CommonJS 的包,有一个简洁的三步解决方案,使用 Node 16+ LTS 和 TypeScript 4.7+ 。
package.json中的"imports"
字段定义只能从实际包中导入的内部伪包。定义内部导入说明符,例如在package.json中:#package.json
{
"type": "module",
"exports": "./dist/index.js",
"imports": {
"#package.json": "./package.json"
}
}
Run Code Online (Sandbox Code Playgroud)
在tsconfig.json中启用对 ES 模块和 JSON 导入的TypeScript 支持:
{
"compilerOptions": {
"module": "nodenext",
// "moduleResolution" defaults to "nodenext", just made explicit here
"moduleResolution": "nodenext",
"resolveJsonModule": true,
}
}
Run Code Online (Sandbox Code Playgroud)
最后,从 TypeScript 模块导入:#package.json
import packageJson from '#package.json' assert { type: 'json' };
console.log(packageJson);
Run Code Online (Sandbox Code Playgroud)
小智 1
这取决于您阅读“package.json”的方式和时间。您可以在运行时使用 NodeJS“fs”模块将其读取为文件,或者只需输入 const package = require(“package.json”)。
在第二种情况下,Typescript 将在编译时在根目录中搜索它(请参阅Typescript 模块解析文档)。
您还可以使用“rootDirs”属性而不是“rootDir”来指定根文件夹数组。
归档时间: |
|
查看次数: |
15683 次 |
最近记录: |