翻譯自 https://github.com/dojo/framework/blob/master/docs/en/building/supplemental.md
創(chuàng)建包
一個包就是一部分代碼,它用于表示一部分功能。可以按需異步涛菠、并行加載包棍潘。與不使用任何代碼拆分技術(shù)的應(yīng)用程序相比紫岩,合理分包的應(yīng)用程序可以顯著提高響應(yīng)速度啸澡,需要請求的字節(jié)數(shù)更少,加載的時間更短烂叔。在處理大型應(yīng)用程序時,這一點尤其重要固歪,因為這類應(yīng)用程序的大部分表現(xiàn)層邏輯在初始化時是不需要加載的蒜鸡。
Dojo 嘗試使用路由和 outlet 智能地做出選擇,自動將代碼拆分為更小的包牢裳。通常各個包內(nèi)的代碼都是緊密相關(guān)的逢防。這是構(gòu)建系統(tǒng)內(nèi)置的功能,可直接使用蒲讯。但是忘朝,對于有特殊分包需求的用戶,Dojo 還允許在 .dojorc
配置文件中顯示定義包判帮。
默認(rèn)情況下局嘁,Dojo 應(yīng)用程序只創(chuàng)建一個應(yīng)用程序包溉箕。但是 @dojo/cli-build-app 提供了很多配置選項,這些選項可將應(yīng)用程序拆分為較小的悦昵、可逐步加載的包肴茄。
使用路由自動分包
默認(rèn)情況下,Dojo 會基于應(yīng)用程序的路由自動創(chuàng)建包旱捧。要做到這一點需要遵循以下幾條規(guī)則独郎。
-
src/routes.ts
必須默認(rèn)導(dǎo)出路由配置信息 - 部件所屬的模塊必須默認(rèn)導(dǎo)出部件
-
Outlet
的render
函數(shù)必須使用內(nèi)聯(lián)函數(shù)
src/routes.ts
export default [
{
path: 'home',
outlet: 'home',
defaultRoute: true
},
{
path: 'about',
outlet: 'about'
},
{
path: 'profile',
outlet: 'profile'
}
];
src/App.ts
export default class App extends WidgetBase {
protected render() {
return (
<div classes={[css.root]}>
<Menu />
<div>
<Outlet key="home" id="home" renderer={() => <Home />} />
<Outlet key="about" id="about" renderer={() => <About />} />
<Outlet key="profile" id="profile" renderer={() => <Profile username="Dojo User" />} />
</div>
</div>
);
}
}
將會為應(yīng)用程序的每個頂級路由生成單獨的包。在本例中枚赡,會生成一個應(yīng)用程序的主包以及 src/Home
氓癌、src/About
和 src/Profile
三個包。
使用 @dojo/cli-create-app 新建一個應(yīng)用程序贫橙,然后運行 npm run build
贪婉,就可看到自動分包的實際效果。Dojo 將自動為示例應(yīng)用程序中的所有路由創(chuàng)建包卢肃。
手動分包
可以在 .dojorc
配置文件中手動分包疲迂,這就為應(yīng)用程序提供了一種聲明式代碼拆分的手段。當(dāng)自動根據(jù)路由分包無法滿足需求時莫湘,這對于將應(yīng)用程序拆分為更小的包是極其有用的尤蒿。
bundles
功能是 build app 命令的一部分。配置由由一組包名和緊隨其后的文件列表或匹配符組成幅垮。
例如腰池,以下配置將 About
和 Profile
合在一個包中,并命名為 additional.[hash].js
忙芒。在 w()
中使用的部件模塊將被自動轉(zhuǎn)換為在父部件中延遲加載的本地注冊項示弓。
.dojorc
{
"build-app": {
"bundles": {
"additional": ["src/widgets/About", "src/widgets/Profile"]
}
}
}
如果我們想分地區(qū)創(chuàng)建國際化模塊,我們應(yīng)該使用通配符以確保將每個語言目錄下的所有文件都會包含在內(nèi)呵萨。
.dojorc
{
"build-app": {
"bundles": {
"fr": ["src/**/nls/fr/**"],
"de": ["src/**/nls/de/**"]
}
}
}
在這種情況下奏属,Dojo 將創(chuàng)建名為 fr.[hash].js
的包,和名為 de.[hash].js
的包潮峦。想了解更新信息囱皿,請參閱國際化參考指南中的使用消息包。
分包注意事項
有時跑杭,根據(jù)構(gòu)建工具自動分包或者在 .dojorc
中手動定義的包中會重復(fù)包含被多個包共享的資源铆帽。有一些是無法避免的。一個避免重復(fù)的法則是嘗試將共享代碼移到應(yīng)用程序依賴樹的最外圍德谅。換句話說爹橱,就是盡可能減少共享代碼之間的依賴。如果大量的代碼在包之間共享(例如,公共的部件)愧驱,請考慮將這些資源放在一個包中慰技。
靜態(tài)資源
很多靜態(tài)資源,如在模塊中導(dǎo)入的 CSS 和圖片组砚,在構(gòu)建過程中會被自動內(nèi)聯(lián)吻商。但是,有時還需要為網(wǎng)站圖標(biāo)(favicon)或視頻文件等靜態(tài)資源提供服務(wù)糟红。
靜態(tài)資源存放在項目根目錄下的 assets/
文件夾中艾帐。在構(gòu)建時,這些資源會被復(fù)制到應(yīng)用程序構(gòu)建版本的 assets/
文件夾中盆偿。
構(gòu)建也會解析 src/index.html
中引用的 CSS柒爸、JavaScript 和圖片資源等慢洋,對這些資源名進(jìn)行哈希處理轮纫,并在輸出文件夾中包含這些資源∮倒樱可以將 favicon 存放在 src
文件夾中求橄,然后在 src/index.html
中引用今野。構(gòu)建會自動對 favicon 文件名進(jìn)行哈希處理,并會將文件復(fù)制到輸出文件夾中罐农,然后重命名為 favicon.[hash].ico
条霜。
漸進(jìn)式 web 應(yīng)用程序
漸進(jìn)式 web 應(yīng)用程序(PWA)由一系列技術(shù)和模式組成,主要用于改善用戶體驗涵亏,幫助創(chuàng)建更可靠和可用的應(yīng)用程序蛔外。尤其是移動用戶,他們會發(fā)現(xiàn)應(yīng)用程序能更好的集成到他們的設(shè)備中溯乒,就跟本地安裝的應(yīng)用程序一樣。
漸進(jìn)式 web 應(yīng)用程序主要由兩種技術(shù)組成:Service Worker 和 Manifest豹爹。Dojo 的構(gòu)建命令通過 .dojorc
的 pwa
對象支持這兩種技術(shù)裆悄。
Manifest
Manifest 在一個 JSON 文件中描述一個應(yīng)用程序,并提供了一些詳細(xì)信息臂聋,因此可以直接從萬維網(wǎng)安裝到設(shè)備的主屏幕上光稼。
.dojorc
{
"build-app": {
"pwa": {
"manifest": {
"name": "Todo MVC",
"description": "A simple to-do application created with Dojo",
"icons": [
{ "src": "./favicon-16x16.png", "sizes": "16x16", "type": "image/png" },
{ "src": "./favicon-32x32.png", "sizes": "32x32", "type": "image/png" },
{ "src": "./favicon-48x48.png", "sizes": "48x48", "type": "image/png" },
{ "src": "./favicon-256x256.png", "sizes": "256x256", "type": "image/png" }
]
}
}
}
}
當(dāng)提供了 manifest 信息時,dojo build
將在應(yīng)用程序的 index.html
中注入必需的 <meta>
標(biāo)簽孩等。
-
mobile-web-app-capable="yes"
: 告知 Android 上的 Chrome 可以將此應(yīng)用程序添加到用戶的主界面上艾君。 -
apple-mobile-web-app-capable="yes"
: 告知 iOS 設(shè)備可以將此應(yīng)用程序添加到用戶的主界面上。 -
apple-mobile-web-app-status-bar-style="default"
: 告知 iOS 設(shè)備肄方,狀態(tài)欄使用默認(rèn)外觀冰垄。 -
apple-touch-icon="{{icon}}"
: 相當(dāng)于 Manifest 中的 icons,因為 iOS 當(dāng)前沒有從 Manifest 中讀取 icons权她,所以需要為 icons 數(shù)組中每張圖片單獨注入一個 meta 標(biāo)簽虹茶。
Service worker
Service worder 是一種 web worker逝薪,能夠攔截網(wǎng)絡(luò)請求、緩存和提供資源蝴罪。Dojo 的 build 命令能夠自動構(gòu)建功能全面的 service worker董济,它會在啟動時激活,然后使用配置文件完成預(yù)緩存和自定義路由處理要门。
例如虏肾,我們編寫一個配置文件來創(chuàng)建一個簡單的 service worker,它會緩存除了 admin 包之外的所有應(yīng)用程序包欢搜,也會緩存應(yīng)用程序最近訪問的圖像和文章封豪。
.dojorc
{
"build-app": {
"pwa": {
"serviceWorker": {
"cachePrefix": "my-app",
"excludeBundles": ["admin"],
"routes": [
{
"urlPattern": ".*\\.(png|jpg|gif|svg)",
"strategy": "cacheFirst",
"cacheName": "my-app-images",
"expiration": { "maxEntries": 10, "maxAgeSeconds": 604800 }
},
{
"urlPattern": "http://my-app-url.com/api/articles",
"strategy": "cacheFirst",
"expiration": { "maxEntries": 25, "maxAgeSeconds": 86400 }
}
]
}
}
}
}
ServiceWorker 配置
在底層,@dojo/webpack-contrib
中的 ServicerWorkerPlugin
用于生成 service worker狂巢,它的所有選項都是有效的 pwa.serviceWorker
屬性撑毛。
屬性 | 類型 | 可選 | 描述 |
---|---|---|---|
bundles | string[] |
是 | 需要進(jìn)行預(yù)緩存的一組包。默認(rèn)是所有包唧领。 |
cachePrefix | string |
是 | 在運行時進(jìn)行預(yù)緩存使用的前綴藻雌。 |
clientsClaim | boolean |
是 | Service worker 是否要在開始激活時控制客戶端。默認(rèn)為 false 斩个。 |
excludeBundles | string[] |
是 | 要從預(yù)緩存中排除的一組包胯杭。默認(rèn)為 [] 。 |
importScripts | string[] |
是 | 需要在 service worker 中加載的一組腳本的路徑受啥。 |
precache | object |
是 | 描述預(yù)緩存配置選項的對象(見下文)做个。 |
routes | object[] |
是 | 一組描述要在運行時緩存的配置對象(見下文)。 |
skipWaiting | boolean |
是 | Service worker 是否要跳過“等待”生命周期滚局。 |
預(yù)緩存
precache
選項使用以下選項控制預(yù)緩存行為:
屬性 | 類型 | 可選 | 描述 |
---|---|---|---|
baseDir | string |
是 | 匹配 include 時使用的根目錄居暖。 |
ignore | string[] |
是 | 一組通配符模式的字符串,當(dāng)生成預(yù)緩存項時用于匹配需要忽略的文件藤肢。默認(rèn)為 [ 'node_modules/**/*' ] 太闺。 |
include |
string or string[]
|
是 | 一個或者一組通配符模式的字符串,用于匹配 precache 應(yīng)該包含的文件嘁圈。默認(rèn)是構(gòu)建管道中的所有文件省骂。 |
index | string |
是 | 如果請求以 / 結(jié)尾的 URL 失敗,則應(yīng)該查找的 index 文件名最住。默認(rèn)為 'index.html' 钞澳。 |
maxCacheSize | number |
是 | 往預(yù)緩存中添加的每一個文件不應(yīng)超過的最大字節(jié)數(shù)。默認(rèn)為 2097152 (2 MB)涨缚。 |
strict | boolean |
是 | 如果為 true 轧粟,則 include 模式匹配到一個不存在的文件夾時,構(gòu)建就會失敗。默認(rèn)為 true 逃延。 |
symlinks | boolean |
是 | 當(dāng)生成預(yù)緩存時是否允許軟連接(symlinks)览妖。默認(rèn)為 true 。 |
運行時緩存
除了預(yù)緩存之外揽祥,還可以為特定路由提供緩存策略讽膏,以確定它們是否可以緩存以及如何緩存。routes
選項是一組包含以下屬性的對象:
屬性 | 類型 | 可選 | 描述 |
---|---|---|---|
urlPattern | string |
否 | 用于匹配特定路由的模式字符串(會被轉(zhuǎn)換為正則表達(dá)式)拄丰。 |
strategy | string |
否 | 緩存策略(見下文)府树。 |
options | object |
是 | 一個描述附加選項的對象。每個選項的詳情如下料按。 |
cacheName | string |
是 | 路由使用的緩存名稱奄侠。注意 cachePrefix 不會 添加到緩存名前。默認(rèn)為主運行時緩存(${cachePrefix}-runtime-${domain} )载矿。 |
cacheableResponse | object |
是 | 使用 HTTP 狀態(tài)碼或者報頭(Header)信息來決定是否可以緩存響應(yīng)的內(nèi)容垄潮。此對象有兩個可選屬性:statuses 和 headers 。statuses 是一組對緩存生效的狀態(tài)碼闷盔。headers 是一組 HTTP 的 header 和 value 鍵值對弯洗;至少要與一個報頭匹配,響應(yīng)才會被視為有效逢勾。當(dāng) strategy 的值是 'cacheFirst' 時牡整,默認(rèn)為 { statuses: [ 200 ] } ;當(dāng) strategy 的值為 networkFirst 或者 staleWhileRevalidate 時溺拱,默認(rèn)為 { statuses: [0, 200] }
|
expiration | object |
是 | 控制如何讓緩存失效逃贝。此對象有兩個可選屬性。maxEntries 是任何時間可以緩存的響應(yīng)個數(shù)迫摔。一旦超過此最大值沐扳,就會刪除最舊的條目。maxAgeSeconds 是一個響應(yīng)能緩存的最長時間(以秒為單位)句占,超過此時長就會被刪除迫皱。 |
networkTimeoutSeconds | number |
是 | 與 networkFirst 策略一起使用,指定當(dāng)網(wǎng)絡(luò)請求的響應(yīng)多久沒有返回時就從緩存中獲取資源辖众,單位為秒。 |
目前支持四種路由策略:
-
networkFirst
嘗試通過網(wǎng)絡(luò)加載資源和敬,如果請求失敗或超時才從緩存中獲取資源凹炸。對于頻繁更改或者可能頻繁更改(即沒有版本控制)的資源,這是一個很有用的策略昼弟。 -
cacheFirst
優(yōu)先從緩存中加載資源啤它,如果緩存中不存在,則通過網(wǎng)絡(luò)獲取。這對于很少更改或者能緩存很長一段時間的資源(受版本控制的資源)來說是最好的策略变骡。 -
networkOnly
強(qiáng)制始終通過網(wǎng)絡(luò)獲取資源离赫,對于無需離線處理的資源是很有用的策略。 -
staleWhileRevalidate
同時從緩存和網(wǎng)絡(luò)中請求資源塌碌。網(wǎng)絡(luò)成功響應(yīng)后都會更新緩存渊胸。此策略最適用于不需要持續(xù)更新的資源,比如用戶信息台妆。但是翎猛,當(dāng)獲取第三方資源時沒有發(fā)送 CORS 報頭,就無法讀取響應(yīng)的內(nèi)容或驗證狀態(tài)碼接剩。因此切厘,可能會緩存錯誤的響應(yīng)。在這種情況下懊缺,networkFirst
策略可能更適合疫稿。
構(gòu)建時渲染
構(gòu)建時渲染(Build-time rendering,簡稱 BTR)在構(gòu)建過程中將一個路由渲染為一個 HTML鹃两,并將在初始視圖中顯示的遗座、關(guān)鍵的 CSS 和資源嵌入到頁面中。Dojo 能預(yù)渲染路由使用的初始 HTML怔毛,并直接注入到頁面中员萍,這樣會帶來很多與服務(wù)器端渲染(SSR)相同的好處,如性能提升拣度、搜索引擎優(yōu)化且沒有引入 SSR 的復(fù)雜性碎绎。
使用 BTR
首先確保 index.html
中包含一個擁有 id
屬性的 DOM 節(jié)點。Dojo 的虛擬 DOM 會使用這個節(jié)點來比較和渲染應(yīng)用程序的 HTML抗果。BTR 需要此設(shè)置筋帖,這樣它就能渲染在構(gòu)建階段生成的 HTML。這將會為路由創(chuàng)建一個響應(yīng)非吃┝螅快的初始渲染日麸。
index.html
<!DOCTYPE html>
<html lang="en-us">
<head>
<title>sample-app</title>
<meta name="theme-color" content="#222127" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div id="app"></div>
</body>
</html>
然后將應(yīng)用程序掛載到指定的 DOM 節(jié)點上:
main.ts
const r = renderer(() => w(App, {}));
const domNode = document.getElementById('app') as HTMLElement;
r.mount({ registry, domNode });
然后更新項目的 .dojorc
配置文件,設(shè)置根 DOM 節(jié)點的 id
和在構(gòu)建時要渲染的路由逮光。
.dojorc
{
"build-app": {
"build-time-render": {
"root": "app",
"paths": [
"#home",
{
"path": "#comments/9999",
"match": ["#comments/.*"]
}
]
}
}
}
此配置描述了兩個路由代箭。一個是 home
路由,一個是較復(fù)雜的 comments
路由涕刚。comments
是一個比較復(fù)雜的路由嗡综,需要傳入?yún)?shù)。match
參數(shù)用于確保在構(gòu)建時為此路由生成的 HTML 可以應(yīng)用到與此正則表達(dá)式匹配的任何路由上杜漠。
BTR 在構(gòu)建時為每個渲染路徑(path)生成一份屏幕快照极景,存在 ./output/info/screenshots
文件夾中察净。
History 管理器
構(gòu)建時渲染支持使用 @dojo/framework/routing/history/HashHistory
或 @dojo/framework/routing/history/StateHistory
history 管理器的應(yīng)用程序。當(dāng)使用 HashHistory
時盼樟,確保所有的路徑都是以 #
字符開頭氢卡。
build-time-render
功能標(biāo)記
運行時渲染公開了一個 build-time-render
功能標(biāo)記,可用于跳過在構(gòu)建時不能執(zhí)行的功能晨缴。這樣在創(chuàng)建一個初始渲染時译秦,就可以避免對外部系統(tǒng)調(diào)用 fetch
,而是提供靜態(tài)數(shù)據(jù)喜庞。
if (!has('build-time-render')) {
const response = await fetch(/* remote JSON */);
return response.json();
} else {
return Promise.resolve({
/* predefined Object */
});
}
Dojo Blocks
Dojo 提供了一個 block 系統(tǒng)诀浪,在構(gòu)建階段的渲染過程中會執(zhí)行 Node.js 代碼。執(zhí)行的結(jié)果會被寫入到緩存中延都,然后在瀏覽器運行階段會以相同的方式雷猪、透明的使用這些緩存。這就為使用一些瀏覽器中無法實現(xiàn)或者性能不佳的操作開辟了新的機(jī)會晰房。
例如求摇,Dojo 的 block 模塊可以讀取一組 markdown 文件,將其轉(zhuǎn)換為 VNode殊者,并使它們可以在應(yīng)用程序中渲染与境,所有這些都可在構(gòu)建時執(zhí)行。然后 Dojo block 模塊的構(gòu)建結(jié)果會緩存在應(yīng)用程序的包中猖吴,以便在運行時在瀏覽器中使用摔刁。
Dojo block 模塊的用法與在 Dojo 部件中使用其它 meta 的用法類似。因此無需大量的配置或其他編寫模式海蔽。
例如共屈,block 模塊讀取一個文本文件,然后將內(nèi)容返回給應(yīng)用程序党窜。
src/blocks/read-file.ts
import * as fs from 'fs';
import { resolve } from 'path';
export default (path: string) => {
path = resolve(__dirname, path);
return fs.readFileSync(path, 'utf8');
};
src/widgets/MyBlockWidget.tsx
import Block from '@dojo/framework/core/meta/Block';
import WidgetBase from '@dojo/framework/core/WidgetBase';
import { v } from '@dojo/framework/core/vdom';
import readFile from '../blocks/read-file';
export default class MyBlockWidget extends WidgetBase {
protected render() {
const message = this.meta(Block).run(readFile)('../content/hello-dojo-blocks.txt');
return v('div', [message]);
}
}
這個部件會在構(gòu)建階段運行 src/blocks/read-file.ts
模塊來讀取指定文件的內(nèi)容拗引。然后將內(nèi)容作為文本節(jié)點,用作部件 VDOM 輸出的子節(jié)點幌衣。
按條件選取代碼
構(gòu)建工具的靜態(tài)代碼分析工具能夠從它創(chuàng)建的包中移除無用的代碼矾削。命名的條件塊是使用 dojo 框架的 has
模塊定義的,并且可以在 .dojorc
中靜態(tài)設(shè)置為 true 或 false豁护,然后在構(gòu)建階段移除哼凯。
main.ts
import has from '@dojo/framework/has';
if (has('production')) {
console.log('Starting in production');
} else {
console.log('Starting in dev mode');
}
export const mode = has('production') ? 'dist' : 'dev';
.dojorc
{
"build-app": {
"features": {
"production": true
}
}
}
上述的 production
功能將構(gòu)建生產(chǎn)版本(dist
模式)設(shè)置為 true
。構(gòu)建系統(tǒng)使用 @dojo/framework/has
將代碼標(biāo)記為無法訪問楚里,并在構(gòu)建時移除這些無用的代碼挡逼。
比如,上述代碼將重寫為:
static-build-loader 輸出
import has from '@dojo/framework/has';
if (true) {
console.log('Starting in production');
} else {
console.log('Starting in dev mode');
}
export const mode = true ? 'dist' : 'dev';
然后腻豌,構(gòu)建工具的無用分支移除工具將移除無用的代碼家坎。
Uglify 輸出
console.log('Starting in production');
export const mode = 'dist';
任何沒有被靜態(tài)斷言的功能都不會被重寫。這就允許在運行時來確定是否存在這個功能吝梅。
已提供的功能
構(gòu)建系統(tǒng)已提供以下功能(feature)虱疏,用于幫助識別特定的環(huán)境或操作模式。
功能標(biāo)記 | 描述 |
---|---|
debug |
提供了一種為代碼創(chuàng)建代碼路徑的方法苏携,該代碼路徑僅在調(diào)試或者提供更強(qiáng)的診斷時有用做瞪,在為 生產(chǎn) 構(gòu)建時是不需要的。默認(rèn)為 true 右冻,但在構(gòu)建生產(chǎn)版本時應(yīng)該靜態(tài)地配置為 false 装蓬。 |
host-browser |
確定當(dāng)前環(huán)境下 global 上下文中是否包含 window 和 document 對象,因此通成磁ぃ可以安全地假設(shè)代碼運行在瀏覽器環(huán)境下牍帚。 |
host-node |
嘗試檢測當(dāng)前環(huán)境是不是 node 環(huán)境。 |
build-time-render |
在構(gòu)建期間渲染時由 BTR 系統(tǒng)靜態(tài)定義乳蛾。 |
外部依賴
通常不能被打包的非模塊化庫或者獨立的應(yīng)用程序暗赶,如果需要引入到 dojo 應(yīng)用程序中,則可以通過提供一個 require
或 define
實現(xiàn)肃叶,并在項目的 .dojorc
文件中做一些配置蹂随。
要配置外部依賴項,則需要為 build-app
配置對象設(shè)置 externals
屬性因惭。externals
是一個對象岳锁,包含以下兩個屬性:
-
outputPath
: 一個可選屬性,指定一個將文件復(fù)制到何處的輸出路徑蹦魔。 -
dependencies
: 一個必填的數(shù)組激率,定義哪些模塊應(yīng)該通過外部加載器加載,以及在構(gòu)建時應(yīng)該包含哪些文件版姑。每個記錄可以是以下兩種類型之一:- 一個字符串柱搜,表示應(yīng)該使用外部加載器加載此路徑及其所有子路徑。
- 一個對象剥险,為需要復(fù)制到構(gòu)建版應(yīng)用程序的依賴提供附加配置項聪蘸。此對象具有以下屬性:
屬性 | 類型 | 可選 | 描述 |
---|---|---|---|
from |
string |
否 | 相對于項目根目錄的路徑,指定位于何處的文件夾或目錄要復(fù)制到已構(gòu)建應(yīng)用程序中表制。 |
to |
string |
是 | 一個路徑健爬,表示將 from 路徑下的依賴復(fù)制到何處的目標(biāo)路徑。默認(rèn)情況下么介,依賴會被復(fù)制到 ${externalsOutputPath}/${to} 娜遵;如果沒有設(shè)置 to ,依賴會被復(fù)制到 ${externalsOutputPath}/${from} 壤短。如果路徑中包含 . 字符或者路徑表示的是一個文件夾设拟,則需要以正斜杠結(jié)尾慨仿。 |
name |
string |
是 | 在應(yīng)用程序代碼中引用的模塊 id 或者全局變量名。 |
inject |
string, string[], or boolean |
是 | 此屬性表示這個依賴定義的(或者包含的)纳胧,要在頁面中加載的腳本或樣式文件镰吆。如果 inject 的值為 true ,那么就會在頁面中加載 to 或 from 指定位置的文件跑慕。如果依賴的是文件夾万皿,則 inject 可以被設(shè)置為一個或者一組字符串,來定義一個或多個要注入的文件核行。inject 中的每個路徑都應(yīng)該是相對于 ${externalsOutputPath}/${to} 或 ${externalsOutputPath}/${from} (具體取決于是否指定了 to )牢硅。 |
type |
'root' or 'umd' or 'amd' or 'commonjs' or 'commonjs2' |
是 | 強(qiáng)制模塊用指定的方法解析。如果是 AMD 風(fēng)格芝雪,則必須使用 umd 或 amd 减余。如果是 node 風(fēng)格則必須使用 commonjs ,并且值為 root 時以全局的方式訪問對象绵脯。 |
例如佳励,以下配置會將 src/legacy/layer.js
注入到應(yīng)用程序頁面中;注入定義了 MyGlobal
全局變量的文件蛆挫;聲明模塊 a
和 b
為外部依賴赃承,且要委托給外部層;然后復(fù)制 node_modules/legacy-dep
下的文件悴侵,并將其中的幾個文件注入到頁面中瞧剖。所有文件都將被復(fù)制到 externals
文件夾中,也可以使用 externals
配置中的 outputPath
屬性來重新指定文件夾可免。
{
"build-app": {
"externals": {
"dependencies": [
"a",
"b",
{
"from": "node_modules/GlobalLibrary.js",
"to": "GlobalLibrary.js",
"name": "MyGlobal",
"inject": true
},
{ "from": "src/legacy/layer.js", "to": "legacy/layer.js", "inject": true },
{
"from": "node_modules/legacy-dep",
"to": "legacy-dep/",
"inject": ["moduleA/layer.js", "moduleA/layer.css", "moduleB/layer.js"]
}
]
}
}
}
externals
中包含的依賴項的類型會被安裝到 node_modules/@types
中抓于,這跟其它依賴項是一樣的。
因為這些文件位于主構(gòu)建(main build)之外浇借,所以在生產(chǎn)構(gòu)建中不會執(zhí)行版本控制或哈希處理(在 inject
中指定資源的鏈接除外)捉撮。可以在 to
屬性中指定版本號妇垢,將依賴復(fù)制到對應(yīng)版本的文件夾下巾遭,這樣就能避免緩存不同版本的文件。
脫離 Dojo 構(gòu)建管道
Dojo 的構(gòu)建管道為項目提供了一個端到端的工具鏈闯估,但是灼舍,在極少數(shù)情況下,可能需要自定義工具鏈涨薪。只要將項目脫離 Dojo 的構(gòu)建管道骑素,就可以自定義工具鏈。
將項目脫離構(gòu)建管道刚夺,是一個不可逆的献丑、單向過程末捣,它會導(dǎo)出 Webpack、Intern 以及 dojo
命令使用的其他項目的底層配置文件创橄。如果提供的生成工具無法提供所需的功能或特性塔粒,推薦的方法是 fork 選定的構(gòu)建命令,然后往工具中添加額外的功能筐摘。Dojo 的 CLI 本質(zhì)上是專門按模塊化設(shè)計的,考慮到了這個用例船老。
要將一個項目脫離出 dojo 構(gòu)建管道咖熟,請使用 dojo eject
命令,它將提示你確實已明白過程是不可逆的柳畔。這個導(dǎo)出過程將所有已安裝的 dojo 命令中導(dǎo)出的配置信息存到 config
文件夾中馍管。這個過程也會安裝一些項目需要的附加依賴。
現(xiàn)在項目已經(jīng)是一個 webpack 項目薪韩∪贩校可以通過修改 config/build-app/base.config.js
來更改構(gòu)建配置。
然后俘陷,可以通過運行 webpack 的構(gòu)建命令并提供配置項來觸發(fā)一個構(gòu)建罗捎。此外,使用 webpack 的 env 標(biāo)記(例如 --env.mode=dev)來指定模式拉盾,默認(rèn)為 dist桨菜。
./node_modules/.bin/webpack --config=config/build-app/ejected.config.js --env.mode=[mode]