溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Dojo Build 進(jìn)階

發(fā)布時(shí)間:2020-08-02 08:19:05 來源:網(wǎng)絡(luò) 閱讀:194 作者:blocklang 欄目:web開發(fā)

翻譯自 https://github.com/dojo/framework/blob/master/docs/en/building/supplemental.md

創(chuàng)建包

一個(gè)包就是一部分代碼,它用于表示一部分功能??梢园葱璁惒?、并行加載包。與不使用任何代碼拆分技術(shù)的應(yīng)用程序相比,合理分包的應(yīng)用程序可以顯著提高響應(yīng)速度,需要請(qǐng)求的字節(jié)數(shù)更少,加載的時(shí)間更短。在處理大型應(yīng)用程序時(shí),這一點(diǎn)尤其重要,因?yàn)檫@類應(yīng)用程序的大部分表現(xiàn)層邏輯在初始化時(shí)是不需要加載的。

Dojo 嘗試使用路由和 outlet 智能地做出選擇,自動(dòng)將代碼拆分為更小的包。通常各個(gè)包內(nèi)的代碼都是緊密相關(guān)的。這是構(gòu)建系統(tǒng)內(nèi)置的功能,可直接使用。但是,對(duì)于有特殊分包需求的用戶,Dojo 還允許在 .dojorc 配置文件中顯示定義包。

默認(rèn)情況下,Dojo 應(yīng)用程序只創(chuàng)建一個(gè)應(yīng)用程序包。但是 @dojo/cli-build-app 提供了很多配置選項(xiàng),這些選項(xiàng)可將應(yīng)用程序拆分為較小的、可逐步加載的包。

使用路由自動(dòng)分包

默認(rèn)情況下,Dojo 會(huì)基于應(yīng)用程序的路由自動(dòng)創(chuàng)建包。要做到這一點(diǎn)需要遵循以下幾條規(guī)則。

  1. src/routes.ts 必須默認(rèn)導(dǎo)出路由配置信息
  2. 部件所屬的模塊必須默認(rèn)導(dǎo)出部件
  3. Outletrender 函數(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>
        );
    }
}

將會(huì)為應(yīng)用程序的每個(gè)頂級(jí)路由生成單獨(dú)的包。在本例中,會(huì)生成一個(gè)應(yīng)用程序的主包以及 src/Homesrc/Aboutsrc/Profile 三個(gè)包。

使用 @dojo/cli-create-app 新建一個(gè)應(yīng)用程序,然后運(yùn)行 npm run build,就可看到自動(dòng)分包的實(shí)際效果。Dojo 將自動(dòng)為示例應(yīng)用程序中的所有路由創(chuàng)建包。

手動(dòng)分包

可以在 .dojorc 配置文件中手動(dòng)分包,這就為應(yīng)用程序提供了一種聲明式代碼拆分的手段。當(dāng)自動(dòng)根據(jù)路由分包無法滿足需求時(shí),這對(duì)于將應(yīng)用程序拆分為更小的包是極其有用的。

bundles 功能是 build app 命令的一部分。配置由由一組包名和緊隨其后的文件列表或匹配符組成。

例如,以下配置將 AboutProfile 合在一個(gè)包中,并命名為 additional.[hash].js。在 w() 中使用的部件模塊將被自動(dòng)轉(zhuǎn)換為在父部件中延遲加載的本地注冊(cè)項(xiàng)。

.dojorc

{
    "build-app": {
        "bundles": {
            "additional": ["src/widgets/About", "src/widgets/Profile"]
        }
    }
}

如果我們想分地區(qū)創(chuàng)建國(guó)際化模塊,我們應(yīng)該使用通配符以確保將每個(gè)語(yǔ)言目錄下的所有文件都會(huì)包含在內(nèi)。

.dojorc

{
    "build-app": {
        "bundles": {
            "fr": ["src/**/nls/fr/**"],
            "de": ["src/**/nls/de/**"]
        }
    }
}

在這種情況下,Dojo 將創(chuàng)建名為 fr.[hash].js 的包,和名為 de.[hash].js 的包。想了解更新信息,請(qǐng)參閱國(guó)際化參考指南中的使用消息包。

