欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TypeScript Module Resolution解析過程

 更新時(shí)間:2023年07月27日 14:20:23   作者:JerryWang_汪子熙  
這篇文章主要為大家介紹了TypeScript Module Resolution解析過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Module Resolution

Module Resolution

模塊解析是編譯器用來確定導(dǎo)入所指內(nèi)容的過程。考慮像 import { a } from "moduleA"; 這樣的導(dǎo)入語句。為了檢查 a 的任何使用,編譯器需要確切地知道它代表什么,并且需要檢查它的定義 moduleA。

此時(shí),編譯器會(huì)問“moduleA 的形狀是什么?”雖然這聽起來很簡(jiǎn)單,但 moduleA 可以在您自己的 .ts/.tsx 文件之一中定義,或者在您的代碼所依賴的 .d.ts 中定義。

首先,編譯器會(huì)嘗試定位一個(gè)代表導(dǎo)入模塊的文件。為此,編譯器遵循兩種不同策略之一:classical 或 Node。這些策略告訴編譯器去哪里尋找 moduleA。

如果這不起作用并且模塊名稱是非相關(guān)的(在“moduleA”的情況下,它是),那么編譯器將嘗試定位一個(gè)環(huán)境模塊聲明。接下來我們將介紹非相對(duì)導(dǎo)入。

最后,如果編譯器無法解析模塊,它將記錄一個(gè)錯(cuò)誤。在這種情況下,錯(cuò)誤類似于錯(cuò)誤 TS2307:找不到模塊 'moduleA'。

Relative vs. Non-relative module imports

根據(jù)模塊引用是相對(duì)的還是非相對(duì)的,模塊導(dǎo)入的解析方式不同。

相對(duì)導(dǎo)入是以 /、./ 或 ../ 開頭的導(dǎo)入。 一些例子包括:

import Entry from "./components/Entry";
import { DefaultHeaders } from "../constants/http";
import "/mod";

任何其他導(dǎo)入都被認(rèn)為是非相關(guān)的。 一些例子包括:

import * as $ from "jquery";
import { Component } from "@angular/core";

相對(duì)導(dǎo)入是相對(duì)于導(dǎo)入文件解析的,無法解析為環(huán)境模塊聲明。 您應(yīng)該對(duì)自己的模塊使用相對(duì)導(dǎo)入,以保證在運(yùn)行時(shí)保持其相對(duì)位置。

Module Resolution Strategies

有兩種可能的模塊解析策略:Node 和 Classic。 您可以使用 --moduleResolution 標(biāo)志來指定模塊解析策略。 如果未指定,則 --module commonjs 默認(rèn)為 Node,否則默認(rèn)為 Classic(包括 --module 設(shè)置為 amd、system、umd、es2015、esnext 等時(shí))。

注意:Node 模塊解析是 TypeScript 社區(qū)中最常用的,推薦用于大多數(shù)項(xiàng)目。 如果您在 TypeScript 中遇到導(dǎo)入和導(dǎo)出的解析問題,請(qǐng)嘗試設(shè)置 moduleResolution: "node" 以查看它是否解決了問題。

Classical 解析策略

這曾經(jīng)是 TypeScript 的默認(rèn)解析策略。 如今,這種策略主要是為了向后兼容。

相對(duì)導(dǎo)入將相對(duì)于導(dǎo)入文件進(jìn)行解析。 因此,在源文件 /root/src/folder/A.ts 中 import { b } from "./moduleB" 將導(dǎo)致以下查找:

  • /root/src/folder/moduleB.ts
  • /root/src/folder/moduleB.d.ts

然而,對(duì)于非相關(guān)模塊導(dǎo)入,編譯器從包含導(dǎo)入文件的目錄開始沿著目錄樹向上走,試圖找到匹配的定義文件。

例如:

在源文件 /root/src/folder/A.ts 中,對(duì) moduleB 的非相對(duì)導(dǎo)入,例如 import { b } from "moduleB",將導(dǎo)致嘗試使用以下位置來定位 "moduleB":

/root/src/folder/moduleB.ts
/root/src/folder/moduleB.d.ts
/root/src/moduleB.ts
/root/src/moduleB.d.ts
/root/moduleB.ts
/root/moduleB.d.ts
/moduleB.ts
/moduleB.d.ts

Node 模式

這種解析策略試圖在運(yùn)行時(shí)模仿 Node.js 模塊解析機(jī)制。 Node.js 模塊文檔中概述了完整的 Node.js 解析算法。

Node.js 如何解析模塊?

