發布
此頁面提供將 Lit 元件發布到 npm 的指南,npm 是絕大多數 JavaScript 函式庫和開發人員使用的套件管理器。請參閱入門套件,其中包含為發布到 npm 而設定的可重複使用元件範本。
發布到 npm
“發布到 npm” 的永久連結若要將您的元件發布到 npm,請參閱有關貢獻 npm 套件的說明。
您的 package.json 設定應具有 type
、main
和 module
欄位
package.json
{
"type": "module",
"main": "my-element.js",
"module": "my-element.js"
}
您也應該建立一個 README,說明如何使用您的元件。
發布現代 JavaScript
“發布現代 JavaScript” 的永久連結我們建議以標準 ES2021 語法發布 JavaScript 模組,因為所有常青瀏覽器都支援此語法,並且會產生最快和最小的 JavaScript。您的套件使用者可以隨時使用編譯器來支援較舊的瀏覽器,但如果您在發布之前預先編譯程式碼,他們就無法將舊版 JavaScript 轉換為現代語法。
但是,如果您使用的是新提出的或非標準 JavaScript 功能(例如 TypeScript、裝飾器和類別欄位),則應該將這些功能編譯為瀏覽器中原生支援的標準 ES2021,然後再發布到 npm。
使用 TypeScript 編譯
“使用 TypeScript 編譯” 的永久連結以下 JSON 範例是部分的 tsconfig.json
,它使用建議的選項來以 ES2021 為目標、啟用裝飾器的編譯,並為使用者輸出 .d.ts
型別
tsconfig.json
"compilerOptions": {
"target": "es2021",
"module": "es2015",
"moduleResolution": "node",
"lib": ["es2021", "dom"],
"declaration": true,
"declarationMap": true,
"experimentalDecorators": true,
"useDefineForClassFields": false
}
請注意,只有在將 target
設定為 es2022
或更高版本(包括 esnext
)時,才需要將 useDefineForClassFields
設定為 false
,但建議明確確保此設定為 false
。
從 TypeScript 編譯時,您應該在 package.json
的 types
欄位中包含元件型別的宣告檔(根據上面的 declaration: true
產生),並確保 .d.ts
和 .d.ts.map
檔案也會發布
package.json
{
...
"types": "my-element.d.ts"
}
請參閱 tsconfig.json 文件以取得更多資訊。
使用 Babel 編譯
“使用 Babel 編譯” 的永久連結若要編譯使用尚未包含在 ES2021 中的建議 JavaScript 功能的 Lit 元件,請使用 Babel。
安裝 Babel 和您需要的 Babel 外掛程式。例如
npm install --save-dev \
@babel/core \
@babel/cli \
@babel/preset-env \
@babel/plugin-proposal-decorators
設定 Babel。例如
babel.config.json
{
"presets": [
["@babel/preset-env", {"targets": "defaults"}]
],
"plugins": [
["@babel/plugin-proposal-decorators", {"version": "2023-05"}]
]
}
您可以調整 "targets"
選項,以鎖定您想要支援的瀏覽器。請參閱 @babel/preset-env
以取得可用的選項。
您可以透過像是 @rollup/plugin-babel 的打包工具外掛程式,或從命令列執行 Babel。請參閱 Babel 文件以取得更多資訊。
發布最佳實務
“發布最佳實務” 的永久連結以下是在發布可重複使用的 Web 元件時應遵循的其他良好實務。
不要將 polyfill 匯入模組
“不要將 polyfill 匯入模組” 的永久連結Polyfill 是應用程式關心的問題,因此應用程式應直接依賴它們,而不是個別套件。所需的確切 polyfill 通常取決於應用程式需要支援的瀏覽器,而此選擇最好留給使用您元件的應用程式開發人員。您的元件文件應清楚地識別它使用的任何可能需要 polyfill 的 API。
套件可能需要依賴 polyfill 進行測試和示範,因此如果需要它們,它們應該只放在 devDependencies
中。
不要將模組打包、最小化或最佳化
“不要將模組打包、最小化或最佳化” 的永久連結打包和其他最佳化是應用程式關心的問題。在發布到 npm 之前打包可重複使用的元件,也可能會在使用者應用程式中引入多個 Lit(和其他套件)版本,因為 npm 無法重複資料刪除套件。這會導致膨脹並可能導致錯誤。
在發布之前最佳化模組也可能會阻止應用程式層級的最佳化。
從 CDN 提供模組時,打包和其他最佳化可能很有價值,但由於使用者可能需要使用多個依賴 Lit 的套件,因此從 CDN 提供可能會導致使用者載入比必要的更多的程式碼。基於這些原因,我們建議對效能敏感的應用程式始終從可以重複資料刪除套件的 npm 建置,而不是從 CDN 載入打包的套件。
如果您想要支援從 CDN 使用,我們建議清楚區分 CDN 模組和預期用於生產的模組。例如,將它們放置在單獨的資料夾中,或僅將它們作為 GitHub 版本的一部分新增,而不是將它們新增到已發布的 npm 模組中。
在匯入指定符中包含檔案擴展名
“在匯入指定符中包含檔案擴展名” 的永久連結Node 模組解析不需要檔案擴展名,因為它會搜尋檔案系統,以尋找是否未給定其中一個檔案擴展名。當您匯入 some-package/foo
時,如果存在,Node 將會匯入 some-package/foo.js
。同樣地,將套件指定符解析為 URL 的建置工具也可以在建置時執行此檔案系統搜尋。
但是,匯入對應規格 開始在瀏覽器中發佈,將允許瀏覽器從來源載入具有裸套件指定符的模組,未經轉換,方法是在匯入對應清單中提供匯入指定符到 URL 的對應(這可能會根據您的例如 npm 安裝工具產生)。
匯入對應將允許將匯入對應到 URL,但它們只有兩種對應類型:精確和前綴。這表示可以透過將套件名稱對應到單個 URL 前綴,輕鬆別名給定套件下的所有模組。但是,如果您在沒有檔案擴展名的情況下編寫匯入,則表示您套件中的每個檔案都需要在匯入對應中建立一個項目。這可能會大大膨脹匯入對應。
因此,為了讓您的來源現在就能夠以最佳方式與匯入對應相容,我們建議在匯入時使用檔案擴展名進行編寫。
發布 TypeScript 型別
“發布 TypeScript 型別” 的永久連結為了讓您更容易從 TypeScript 使用您的元素,我們建議您
為所有以 TypeScript 編寫的元素新增
HTMLElementTagNameMap
項目。@customElement('my-element')
export class MyElement extends LitElement { /* ... */ }
declare global {
interface HTMLElementTagNameMap {
"my-element": MyElement;
}
}
在您的 npm 套件中發布您的
.d.ts
型別。
如需有關 HTMLElementTagNameMap
的更多資訊,請參閱 提供良好的 TypeScript 型別。
自行定義元素
“自行定義元素” 的永久連結宣告 web 元件類別的模組應始終包含對 customElements.define()
(或 @customElement
裝飾器) 的呼叫,以定義元素。
目前,web 元件始終在全域登錄中定義。每個自訂元素定義都需要使用唯一的標籤名稱和唯一的 JavaScript 類別。嘗試註冊相同的標籤名稱兩次,或相同的類別兩次,將會失敗並顯示錯誤。單純匯出類別並期望使用者呼叫 define()
是不穩定的。如果兩個不同的元件都依賴共用的第三個元件,並且兩者都嘗試定義它,則其中一個會失敗。如果始終在宣告類別的相同模組中定義元素,則這不是問題。
此方法的一個缺點是,如果兩個不同的元素使用相同的標籤名稱,則它們無法同時匯入到同一個專案中。
正在開發將具範圍的自訂元素登錄新增到平台中。具範圍的登錄允許元件的使用者針對給定的陰影根範圍選擇自訂元素的標籤名稱。一旦瀏覽器開始發布此功能,發布每個元件的兩個模組將會變得實用:一個模組匯出沒有任何副作用的自訂元素類別,另一個模組使用標籤名稱全域註冊它。
在那之前,我們建議繼續在全域註冊表中註冊元素。
匯出元素類別
「匯出元素類別」的永久連結為了支援子類別化,請從定義元素類別的模組中匯出該類別。這允許為了擴充目的而進行子類別化,以及未來在Scoped Custom Element Registries中註冊。
更多閱讀
「延伸閱讀」的永久連結如需建立高品質、可重複使用的 Web Components 的更通用指南,請參閱Web Components 的黃金標準檢查清單。