分包注意事項(xiàng)

有時(shí),根據(jù)構(gòu)建工具自動(dòng)分包或者在 .dojorc 中手動(dòng)定義的包中會(huì)重復(fù)包含被多個(gè)包共享的資源。有一些是無法避免的。一個(gè)避免重復(fù)的法則是嘗試將共享代碼移到應(yīng)用程序依賴樹的最外圍。換句話說,就是盡可能減少共享代碼之間的依賴。如果大量的代碼在包之間共享(例如,公共的部件),請(qǐng)考慮將這些資源放在一個(gè)包中。

靜態(tài)資源

很多靜態(tài)資源,如在模塊中導(dǎo)入的 CSS 和圖片,在構(gòu)建過程中會(huì)被自動(dòng)內(nèi)聯(lián)。但是,有時(shí)還需要為網(wǎng)站圖標(biāo)(favicon)或視頻文件等靜態(tài)資源提供服務(wù)。

靜態(tài)資源存放在項(xiàng)目根目錄下的 assets/ 文件夾中。在構(gòu)建時(shí),這些資源會(huì)被復(fù)制到應(yīng)用程序構(gòu)建版本的 assets/ 文件夾中。

構(gòu)建也會(huì)解析 src/index.html 中引用的 CSS、JavaScript 和圖片資源等,對(duì)這些資源名進(jìn)行哈希處理,并在輸出文件夾中包含這些資源??梢詫?favicon 存放在 src 文件夾中,然后在 src/index.html 中引用。構(gòu)建會(huì)自動(dòng)對(duì) favicon 文件名進(jìn)行哈希處理,并會(huì)將文件復(fù)制到輸出文件夾中,然后重命名為 favicon.[hash].ico

漸進(jìn)式 web 應(yīng)用程序

漸進(jìn)式 web 應(yīng)用程序(PWA)由一系列技術(shù)和模式組成,主要用于改善用戶體驗(yàn),幫助創(chuàng)建更可靠和可用的應(yīng)用程序。尤其是移動(dòng)用戶,他們會(huì)發(fā)現(xiàn)應(yīng)用程序能更好的集成到他們的設(shè)備中,就跟本地安裝的應(yīng)用程序一樣。

漸進(jìn)式 web 應(yīng)用程序主要由兩種技術(shù)組成:Service Worker 和 Manifest。Dojo 的構(gòu)建命令通過 .dojorcpwa 對(duì)象支持這兩種技術(shù)。

Manifest

