feat: support of external libraries/components in dist-custom-elements

オープン
#3,576 コメント 3 件 リアクション 8 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
25/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
typescript
領域
build-system

調査の方向性

src/declarations/stencil-public-compiler.ts と、関連する bundle-interface.ts、bundle-output.ts、dist-custom-elements-bundle/index.ts ファイルから始めます。dist-custom-elements のオプションがどのように Rollup に渡されるか、また遅延ロードされる Stencil コレクションがどのように処理されるかを追跡します。string または RegExp の外部エントリをサポートし、要求された lazy コンポーネントをバンドルせずに外部のままにできれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Resolution: Refine
Prerequisites
Describe the Feature Request

When building components with dist-custom-elements we may need to share code with other components/apps or use external libraries. Currently every external library that is included within a component will be bundled in the compilation output.

It extends FR described in #3226 and follows the discussion in #3136.

Describe the Use Case

There are two use cases:

  1. Marking, that a library, that is used by a component should not be packed in the component's output bundle
  2. Marking, that an external lazy loaded component that is used by a component should not be packed in the component's output bundle

In the first case, lets say that we have a dependency to moment.js - right now, if you build a component and within the code of the component there are imports from moment.js, then all required code from moment.js (and its dependencies) will be put in the output bundle. That is fine and proper default behavior, but in my case moment.js is used across multiple components and within main project (which imports those components), moment.js is also directly imported so I would end up with moment.js being bundled three times. Having an "external" option in dist-custom-elements will allow to avoid that.

Second case, lets say, that we created a component, that uses @ionic/core lazy loaded component, e.g. ion-button. If you build the component, you will have in the output bundle the ion-button code but also other ionic components (whole collection is consumed). Having an "external" option would tell rollup to treat @ionic/core as external but also to treat stencil collections as external components.

Describe Preferred Solution

In dist-custom-elements we need to create new option "external":

export interface OutputTargetDistCustomElements extends OutputTargetBaseNext {
   ...
   external?: (string | RegExp)[];
   ...
}

Value of the external is directly passed to rollup (array of string or RegExp) - this will fully solve the first case (importing external library). Additionally, somewhere in dist-custom-elements compilation process, Stencil must check if lazy components collection is also to be treated as external.

In my Stencil fork both of those cases are covered in dist-custom-elements-bundle output target, below you may see what changes I had to make in order to make it work:

Describe Alternatives

First case (importing external library, not lazy component) can be resolved with rollup plugin defined in stencil.config.ts:

export function externalsPlugin(externals: (string | RegExp)[]) {
    return {
        id: "externalsPlugin",
        resolveId(id: string) {
            for (const e of externals) {
                if ((typeof e === "string" && id === e) || (e instanceof RegExp && e.exec(id))) {
                    return {id, external: true}
                }
            }
        }
    }
}
Related Code

No response

Additional Information

No response

主要言語
TypeScript
スター
13.2k
フォーク
865
平均マージ
2日 16時間
マージ済み PR(30日)
29

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

stenciljs/core のほかの issue

stenciljs/core の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。