要了解 TS 編譯器將遵循哪些步驟,了解 Node.js 模塊非常重要。傳統(tǒng)上,Node.js 中的導(dǎo)入是通過調(diào)用名為 require 的函數(shù)來執(zhí)行的。 Node.js 采取的行為將根據(jù) require 是相對(duì)路徑還是非相對(duì)路徑而有所不同。

相對(duì)路徑相當(dāng)簡(jiǎn)單。例如,讓我們考慮一個(gè)位于 /root/src/moduleA.js 的文件,其中包含 import var x = require("./moduleB");

Node.js 按以下順序解析該導(dǎo)入:

  • 詢問名為 /root/src/moduleB.js 的文件是否存在。
  • 詢問文件夾 /root/src/moduleB 是否包含指定“主”模塊的名為 package.json 的文件。在我們的示例中,如果 Node.js 發(fā)現(xiàn)文件 /root/src/moduleB/package.json 包含 { "main": "lib/mainModule.js" },那么 Node.js 將引用 /root/src/moduleB/lib/mainModule.js。
  • 詢問文件夾 /root/src/moduleB 是否包含名為 index.js 的文件。該文件被隱式視為該文件夾的“主”模塊。

但是,對(duì)非相關(guān)模塊名稱的解析以不同的方式執(zhí)行。 Node 將在名為 node_modules 的特殊文件夾中查找您的模塊。 node_modules 文件夾可以與當(dāng)前文件位于同一級(jí)別,也可以在目錄鏈中的更高級(jí)別。 Node 將沿著目錄鏈向上遍歷,查看每個(gè) node_modules,直到找到您嘗試加載的模塊。

按照我們上面的例子,考慮 /root/src/moduleA.js 是否使用非相對(duì)路徑并導(dǎo)入 var x = require("moduleB");。然后,Node 會(huì)嘗試將 moduleB 解析為每個(gè)位置,直到一個(gè)位置正常工作。

(1) /root/src/node_modules/moduleB.js

(2) /root/src/node_modules/moduleB/package.json(如果它指定了“main”屬性)

(3) /root/src/node_modules/moduleB/index.js

(4) /root/node_modules/moduleB.js

(5) /root/node_modules/moduleB/package.json(如果它指定了“main”屬性)

(6) /root/node_modules/moduleB/index.js

(7) /node_modules/moduleB.js

(8) /node_modules/moduleB/package.json(如果它指定了“main”屬性)

(9) /node_modules/moduleB/index.js

請(qǐng)注意,Node.js 在步驟 (4) 和 (7) 中跳轉(zhuǎn)了一個(gè)目錄。

您可以在 Node.js 文檔中閱讀有關(guān)從 node_modules 加載模塊的更多信息。

How TypeScript resolves modules

TypeScript 將模仿 Node.js 運(yùn)行時(shí)解析策略,以便在編譯時(shí)定位模塊的定義文件。為此,TypeScript 在 Node 的解析邏輯上覆蓋了 TypeScript 源文件擴(kuò)展名(.ts、.tsx 和 .d.ts)。 TypeScript 還將使用 package.json 中名為“types”的字段來反映“main”的用途——編譯器將使用它來查找要查閱的“main”定義文件。

例如,像 /root/src/moduleA.ts 中的 import { b } from "./moduleB" 這樣的導(dǎo)入語句將導(dǎo)致嘗試以下位置來定位 "./moduleB":

(1)/root/src/moduleB.ts
(2)/root/src/moduleB.tsx
(3)/root/src/moduleB.d.ts
(4)/root/src/moduleB/package.json(如果它指定了“types”屬性)
(5)/root/src/moduleB/index.ts
(6)/root/src/moduleB/index.tsx
(7)/root/src/moduleB/index.d.ts

回想一下,Node.js 查找名為 moduleB.js 的文件,然后是適用的 package.json,然后是 index.js。

同樣,非相對(duì)導(dǎo)入將遵循 Node.js 解析邏輯,首先查找文件,然后查找適用的文件夾。因此,在源文件 /root/src/moduleA.ts 中 import { b } from "moduleB" 將導(dǎo)致以下查找:

