インストール
npm install tuvix.js
# or pnpm add tuvix.jstuvix.jsをインストールすると、@tuvix.js/core、@tuvix.js/router、@tuvix.js/event-bus、@tuvix.js/loader、@tuvix.js/sandboxがインストールされます。6つのパッケージはすべてES moduleとCommonJSのビルドを提供し、"sideEffects": falseを宣言しています。
使いどころ
オーケストレーターをルーター、イベントバス、サンドボックスと組み合わせて使うシェルアプリケーションには、tuvix.jsをインストールしてください。バージョン管理する依存関係とimportパスがそれぞれ1つになり、importしないエクスポートはバンドラーが取り除きます。
次の場合は、代わりにスコープ付きパッケージをインストールしてください。
- マイクロアプリがシェルとだけやり取りする場合。
@tuvix.js/event-bus単体でgetGlobalBus()を利用でき、オーケストレーターがそのnode_modulesに入りません。 - 統合パッケージに含まれないエクスポートが必要な場合。たとえば
@tuvix.js/loaderのregisterModuleやemitLifecycle、@tuvix.js/routerのpathToRegexです。含まれないものを参照してください。 - パッケージがTuvix.jsのどの部分に依存しているかを
package.jsonで明示したい場合。
両方を混在させても安全です。統合パッケージは同じモジュールを再エクスポートするため、tuvix.jsのgetGlobalBusと@tuvix.js/event-busのgetGlobalBusは同じバスを返し、ライフサイクルヘルパーはwindow上の1つのレジストリを共有します。
クイックスタート
/aboutでaboutをマウントし、リンクのクリックをルーターのナビゲーションに変換し、アプリのエラーをログに出すシェルです。
import { createOrchestrator, getGlobalBus, interceptLinks, OrchestratorEvent, type AppErrorEvent } from 'tuvix.js';
const orchestrator = createOrchestrator({ router: { routes: [] } });
orchestrator.register({
name: 'about',
entry: 'https://cdn.example.com/about/main.js',
container: '#main',
activeWhen: '/about',
props: { who: 'us' },
});
getGlobalBus().on<AppErrorEvent>(OrchestratorEvent.APP_ERROR, ({ name, error, phase }) => {
console.error(`${name} failed during ${phase}`, error);
});
await orchestrator.start();
interceptLinks({ navigate: (path) => orchestrator.navigateTo(path) });https://cdn.example.com/about/main.jsにビルドされるaboutアプリです。
import { defineMicroApp } from 'tuvix.js';
export default defineMicroApp({
name: 'about',
mount({ container, props }) {
container.innerHTML = `<h1>About ${String(props?.who)}</h1>`;
},
unmount({ container }) {
container.replaceChildren();
},
});<a href="/about?ref=nav">をクリックすると/about?ref=navがpushされ、オーケストレーターがaboutを#mainにマウントします(クエリ文字列はマッチングに影響しません)。
API
以下のエクスポートはすべて再エクスポートです。シグネチャ、オプション、エッジケースはリンク先のパッケージページに記載されています。
@tuvix.js/coreから
ドキュメント:@tuvix.js/core。
| エクスポート | 種類 | 内容 |
|---|---|---|
createOrchestrator | 関数 | Orchestratorを作成します。 |
Orchestrator | クラス | アプリを登録し、URLに合わせてreconcileし、ルーターに追従し(connectRouter)、propsを更新し、破棄します。 |
defineMicroApp | 関数 | { name, bootstrap?, mount, unmount, update?, ssr? }オブジェクトを検証し、ローダー向けに登録し、tuvix:mounted / tuvix:unmounted / tuvix:errorを発行するようにします。 |
OrchestratorEvent | enum | オーケストレーターがバスに発行するイベント名(tuvix:app:mount、tuvix:app:errorなど)。 |
OrchestratorConfig、MicroAppConfig、MicroAppDefinition | 型 | createOrchestrator、register、defineMicroAppの引数。 |
AppStatus、AppSandboxOption、RouterSource、RegisteredApp | 型 | アプリのステータスのunion、sandboxオプション、connectRouterの引数、アプリのレコードの形。 |
AppErrorEvent、AppErrorPhase | 型 | APP_ERRORのペイロード{ name, error, phase }と、そのphaseのunion('load'、'bootstrap'、'mount'、'update'、'unmount')。 |
@tuvix.js/event-busから
ドキュメント:@tuvix.js/event-bus。
| エクスポート | 種類 | 内容 |
|---|---|---|
EventBus | クラス | on、once、emit、off、onAnyを持つPub/Subバス。 |
createEventBus | 関数 | 新しい独立したEventBusを作成します。 |
getGlobalBus | 関数 | window.__TUVIX_GLOBAL_BUS__に保存されたページ全体のバスを返します。オーケストレーターはデフォルトでこれを使います。 |
resetGlobalBus | 関数 | ページ全体のバスを破棄します。次のgetGlobalBus()が新しいバスを作成します。 |
IEventBus、EventHandler、WildcardHandler、Unsubscribe、EventBusOptions | 型 | バスのインターフェース、ハンドラーのシグネチャ、購読解除関数、コンストラクターのオプション。 |
@tuvix.js/routerから
ドキュメント:@tuvix.js/router。
| エクスポート | 種類 | 内容 |
|---|---|---|
Router | クラス | パスをアプリ名に対応付けるhistoryまたはhashのルーター。 |
createRouter | 関数 | Routerを作成します。 |
matchPath | 関数 | パスをパターンとマッチさせます(:param、/*に対応し、クエリとハッシュは無視)。activeWhenの文字列はこれを使います。 |
matchRoute | 関数 | RouteConfig[]のうちパス全体にマッチする最初のルートを、paramsとquery付きで返します。 |
normalizePath | 関数 | 先頭にスラッシュを付け、末尾のスラッシュを取り除きます。 |
interceptLinks | 関数 | 同一オリジンのリンクのクリックをnavigate(path)の呼び出しに変換します。インテントに基づくプリフェッチもオプションで行えます。 |
resolveLink | 関数 | イベントが発生したHTMLリンクについて{ anchor, url, path }を返します。ブラウザに処理を任せるべき場合はnullを返します。 |
IRouter、RouterConfig、RouterMode、RouteConfig、MatchedRoute | 型 | ルーターのインターフェース、オプション、ルートの形。 |
NavigationEvent、NavigationGuard、RouteChangeHandler | 型 | ナビゲーションのペイロード、ガード、リスナーのシグネチャ。 |
PathMatch、MatchPathOptions、InterceptLinksOptions、ResolvedLink、ResolveLinkOptions | 型 | matchPathの結果とオプション、interceptLinksのオプション、resolveLinkの結果とオプション。 |
@tuvix.js/loaderから
ドキュメント:@tuvix.js/loader。
| エクスポート | 種類 | 内容 |
|---|---|---|
ModuleLoader | クラス | エントリー(URL、script/styleの設定、またはローダー関数)を、タイムアウト、再試行、キャッシュ付きでロードします。 |
createLoader | 関数 | ModuleLoaderを作成します。 |
whenMounted | 関数 | アプリがmountedライフサイクルイベントを発行したときにresolveします。 |
onLifecycle | 関数 | tuvix:mounted、tuvix:unmounted、tuvix:errorのDOMイベントを監視します。 |
isMounted | 関数 | ライフサイクルイベントに基づき、アプリのいずれかのコンテナがマウントされている間はtrueです。 |
Entry、EntryConfig、MicroAppModule、MountContext、UnmountContext、UpdateContext | 型 | エントリーの形式と、マイクロアプリが実装するライフサイクルの契約。 |
LoaderOptions、LoadResult、LoadStatus、PrefetchStrategy | 型 | ローダーのオプションと結果。 |
LifecycleType、LifecycleDetail、LifecycleEvent | 型 | ライフサイクルイベントの名前、ペイロード、DOMイベントの型。 |
import { onLifecycle, whenMounted } from 'tuvix.js';
const off = onLifecycle('error', ({ name, error }) => console.error(name, error));
const { container, hydrated } = await whenMounted('footer', { signal: AbortSignal.timeout(5000) });
console.log(container.id, hydrated);
off();@tuvix.js/sandboxから
ドキュメント:@tuvix.js/sandbox。
| エクスポート | 種類 | 内容 |
|---|---|---|
CssSandbox | クラス | コンテナをshadow rootに移し、その中でスタイルシートをロードします。オーケストレーターはsandbox: trueのときにこれを使います。 |
JsSandbox | クラス | スクリプトが書き込むグローバルを実際のwindowから隔離するProxyのwindow。 |
Sandbox | クラス | CssSandboxとJsSandboxを1組のactivate / deactivateの背後にまとめたもの。 |
createSandbox | 関数 | Sandboxを作成します。 |
SandboxOptions、ISandbox、ICssSandbox、IJsSandbox | 型 | サンドボックスのオプションとインターフェース。 |
AdoptStylesOptions、AdoptedStyles | 型 | CssSandbox.adoptStylesの引数と戻り値。 |
含まれないもの
統合パッケージには以下が含まれません。それらを提供するパッケージをインストールしてください。
| 必要なもの | インストールするもの |
|---|---|
registerModule、unregisterModule、getRegisteredModule、emitLifecycle、hasServerMarkup、normalizeEntry、loadScript、loadStyle、removeScript、removeStyle、prefetchResource、および型EntryLoader、EntryLoaderContext、MicroAppBus、ScriptType、CacheEntry、ResourceOptions、LoadScriptOptions、LoadStyleOptions、PrefetchOptions | @tuvix.js/loader |
pathToRegex、parseQuery、isPathActive | @tuvix.js/router |
| React、Vue、Svelte、Angularのマイクロアプリ | @tuvix.js/react、@tuvix.js/vue、@tuvix.js/svelte、@tuvix.js/angular |
| サーバーサイドでの合成 | @tuvix.js/server |
| Module Federationのリモート | @tuvix.js/module-federation |
| Viteビルドでのアイランドのアセット | @tuvix.js/vite |
| DevToolsパネル | @tuvix.js/devtools |
| プロジェクトのスキャフォールディング | create-tuvix-app |
エッジケース
tuvix.jsのエントリーポイントは1つです。tuvix.js/coreやtuvix.js/routerのようなサブパスのimportは解決に失敗します。tuvix.jsまたはスコープ付きパッケージからimportしてください。- 統合パッケージは依存関係を同じリリースに固定しています。
tuvix.jsと並べて別バージョンのスコープ付きパッケージをインストールすると、そのパッケージのコピーが2つできます。getGlobalBus()とライフサイクルのレジストリは引き続きwindowを通じて状態を共有しますが、instanceof Orchestratorやinstanceof EventBusのチェックはコピー間で失敗します。 whenMounted、onLifecycle、isMountedはtuvix:*のDOMイベントに反応します。defineMicroAppとフレームワークアダプターのモジュールはこれらを発行しますが、手書きのモジュールは@tuvix.js/loaderのemitLifecycleを呼び出さない限り何も発行しません。ドキュメント外にあるコンテナのイベントはdocumentでディスパッチされます。resetGlobalBus()は、実行中のオーケストレーターが保持しているバスを破棄します。オーケストレーターは破棄されたそのバスを保持し続けるため、そのイベントは次のgetGlobalBus()の購読者に届かなくなります。テストの合間に、orchestrator.destroy()の後で呼び出してください。@tuvix.js/coreと@tuvix.js/routerの挙動の変更と破壊的変更は、そのままここにも当てはまります。0.4からの移行を参照してください。
しないこと
- 独自のコードは追加しません。すべてのエクスポートは5つのスコープ付きパッケージのいずれかから来ています。
- フレームワークアダプター、サーバーパッケージ、Module Federation、Vite、DevToolsは含まれません。
- パッケージごとのサブパスエントリーは提供しません。