Manifest 在一個(gè) JSON 文件中描述一個(gè)應(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 信息時(shí),dojo build 將在應(yīng)用程序的 index.html 中注入必需的 &lt;meta&gt; 標(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-: 告知 iOS 設(shè)備,狀態(tài)欄使用默認(rèn)外觀。
  • apple-touch-icon="{{icon}}": 相當(dāng)于 Manifest 中的 icons,因?yàn)?iOS 當(dāng)前沒有從 Manifest 中讀取 icons,所以需要為 icons 數(shù)組中每張圖片單獨(dú)注入一個(gè) meta 標(biāo)簽。

Service worker

Service worder 是一種 web worker,能夠攔截網(wǎng)絡(luò)請(qǐng)求、緩存和提供資源。Dojo 的 build 命令能夠自動(dòng)構(gòu)建功能全面的 service worker,它會(huì)在啟動(dòng)時(shí)激活,然后使用配置文件完成預(yù)緩存和自定義路由處理。

例如,我們編寫一個(gè)配置文件來創(chuàng)建一個(gè)簡(jiǎn)單的 service worker,它會(huì)緩存除了 admin 包之外的所有應(yīng)用程序包,也會(huì)緩存應(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,它的所有選項(xiàng)都是有效的 pwa.serviceWorker 屬性。

屬性 類型 可選 描述
bundles string[] 需要進(jìn)行預(yù)緩存的一組包。默認(rèn)是所有包。
cachePrefix string 在運(yùn)行時(shí)進(jìn)行預(yù)緩存使用的前綴。
clientsClaim boolean Service worker 是否要在開始激活時(shí)控制客戶端。默認(rèn)為 false。
excludeBundles string[] 要從預(yù)緩存中排除的一組包。默認(rèn)為 []
importScripts string[] 需要在 service worker 中加載的一組腳本的路徑。
precache object 描述預(yù)緩存配置選項(xiàng)的對(duì)象(見下文)。
routes object[] 一組描述要在運(yùn)行時(shí)緩存的配置對(duì)象(見下文)。
skipWaiting boolean Service worker 是否要跳過“等待”生命周期。
預(yù)緩存

precache 選項(xiàng)使用以下選項(xiàng)控制預(yù)緩存行為:

屬性 類型 可選 描述
baseDir string 匹配 include 時(shí)使用的根目錄。
ignore string[] 一組通配符模式的字符串,當(dāng)生成預(yù)緩存項(xiàng)時(shí)用于匹配需要忽略的文件。默認(rèn)為 [ 'node_modules/**/*' ]。
include string or string[] 一個(gè)或者一組通配符模式的字符串,用于匹配 precache 應(yīng)該包含的文件。默認(rèn)是構(gòu)建管道中的所有文件。
index string 如果請(qǐng)求以 / 結(jié)尾的 URL 失敗,則應(yīng)該查找的 index 文件名。默認(rèn)為 'index.html'
maxCacheSize number 往預(yù)緩存中添加的每一個(gè)文件不應(yīng)超過的最大字節(jié)數(shù)。默認(rèn)為 2097152 (2 MB)。
strict boolean 如果為 true,則 include 模式匹配到一個(gè)不存在的文件夾時(shí),構(gòu)建就會(huì)失敗。默認(rèn)為 true。
symlinks boolean 當(dāng)生成預(yù)緩存時(shí)是否允許軟連接(symlinks)。默認(rèn)為 true。
運(yùn)行時(shí)緩存

除了預(yù)緩存之外,還可以為特定路由提供緩存策略,以確定它們是否可以緩存以及如何緩存。routes 選項(xiàng)是一組包含以下屬性的對(duì)象:

屬性 類型 可選 描述
urlPattern string 用于匹配特定路由的模式字符串(會(huì)被轉(zhuǎn)換為正則表達(dá)式)。
strategy string 緩存策略(見下文)。
options object 一個(gè)描述附加選項(xiàng)的對(duì)象。每個(gè)選項(xiàng)的詳情如下。
cacheName string 路由使用的緩存名稱。注意 cachePrefix 不會(huì) 添加到緩存名前。默認(rèn)為主運(yùn)行時(shí)緩存(${cachePrefix}-runtime-${domain})。
cacheableResponse object 使用 HTTP 狀態(tài)碼或者報(bào)頭(Header)信息來決定是否可以緩存響應(yīng)的內(nèi)容。此對(duì)象有兩個(gè)可選屬性:statusesheadersstatuses 是一組對(duì)緩存生效的狀態(tài)碼。headers 是一組 HTTP 的 header 和 value 鍵值對(duì);至少要與一個(gè)報(bào)頭匹配,響應(yīng)才會(huì)被視為有效。當(dāng) strategy 的值是 'cacheFirst' 時(shí),默認(rèn)為 { statuses: [ 200 ] };當(dāng) strategy 的值為 networkFirst 或者 staleWhileRevalidate 時(shí),默認(rèn)為 { statuses: [0, 200] }
expiration object 控制如何讓緩存失效。此對(duì)象有兩個(gè)可選屬性。maxEntries 是任何時(shí)間可以緩存的響應(yīng)個(gè)數(shù)。一旦超過此最大值,就會(huì)刪除最舊的條目。maxAgeSeconds 是一個(gè)響應(yīng)能緩存的最長(zhǎng)時(shí)間(以秒為單位),超過此時(shí)長(zhǎng)就會(huì)被刪除。
networkTimeoutSeconds number networkFirst 策略一起使用,指定當(dāng)網(wǎng)絡(luò)請(qǐng)求的響應(yīng)多久沒有返回時(shí)就從緩存中獲取資源,單位為秒。

目前支持四種路由策略:

  • networkFirst 嘗試通過網(wǎng)絡(luò)加載資源,如果請(qǐng)求失敗或超時(shí)才從緩存中獲取資源。對(duì)于頻繁更改或者可能頻繁更改(即沒有版本控制)的資源,這是一個(gè)很有用的策略。
  • cacheFirst 優(yōu)先從緩存中加載資源,如果緩存中不存在,則通過網(wǎng)絡(luò)獲取。這對(duì)于很少更改或者能緩存很長(zhǎng)一段時(shí)間的資源(受版本控制的資源)來說是最好的策略。
  • networkOnly 強(qiáng)制始終通過網(wǎng)絡(luò)獲取資源,對(duì)于無需離線處理的資源是很有用的策略。
  • staleWhileRevalidate 同時(shí)從緩存和網(wǎng)絡(luò)中請(qǐng)求資源。網(wǎng)絡(luò)成功響應(yīng)后都會(huì)更新緩存。此策略最適用于不需要持續(xù)更新的資源,比如用戶信息。但是,當(dāng)獲取第三方資源時(shí)沒有發(fā)送 CORS 報(bào)頭,就無法讀取響應(yīng)的內(nèi)容或驗(yàn)證狀態(tài)碼。因此,可能會(huì)緩存錯(cuò)誤的響應(yīng)。在這種情況下,networkFirst 策略可能更適合。

構(gòu)建時(shí)渲染

構(gòu)建時(shí)渲染(Build-time rendering,簡(jiǎn)稱 BTR)在構(gòu)建過程中將一個(gè)路由渲染為一個(gè) HTML,并將在初始視圖中顯示的、關(guān)鍵的 CSS 和資源嵌入到頁(yè)面中。Dojo 能預(yù)渲染路由使用的初始 HTML,并直接注入到頁(yè)面中,這樣會(huì)帶來很多與服務(wù)器端渲染(***)相同的好處,如性能提升、搜索引擎優(yōu)化且沒有引入 *** 的復(fù)雜性。

使用 BTR

首先確保 index.html 中包含一個(gè)擁有 id 屬性的 DOM 節(jié)點(diǎn)。Dojo 的虛擬 DOM 會(huì)使用這個(gè)節(jié)點(diǎn)來比較和渲染應(yīng)用程序的 HTML。BTR 需要此設(shè)置,這樣它就能渲染在構(gòu)建階段生成的 HTML。這將會(huì)為路由創(chuàng)建一個(gè)響應(yīng)非??斓某跏间秩尽?/p>

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é)點(diǎn)上:

main.ts

const r = renderer(() => w(App, {}));
const domNode = document.getElementById('app') as HTMLElement;
r.mount({ registry, domNode });

然后更新項(xiàng)目的 .dojorc 配置文件,設(shè)置根 DOM 節(jié)點(diǎn)的 id 和在構(gòu)建時(shí)要渲染的路由。

.dojorc

{
    "build-app": {
        "build-time-render": {
            "root": "app",
            "paths": [
                "#home",
                {
                    "path": "#comments/9999",
                    "match": ["#comments/.*"]
                }
            ]
        }
    }
}

此配置描述了兩個(gè)路由。一個(gè)是 home 路由,一個(gè)是較復(fù)雜的 comments 路由。comments 是一個(gè)比較復(fù)雜的路由,需要傳入?yún)?shù)。match 參數(shù)用于確保在構(gòu)建時(shí)為此路由生成的 HTML 可以應(yīng)用到與此正則表達(dá)式匹配的任何路由上。

