モジュールのバンドル
ステンシルは、内部でRollupを使用してコンポーネントをバンドルします。 このガイドでは、発生する可能性のある最も一般的なバンドルの問題のいくつかについて、特定の回避策について説明し、推奨します。
モジュールごとに1つのコンポーネント
Stencilでコンポーネントを最も効率的にバンドルするには、TypeScriptファイルごとに単一のコンポーネント(@Component
で装飾されたクラス)を宣言する必要があり、コンポーネント自体には一意のexport
が必要です。 そうすることで、ステンシルはアプリ内のコンポーネントグラフ全体を簡単に分析し、コンポーネントをどのようにバンドルするかを最もよく理解できます。 内部的には、Rollupバンドラーを使用して、共有コードを効率的にバンドルします。 さらに、遅延読み込みはStencilのデフォルト機能であるため、コード分割はすでに自動的に行われており、ページで使用されているコンポーネントのみが動的にインポートされます。
コンポーネントを含むモジュールはエントリポイントです。つまり、他のモジュールはそれらから何もインポートしないでください。
次の例は無効です。
src/components/my-cmp.tsx:
// This module has a component, you cannot export anything else
export function someUtilFunction() {
console.log('do stuff');
}
@Component({
tag: 'my-cmp'
})
export class MyCmp {}
この場合、コンパイラは次のようなエラーを出力します。
[ ERROR ] src/components/my-cmp.tsx:4:1
To allow efficient bundling, modules using @Component() can only have a single export which is the component
class itself. Any other exports should be moved to a separate file. For further information check out:
https://stenciljs.com/docs/module-bundling
L4: export function someUtilFunction() {
L5: console.log('do stuff');
解決策は、次のように、共有関数またはクラスを別の .ts
ファイルに移動することです。
src/utils.ts:
export function someUtilFunction() {
console.log('do stuff');
}
src/components/my-cmp.tsx:
import { someUtilFunction } from '../utils.ts';
@Component({
tag: 'my-cmp'
})
export class MyCmp {}
src/components/my-cmp-two.tsx:
import { someUtilFunction } from '../utils.ts';
@Component({
tag: 'my-cmp-two'
})
export class MyCmpTwo {}
CommonJSの依存関係
ロールアップは、ESモジュール(ESM)に依存して、モジュールグラフを適切にツリーシェイクしますが、残念ながら一部のサードパーティのライブラリは、CommonJSモジュールシステムを使用してコードを出荷しますが、これは理想的ではありません。
CommonJSライブラリは今日でも一般的であるため、Stencilにはrollup-plugin-commonjs
が既にインストールおよび構成されています。
コンパイラ時に、 rollup-plugin-commonjs
プラグインはCommonJSをESMに変換するために最善を尽くしますが、これは必ずしも簡単な作業ではありません。 CommonJSは本質的に動的ですが、ESMは設計上静的です。
Stencilの構成は、RollupCommonJSプラグインに渡される commonjs
プロパティを公開します。この設定を使用して、特定のバンドルの問題を回避できます。
NamedModules:XはXによってエクスポートされません
Rollupは、CommonJSモジュールを適切に静的に分析できず、一部の名前付きエクスポートを見逃す場合があります。幸い、使用できる回避策があります。
すでに知っているように、 stencil.config.ts
はcommonjs
プロパティを公開します。この場合、[namedExports
プロパティ](https://github.com/rollup/rollup-plugin-)を利用できます。 commonjs#custom-named-exports)。
たとえば、 commonjs-dep
モジュールのexportという名前のhello
を使用しようとすると、ロールアップが失敗したとします。
// NamedModules: hello is not exported by commonjs-dep
import { hello } from 'commonjs-dep';
この問題を回避するには、 stencil.config.ts
ファイルのconfig.commonjs.namedExports
設定を使用できます。
export const config = {
commonjs: {
namedExports: {
// commonjs-dep has a "hello" export
'commonjs-dep': ['hello']
}
}
}
問題のある依存関係に対して
namedExports
のマップを設定できます。この場合、commonjs-dep
モジュールで名前付きhello
エクスポートを明示的に定義しています。
詳細については、rollup-plugin-commonjsドキュメントを確認してください。
カスタムロールアッププラグイン
Stencilは、カスタムロールアッププラグインを stencil.config.ts
のバンドルプロセスに渡すためのAPIを提供します。 内部的には、ステンシルには
node-resolve
やcommonjs
などの組み込みプラグインが付属しています。一部のロールアッププラグインの実行順序が重要であるため、ステンシルはノード解決の前にカスタムプラグインを挿入するAPIを提供します。 commonjs変換後:
export const config = {
rollupPlugins: {
before: [
// Plugins injected before rollupNodeResolve()
resolvePlugin()
],
after: [
// Plugins injected after commonjs()
nodePolyfills()
]
}
}
経験則として、モジュールを解決する必要のあるプラグインは
before
に配置する必要がありますが、node-polyfills
、 replace
...などのコード変換プラグインはafter
に配置する必要があります。 プラグインのドキュメントに従って、プラグインが正しい順序で実行されていることを確認してください。
ノードポリフィル
プロジェクトが依存しているライブラリによっては、rollup-plugin-node-polyfillsプラグインが必要になる場合があります。 このような場合、ビルド時に次のようなエラーメッセージが表示されます。
[ ERROR ] Bundling Node Builtin
For the import "crypto" to be bundled from 'problematic-dep',
ensure the "rollup-plugin-node-polyfills" plugin is installed
and added to the stencil config plugins.
これは、ブラウザで使用できないNode APIを使用するサードパーティの依存関係である rollup-pluginが原因で発生します。 -node-polyfills
プラグインは、ブラウザでこの欠落しているAPIを透過的にポリフィルすることで機能します。
1.
rollup-plugin-node-polyfills
をインストールします。
npm install rollup-plugin-node-polyfills --save-dev
2. プラグインを含む stencil.config.ts
ファイルを更新します。
import { Config } from '@stencil/core';
import nodePolyfills from 'rollup-plugin-node-polyfills';
export const config: Config = {
namespace: 'mycomponents',
rollupPlugins: {
after: [
nodePolyfills(),
]
}
};
注:
rollup-plugin-node-polyfills
はコード変換プラグインであるため、commonjs変換プラグインの後に実行する必要があります。これが、プラグインの「後」配列に配置される理由です。
strictモード
ESモジュールは常に厳密モードで解析されます。 つまり、特定の非厳密な構成(8進リテラルなど)は、ロールアップがそれらを使用するモジュールを解析するときに構文エラーとして扱われます。 一部の古いCommonJSモジュールはこれらの構造に依存しており、それらに依存するとバンドルが爆発します。 それについて私たちにできることは何もありません。
幸いなことに、すべてに厳密モードを使用しない理由はまったくありません。したがって、この問題の解決策は、これらのモジュールの作成者にロビー活動を行ってモジュールを更新することです。
ソース: https://github.com/rollup/rollup-plugin-commonjs#strict-mode
Contributors
Thanks for your interest!
We just need some basic information so we can send the guide your way.