TypeScript 模块加载机制
一、TS 文件的加载策略
TS 中的加载策略分为两种方式,分别为相对路径和绝对路径两种方式。
1、相对路径
TypeScript 将 TypeScript 源文件扩展名(.ts
、.tsx
和.d.ts
)覆盖在 Node 的解析逻辑上。同时TypeScript 还将使用 package.json
named 中的一个字段 types
来镜像目的"main"
,编译器将使用它来查找“主”定义文件以进行查阅。
-
// 假设当前执行路径为 /root/src/modulea
-
-
import { b } from './moduleb'
此时,TS 对于 ./moduleb
的加载方式其实是和 node 的模块加载机制比较类似:
- 首先寻找
/root/src/moduleb.ts
是否存在,如果存在使用该文件。 - 其次寻找
/root/src/moduleb.tsx
是否存在,如果存在使用该文件。 - 其次寻找
/root/src/moduleb.d.ts
是否存在,如果存在使用该文件。 - 其次寻找
/root/src/moduleB/package.json
,如果 package.json 中指定了一个types
属性的话那么会返回该文件。 - 如果上述仍然没有找到,之后会查找
/root/src/moduleB/index.ts
。 - 如果上述仍然没有找到,之后会查找
/root/src/moduleB/index.tsx
。 - 如果上述仍然没有找到,之后会查找
/root/src/moduleB/index.d.ts
。
可以看到 TS 中针对于相对路径查找的规范是和 nodejs 比较相似的。
Ts 在寻找文件路径时,在某些条件下是会按照目录去查找 .d.ts
的。
2、绝对路径
-
// 假设当前文件所在路径为 /root/src/modulea
-
-
import { b } from 'moduleb'
/root/src/node_modules/moduleB.ts
/root/src/node_modules/moduleB.tsx
/root/src/node_modules/moduleB.d.ts
/root/src/node_modules/moduleB/package.json
(如果它指定了一个types
属性)/root/src/node_modules/@types/moduleB.d.ts
/root/src/node_modules/moduleB/index.ts
/root/src/node_modules/moduleB/index.tsx
/root/src/node_modules/moduleB/index.d.ts
typescript 针对于非相对导入的 moduleb 会按照以上路径去当前路径的 node_modules 中去查找,如果上述仍然未找到。
此时,TS 仍然会按照 node 的模块解析规则,继续向上进行目录查找,比如又会进入上层目录 /root/node_modules/moduleb.ts ...
进行查找,直到查找到顶层 node_modules 也就是最后一个查找的路径为 /node_modules/moduleB/index.d.ts
如果未找到则会抛出异常 can't find module 'moduleb'
。
上述查找规则是基于 tsconfig.json 中指定的moduleResolution:node
,当然还有classic
不过classic
规则是 TS 为了兼容老旧版本,现代代码中基本可以忽略这个模块查找规则。
3、解析 *.d.ts
声明
日常开发中,有这样一种场景,在 TS 项目中我们需要引入一些后缀为 png 的图片资源,那么此时 TS 是无法识别此模块的。
解决方法也非常简单,通常我们会在项目的根目录中也就是和 tsconfig.json 平级的任意目录中添加对应的声明文件 image.d.ts
:
-
// image.d.ts
-
-
declare module '*.png' {
-
const src: String;
-
export default src;
-
}
import logo from './assets/logo.png'
可以看到,通过定义声明文件的方式解决了我们的问题。
3.1 typescript模块加载机制是怎么查找到定义在项目目录中的 image.d.ts
呢?
本质上我们引入任何模块时,加载机制无非就是我们上边提到的两种加载方式。
不过,这里有一个细小的点即是 ts 编译器会处理 tsconfig.json 的 file、include、exclude
对应目录下的所有 .d.ts 文件:
简单来说,ts 编译器首先会根据 tsconfig.json 中的上述三个字段来加载项目内的 d.ts
全局模块声明文件,自然由于 '.png' 文件会命中全局加载的 image.d.ts
中的 声明的 module
所以会找到对应的文件。
include 在未指定 file 配置下默认为**
,表示 tsc 解析的目录为当前 tsconfig.json 所在的项目文件夹。
关于 file、include、exclude 三者本质上都是针对于 TSC 编译器处理的范围。
-
// tsconfig.json
-
-
{
-
"compilerOptions": {
-
"outDir": "build/dist",
-
"module": "esnext",
-
"target": "esnext",
-
"lib": ["esnext", "dom"],
-
"sourceMap": true,
-
"baseUrl": ".",
-
"jsx": "react-jsx",
-
"resolveJsonModule": true,
-
"allowSyntheticDefaultImports": true,
-
"moduleResolution": "node",
-
"forceConsistentCasingInFileNames": true,
-
"noImplicitReturns": true,
-
"noImplicitAny": false,
-
"suppressImplicitAnyIndexErrors": true,
-
"noUnusedLocals": true,
-
"allowJs": true,
-
"skipLibCheck": true,
-
"experimentalDecorators": true,
-
"strict": true,
-
"paths": {
-
"@/*": ["./src/*"],
-
"@@/*": ["./src/.umi/*"]
-
}
-
},
-
"include": [
-
"mock/**/*",
-
"src/**/*",
-
"playwright.config.ts",
-
"tests/**/*",
-
"test/**/*",
-
"__test__/**/*",
-
"typings/**/*",
-
"config/**/*",
-
".eslintrc.js",
-
".stylelintrc.js",
-
".prettierrc.js",
-
"jest.config.js",
-
"mock/*"
-
],
-
"exclude": ["node_modules", "build", "dist", "scripts", "src/.umi/*", "webpack", "jest"],
-
"files": []
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbckia
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01