BTR 在構(gòu)建時(shí)為每個(gè)渲染路徑(path)生成一份屏幕快照,存在 ./output/info/screenshots 文件夾中。

History 管理器

構(gòu)建時(shí)渲染支持使用 @dojo/framework/routing/history/HashHistory@dojo/framework/routing/history/StateHistory history 管理器的應(yīng)用程序。當(dāng)使用 HashHistory 時(shí),確保所有的路徑都是以 # 字符開頭。

build-time-render 功能標(biāo)記

運(yùn)行時(shí)渲染公開了一個(gè) build-time-render 功能標(biāo)記,可用于跳過在構(gòu)建時(shí)不能執(zhí)行的功能。這樣在創(chuàng)建一個(gè)初始渲染時(shí),就可以避免對(duì)外部系統(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 提供了一個(gè) block 系統(tǒng),在構(gòu)建階段的渲染過程中會(huì)執(zhí)行 Node.js 代碼。執(zhí)行的結(jié)果會(huì)被寫入到緩存中,然后在瀏覽器運(yùn)行階段會(huì)以相同的方式、透明的使用這些緩存。這就為使用一些瀏覽器中無法實(shí)現(xiàn)或者性能不佳的操作開辟了新的機(jī)會(huì)。

例如,Dojo 的 block 模塊可以讀取一組 markdown 文件,將其轉(zhuǎn)換為 VNode,并使它們可以在應(yīng)用程序中渲染,所有這些都可在構(gòu)建時(shí)執(zhí)行。然后 Dojo block 模塊的構(gòu)建結(jié)果會(huì)緩存在應(yīng)用程序的包中,以便在運(yùn)行時(shí)在瀏覽器中使用。

Dojo block 模塊的用法與在 Dojo 部件中使用其它 meta 的用法類似。因此無需大量的配置或其他編寫模式。

例如,block 模塊讀取一個(gè)文本文件,然后將內(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è)部件會(huì)在構(gòu)建階段運(yùn)行 src/blocks/read-file.ts 模塊來讀取指定文件的內(nèi)容。然后將內(nèi)容作為文本節(jié)點(diǎn),用作部件 VDOM 輸出的子節(jié)點(diǎn)。

按條件選取代碼

構(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)建時(shí)移除這些無用的代碼。

比如,上述代碼將重寫為:

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)斷言的功能都不會(huì)被重寫。這就允許在運(yùn)行時(shí)來確定是否存在這個(gè)功能。