/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
/root/node_modules/moduleB.ts
/root/node_modules/moduleB.tsx
/root/node_modules/moduleB.d.ts
/root/node_modules/moduleB/package.json(如果它指定了“types”屬性)
/root/node_modules/@types/moduleB.d.ts
/root/node_modules/moduleB/index.ts
/root/node_modules/moduleB/index.tsx
/root/node_modules/moduleB/index.d.ts
/node_modules/moduleB.ts
/node_modules/moduleB.tsx
/node_modules/moduleB.d.ts
/node_modules/moduleB/package.json(如果它指定了“types”屬性)
/node_modules/@types/moduleB.d.ts
/node_modules/moduleB/index.ts
/node_modules/moduleB/index.tsx
/node_modules/moduleB/index.d.ts

不要被這里的步驟數(shù)嚇倒——TypeScript 仍然只在步驟 (9) 和 (17) 中兩次跳轉(zhuǎn)目錄。這實(shí)際上并不比 Node.js 本身所做的更復(fù)雜。

Additional module resolution flags

項(xiàng)目源布局有時(shí)與輸出布局不匹配。 通常一組構(gòu)建步驟會(huì)生成最終輸出。 其中包括將 .ts 文件編譯為 .js,以及將依賴項(xiàng)從不同的源位置復(fù)制到單個(gè)輸出位置。 最終結(jié)果是模塊在運(yùn)行時(shí)的名稱可能與包含其定義的源文件的名稱不同。 或者最終輸出中的模塊路徑可能在編譯時(shí)與其對(duì)應(yīng)的源文件路徑不匹配。

TypeScript 編譯器有一組額外的標(biāo)志來通知編譯器預(yù)期發(fā)生在源上的轉(zhuǎn)換以生成最終輸出。

需要注意的是,編譯器不會(huì)執(zhí)行任何這些轉(zhuǎn)換; 它只是使用這些信息來指導(dǎo)將模塊導(dǎo)入解析到其定義文件的過程。

Base Url

在使用 AMD 模塊加載器的應(yīng)用程序中,使用 baseUrl 是一種常見做法,其中模塊在運(yùn)行時(shí)“部署”到單個(gè)文件夾。 這些模塊的源代碼可以位于不同的目錄中,但是構(gòu)建腳本會(huì)將它們放在一起。

設(shè)置 baseUrl 通知編譯器在哪里可以找到模塊。 假定所有具有非相對(duì)名稱的模塊導(dǎo)入都與 baseUrl 相關(guān)。

baseUrl 的值確定為:

(1)baseUrl 命令行參數(shù)的值(如果給定的路徑是相對(duì)的,則根據(jù)當(dāng)前目錄計(jì)算)

(2)'tsconfig.json' 中 baseUrl 屬性的值(如果給定的路徑是相對(duì)的,則根據(jù) 'tsconfig.json' 的位置計(jì)算)

請(qǐng)注意,相對(duì)模塊導(dǎo)入不會(huì)受到設(shè)置 baseUrl 的影響,因?yàn)樗鼈兛偸窍鄬?duì)于它們的導(dǎo)入文件進(jìn)行解析。

您可以在 RequireJS 和 SystemJS 文檔中找到有關(guān) baseUrl 的更多文檔。

path mapping

有時(shí)模塊并不直接位于 baseUrl 下。例如,對(duì)模塊“jquery”的導(dǎo)入將在運(yùn)行時(shí)轉(zhuǎn)換為“node_modules/jquery/dist/jquery.slim.min.js”。加載器使用映射配置在運(yùn)行時(shí)將模塊名稱映射到文件,請(qǐng)參閱 RequireJs 文檔和 SystemJS 文檔。

TypeScript 編譯器支持使用 tsconfig.json 文件中的“paths”屬性聲明此類映射。 以下是如何為 jquery 指定“paths”屬性的示例。

{
  "compilerOptions": {
    "baseUrl": ".", // This must be specified if "paths" is.
    "paths": {
      "jquery": ["node_modules/jquery/dist/jquery"] // This mapping is relative to "baseUrl"
    }
  }
}

如何檢查 TypeScript 模塊解析過程

如前所述,編譯器在解析模塊時(shí)可以訪問當(dāng)前文件夾之外的文件。 在診斷模塊未解析的原因或解析為不正確的定義時(shí),這可能很困難。 使用 --traceResolution 啟用編譯器模塊解析跟蹤可以深入了解模塊解析過程中發(fā)生的情況。

假設(shè)我們有一個(gè)使用 typescript 模塊的示例應(yīng)用程序。

app.ts has an import like import * as ts from "typescript".

│   tsconfig.json
├───node_modules
│   └───typescript
│       └───lib
│               typescript.d.ts
└───src
        app.ts

使用如下命令行編譯:

tsc --traceResolution

結(jié)果:

======== Resolving module 'typescript' from 'src/app.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module 'typescript' from 'node_modules' folder.
File 'src/node_modules/typescript.ts' does not exist.
File 'src/node_modules/typescript.tsx' does not exist.
File 'src/node_modules/typescript.d.ts' does not exist.
File 'src/node_modules/typescript/package.json' does not exist.
File 'node_modules/typescript.ts' does not exist.
File 'node_modules/typescript.tsx' does not exist.
File 'node_modules/typescript.d.ts' does not exist.
Found 'package.json' at 'node_modules/typescript/package.json'.
'package.json' has 'types' field './lib/typescript.d.ts' that references 'node_modules/typescript/lib/typescript.d.ts'.
File 'node_modules/typescript/lib/typescript.d.ts' exist - use it as a module resolution result.
======== Module name 'typescript' was successfully resolved to 'node_modules/typescript/lib/typescript.d.ts'. ========

觸發(fā)模塊解析的源代碼位置:

======== Resolving module ‘typescript’ from ‘src/app.ts’. ========

模塊解析策略:

Module resolution kind is not specified, using ‘NodeJs’.

Loading of types from npm packages:

‘package.json’ has ‘types’ field ‘./lib/typescript.d.ts’ that references ‘node_modules/typescript/lib/typescript.d.ts’.

最后成功解析的輸出:

======== Module name ‘typescript’ was successfully resolved to ‘node_modules/typescript/lib/typescript.d.ts’. ========

以上就是TypeScript Module Resolution解析過程的詳細(xì)內(nèi)容,更多關(guān)于TypeScript Module Resolution的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于tsup打包TypeScript實(shí)現(xiàn)過程

    基于tsup打包TypeScript實(shí)現(xiàn)過程

    這篇文章主要為大家介紹了基于tsup打包TypeScript實(shí)現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • typescript在vue中的入門案例代碼demo

    typescript在vue中的入門案例代碼demo

    這篇文章主要介紹了typescript在vue中的入門案例代碼demo,使用技術(shù)棧vue2+typescript+scss入門練手項(xiàng)目,天氣預(yù)報(bào)demo,需要的朋友可以參考下。
    2022-12-12
  • LocalStorage封裝一次解決方法示例

    LocalStorage封裝一次解決方法示例

    這篇文章主要為大家介紹了LocalStorage封裝一次解決的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • TypeScript十大排序算法之選擇排序?qū)崿F(xiàn)示例詳解

    TypeScript十大排序算法之選擇排序?qū)崿F(xiàn)示例詳解

    這篇文章主要為大家介紹了TypeScript十大排序算法之選擇排序?qū)崿F(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • ThreeJS使用紋理貼圖創(chuàng)建一個(gè)我的世界草地方塊

    ThreeJS使用紋理貼圖創(chuàng)建一個(gè)我的世界草地方塊

    這篇文章主要為大家介紹了ThreeJS使用紋理貼圖創(chuàng)建一個(gè)我的世界草地方塊的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • TypeScript數(shù)據(jù)結(jié)構(gòu)鏈表結(jié)構(gòu)?LinkedList教程及面試

    TypeScript數(shù)據(jù)結(jié)構(gòu)鏈表結(jié)構(gòu)?LinkedList教程及面試

    這篇文章主要為大家介紹了TypeScript數(shù)據(jù)結(jié)構(gòu)鏈表結(jié)構(gòu)?LinkedList教程及面試,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Webpack source map實(shí)戰(zhàn)分析詳解

    Webpack source map實(shí)戰(zhàn)分析詳解

    這篇文章主要為大家介紹了Webpack source map示例分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • TypeScript與JavaScript的區(qū)別分析

    TypeScript與JavaScript的區(qū)別分析

    TypeScript可以使用JavaScript中的所有代碼和編程概念,TypeScript是為了使JavaScript的開發(fā)變得更加容易而創(chuàng)建的。推薦先精通JS的的前提下再學(xué)習(xí)TS,這樣更有利于同時(shí)學(xué)習(xí)兩門語言。
    2022-12-12
  • TypeScript十大排序算法插入排序?qū)崿F(xiàn)示例詳解

    TypeScript十大排序算法插入排序?qū)崿F(xiàn)示例詳解

    這篇文章主要為大家介紹了TypeScript十大排序算法插入排序?qū)崿F(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • type-challenge刷題(easy部分)示例詳解

    type-challenge刷題(easy部分)示例詳解

    這篇文章主要為大家介紹了type-challenge刷題(easy部分)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08

最新評(píng)論