轉(zhuǎn)發(fā) ## TypeScript基礎(chǔ)入門之模塊解析(二)
模塊解析
Base URL
使用baseUrl是使用AMD模塊加載器的應(yīng)用程序中的常見做法辩恼,其中模塊在運(yùn)行時(shí)"deployed"到單個(gè)文件夾深员。
這些模塊的源代碼可以存在于不同的目錄中,但構(gòu)建腳本會(huì)將它們放在一起第租。
設(shè)置baseUrl通知編譯器在哪里可以找到模塊彪笼。
假定所有具有非相對(duì)名稱的模塊導(dǎo)入都相對(duì)于baseUrl
baseUrl的值確定為:
- baseUrl命令行參數(shù)的值(如果給定的路徑是相對(duì)的拷获,則根據(jù)當(dāng)前目錄計(jì)算)
- 'tsconfig.json'中baseUrl屬性的值(如果給定的路徑是相對(duì)的待榔,則根據(jù)'tsconfig.json'的位置計(jì)算)
請(qǐng)注意,設(shè)置baseUrl不會(huì)影響相對(duì)模塊導(dǎo)入猎莲,因?yàn)樗鼈兪冀K相對(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"
}
}
}
請(qǐng)注意,相對(duì)于"baseUrl"解析"paths"瞻佛。
當(dāng)將"baseUrl"設(shè)置為"."之外的另一個(gè)值脱篙,即tsconfig.json的目錄時(shí),必須相應(yīng)地更改映射伤柄。
比如說绊困,你在上面的例子中設(shè)置了"baseUrl": "./src",然后jquery應(yīng)該映射到"../node_modules/jquery/dist/jquery"
使用"paths"還允許更復(fù)雜的映射适刀,包括多個(gè)后退位置秤朗。
考慮一個(gè)項(xiàng)目配置,其中只有一些模塊在一個(gè)位置可用笔喉,其余模塊在另一個(gè)位置取视。
構(gòu)建步驟將它們放在一個(gè)地方。
項(xiàng)目布局可能如下所示:
projectRoot
├── folder1
│ ├── file1.ts (imports 'folder1/file2' and 'folder2/file3')
│ └── file2.ts
├── generated
│ ├── folder1
│ └── folder2
│ └── file3.ts
└── tsconfig.json
相應(yīng)的tsconfig.json如下所示:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": [
"*",
"generated/*"
]
}
}
}
這告訴編譯器任何與模式"*"(即所有值)匹配的模塊導(dǎo)入常挚,以查看兩個(gè)位置:
- "*"表示同名不變作谭,因此map <moduleName> => <baseUrl>/<moduleName>
- "generated/*"表示帶有附加前綴"generated"的模塊名稱,因此map <moduleName> => <baseUrl>/generated/<moduleName>
遵循此邏輯待侵,編譯器將嘗試解析這兩個(gè)導(dǎo)入:
-
import 'folder1/file2'
- 模式'*'匹配丢早,通配符捕獲整個(gè)模塊名稱
- 嘗試列表中的第一個(gè)替換:'*' -> folder1/file2
- 替換結(jié)果是非相對(duì)名稱 - 將其與baseUrl -> projectRoot/folder1/file2.ts結(jié)合使用姨裸。
- 文件已存在秧倾。完成。
-
import 'folder2/file3'
- 模式'*'匹配傀缩,通配符捕獲整個(gè)模塊名稱
- 嘗試列表中的第一個(gè)替換:'*' -> folder2/file3
- 替換結(jié)果是非相對(duì)名稱 - 將其與baseUrl -> projectRoot/folder2/file3.ts結(jié)合使用那先。
- 文件不存在,移動(dòng)到第二個(gè)替換
- 第二次替換'generated/*' -> generated/folder2/file3
- 替換結(jié)果是非相對(duì)名稱 - 將它與baseUrl -> projectRoot/generated/folder2/file3.ts結(jié)合使用
- 文件已存在赡艰。完成售淡。
使用rootDirs的虛擬目錄
有時(shí),編譯時(shí)來自多個(gè)目錄的項(xiàng)目源都被組合在一起以生成單個(gè)輸出目錄慷垮。
這可以看作是一組源目錄創(chuàng)建一個(gè)"虛擬"目錄揖闸。
使用'rootDirs',您可以通知編譯器構(gòu)成此"虛擬"目錄的根;
因此編譯器可以解析這些"虛擬"目錄中的相關(guān)模塊導(dǎo)入料身,就像在一個(gè)目錄中合并在一起一樣汤纸。
例如,考慮這個(gè)項(xiàng)目結(jié)構(gòu):
src
└── views
└── view1.ts (imports './template1')
└── view2.ts
generated
└── templates
└── views
└── template1.ts (imports './view2')
src/views中的文件是某些UI控件的用戶代碼芹血。
生成/模板中的文件是由模板生成器自動(dòng)生成的UI模板綁定代碼贮泞,作為構(gòu)建的一部分楞慈。
構(gòu)建步驟會(huì)將/src/views和/generated/templates/views中的文件復(fù)制到輸出中的同一目錄。
在運(yùn)行時(shí)啃擦,視圖可以期望其模板存在于其旁邊囊蓝,因此應(yīng)使用相對(duì)名稱"./template"將其導(dǎo)入。
要指定與編譯器的此關(guān)系令蛉,請(qǐng)使用"rootDirs"聚霜。
"rootDirs"指定一個(gè)根列表,其內(nèi)容應(yīng)在運(yùn)行時(shí)合并言询。
因此俯萎,按照我們的示例,tsconfig.json文件應(yīng)如下所示:
{
"compilerOptions": {
"rootDirs": [
"src/views",
"generated/templates/views"
]
}
}
每次編譯器在其中一個(gè)rootDirs的子文件夾中看到相對(duì)模塊導(dǎo)入時(shí)运杭,它將嘗試在rootDirs的每個(gè)條目中查找此導(dǎo)入夫啊。
rootDirs的靈活性不僅限于指定邏輯合并的物理源目錄列表。
所提供的陣列可以包括任意數(shù)量的ad hoc辆憔,任意目錄名撇眯,而不管它們是否存在。
這允許編譯器以類型安全的方式捕獲復(fù)雜的捆綁和運(yùn)行時(shí)功能虱咧,例如條件包含和項(xiàng)目特定的加載器插件熊榛。
考慮一種國際化場(chǎng)景,其中構(gòu)建工具通過插入特殊路徑令牌(例如#{locale})自動(dòng)生成特定于語言環(huán)境的包腕巡,作為相對(duì)模塊路徑的一部分玄坦,例如./#{locale}/messages。
在此假設(shè)設(shè)置中绘沉,該工具枚舉支持的語言環(huán)境煎楣,將抽象的路徑映射到./zh/messages,./de/messages等。
假設(shè)每個(gè)模塊都導(dǎo)出一個(gè)字符串?dāng)?shù)組车伞。
例如./zh/messages可能包含:
export default [
"您好嗎",
"很高興認(rèn)識(shí)你"
];
通過利用rootDirs择懂,我們可以通知編譯器這個(gè)映射,從而允許它安全地解析./#{locale}/messages另玖,即使該目錄永遠(yuǎn)不存在困曙。
例如,使用以下tsconfig.json配置:
{
"compilerOptions": {
"rootDirs": [
"src/zh",
"src/de",
"src/#{locale}"
]
}
}
編譯器現(xiàn)在將解析來自'./#{locale}/messages'的導(dǎo)入消息谦去,以便從工具中導(dǎo)入來自'./zh/messages'的消息慷丽,允許以區(qū)域設(shè)置無關(guān)的方式進(jìn)行開發(fā),而不會(huì)影響設(shè)計(jì)時(shí)支持鳄哭。
未完待續(xù)...