已提供的功能

構(gòu)建系統(tǒng)已提供以下功能(feature),用于幫助識(shí)別特定的環(huán)境或操作模式。

功能標(biāo)記 描述
debug 提供了一種為代碼創(chuàng)建代碼路徑的方法,該代碼路徑僅在調(diào)試或者提供更強(qiáng)的診斷時(shí)有用,在為 生產(chǎn) 構(gòu)建時(shí)是不需要的。默認(rèn)為 true,但在構(gòu)建生產(chǎn)版本時(shí)應(yīng)該靜態(tài)地配置為 false。
host-browser 確定當(dāng)前環(huán)境下 global 上下文中是否包含 windowdocument 對(duì)象,因此通常可以安全地假設(shè)代碼運(yùn)行在瀏覽器環(huán)境下。
host-node 嘗試檢測(cè)當(dāng)前環(huán)境是不是 node 環(huán)境。
build-time-render 在構(gòu)建期間渲染時(shí)由 BTR 系統(tǒng)靜態(tài)定義。

外部依賴

通常不能被打包的非模塊化庫(kù)或者獨(dú)立的應(yīng)用程序,如果需要引入到 dojo 應(yīng)用程序中,則可以通過提供一個(gè) requiredefine 實(shí)現(xiàn),并在項(xiàng)目的 .dojorc 文件中做一些配置。

要配置外部依賴項(xiàng),則需要為 build-app 配置對(duì)象設(shè)置 externals 屬性。externals 是一個(gè)對(duì)象,包含以下兩個(gè)屬性:

  • outputPath: 一個(gè)可選屬性,指定一個(gè)將文件復(fù)制到何處的輸出路徑。
  • dependencies: 一個(gè)必填的數(shù)組,定義哪些模塊應(yīng)該通過外部加載器加載,以及在構(gòu)建時(shí)應(yīng)該包含哪些文件。每個(gè)記錄可以是以下兩種類型之一:
    • 一個(gè)字符串,表示應(yīng)該使用外部加載器加載此路徑及其所有子路徑。
    • 一個(gè)對(duì)象,為需要復(fù)制到構(gòu)建版應(yīng)用程序的依賴提供附加配置項(xiàng)。此對(duì)象具有以下屬性:
屬性 類型 可選 描述
from string 相對(duì)于項(xiàng)目根目錄的路徑,指定位于何處的文件夾或目錄要復(fù)制到已構(gòu)建應(yīng)用程序中。
to string 一個(gè)路徑,表示將 from 路徑下的依賴復(fù)制到何處的目標(biāo)路徑。默認(rèn)情況下,依賴會(huì)被復(fù)制到 ${externalsOutputPath}/${to};如果沒有設(shè)置 to,依賴會(huì)被復(fù)制到 ${externalsOutputPath}/${from}。如果路徑中包含 . 字符或者路徑表示的是一個(gè)文件夾,則需要以正斜杠結(jié)尾。
name string 在應(yīng)用程序代碼中引用的模塊 id 或者全局變量名。
inject string, string[], or boolean 此屬性表示這個(gè)依賴定義的(或者包含的),要在頁(yè)面中加載的腳本或樣式文件。如果 inject 的值為 true,那么就會(huì)在頁(yè)面中加載 tofrom 指定位置的文件。如果依賴的是文件夾,則 inject 可以被設(shè)置為一個(gè)或者一組字符串,來定義一個(gè)或多個(gè)要注入的文件。inject 中的每個(gè)路徑都應(yīng)該是相對(duì)于 ${externalsOutputPath}/${to}${externalsOutputPath}/${from}(具體取決于是否指定了 to)。
type 'root' or 'umd' or 'amd' or 'commonjs' or 'commonjs2' 強(qiáng)制模塊用指定的方法解析。如果是 AMD 風(fēng)格,則必須使用 umdamd。如果是 node 風(fēng)格則必須使用 commonjs,并且值為 root 時(shí)以全局的方式訪問對(duì)象。

例如,以下配置會(huì)將 src/legacy/layer.js 注入到應(yīng)用程序頁(yè)面中;注入定義了 MyGlobal 全局變量的文件;聲明模塊 ab 為外部依賴,且要委托給外部層;然后復(fù)制 node_modules/legacy-dep 下的文件,并將其中的幾個(gè)文件注入到頁(yè)面中。所有文件都將被復(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 中包含的依賴項(xiàng)的類型會(huì)被安裝到 node_modules/@types 中,這跟其它依賴項(xiàng)是一樣的。

因?yàn)檫@些文件位于主構(gòu)建(main build)之外,所以在生產(chǎn)構(gòu)建中不會(huì)執(zhí)行版本控制或哈希處理(在 inject 中指定資源的鏈接除外)??梢栽?to 屬性中指定版本號(hào),將依賴復(fù)制到對(duì)應(yīng)版本的文件夾下,這樣就能避免緩存不同版本的文件。

脫離 Dojo 構(gòu)建管道

Dojo 的構(gòu)建管道為項(xiàng)目提供了一個(gè)端到端的工具鏈,但是,在極少數(shù)情況下,可能需要自定義工具鏈。只要將項(xiàng)目脫離 Dojo 的構(gòu)建管道,就可以自定義工具鏈。

將項(xiàng)目脫離構(gòu)建管道,是一個(gè)不可逆的、單向過程,它會(huì)導(dǎo)出 Webpack、Intern 以及 dojo 命令使用的其他項(xiàng)目的底層配置文件。如果提供的生成工具無法提供所需的功能或特性,推薦的方法是 fork 選定的構(gòu)建命令,然后往工具中添加額外的功能。Dojo 的 CLI 本質(zhì)上是專門按模塊化設(shè)計(jì)的,考慮到了這個(gè)用例。

要將一個(gè)項(xiàng)目脫離出 dojo 構(gòu)建管道,請(qǐng)使用 dojo eject 命令,它將提示你確實(shí)已明白過程是不可逆的。這個(gè)導(dǎo)出過程將所有已安裝的 dojo 命令中導(dǎo)出的配置信息存到 config 文件夾中。這個(gè)過程也會(huì)安裝一些項(xiàng)目需要的附加依賴。

現(xiàn)在項(xiàng)目已經(jīng)是一個(gè) webpack 項(xiàng)目??梢酝ㄟ^修改 config/build-app/base.config.js 來更改構(gòu)建配置。

然后,可以通過運(yùn)行 webpack 的構(gòu)建命令并提供配置項(xiàng)來觸發(fā)一個(gè)構(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]
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI