ブログに戻る
UIcross-platformreleasemilestone

6 つのプラットフォームすべてで完全な機能パリティ

This dated article records the Perry version and measurements available when it was published. Use the current limitations, platform guide, and benchmark artifact for decisions today.

Perryのネイティブ UIシステムの最初のバージョンを出荷した時、「クロスプラットフォーム」とは macOSがうまく動き、他の5つのプラットフォームはスタブという意味でした。v0.2.162の今日、 それはもう当てはまりません。6つのプラットフォームすべて — macOS、iOS、iPadOS、Android、Linux、Windows — が 完全な機能パリティを共有しています。同じTypeScriptコードがすべてのターゲットでネイティブウィジェットにコンパイルされます。

この記事では、v0.2.152からv0.2.164の間に出荷したものを紹介します:Canvasウィジェット、 完全なNSTableView実装、20以上のUIウィジェット、 perry/system モジュール、マルチウィンドウサポート、 システム通知、キーチェーンアクセス、自動バイナリサイズ削減、そしてコンパイル時プラグインシステム。 多くのことがありました。

ウィジェットスプリント:20以上のネイティブUIコンポーネント

最大の進歩はv0.2.155で、全プラットフォームにわたって20以上のUIウィジェットが追加されました。 PerryのTypeScript UI APIは、実際のアプリを出荷するために必要なコンポーネントをカバーしています:

  • レイアウト — VStack、HStack、ZStack、LazyVStack、ScrollView、SplitView
  • 入力 — Button、TextField、TextEditor、Checkbox、Toggle、Slider、Picker
  • 表示 — Text、Label、Image、ProgressView、Divider、Spacer
  • データ — List、Table(NSTableView / GTK4 TreeView / Win32 ListView)
  • オーバーレイ — Alert、Sheet、Popover、Toolbar、NavigationBar
  • 描画 — Canvas(2D描画API、プラットフォームごとにハードウェアアクセラレーション)

これらはカスタムレンダラーのラッパーではありません。各ウィジェットはプラットフォーム固有の ネイティブコンポーネントにコンパイルされます:macOSでは NSButton、 iOSでは UIButton、 Linuxでは GtkButton、 AndroidではJNI経由で android.widget.Button、 Windowsでは CreateWindowEx。 OSがそれらを描画し、テーマを適用し、アクセシビリティを処理します — Perryは TypeScript APIを接続するだけです。

Canvas:TypeScriptからの2D描画

技術的に最も興味深い追加の1つがCanvasウィジェット(v0.2.152)です。TypeScriptから直接 馴染みのある2D描画API — ベジェ曲線、塗りつぶし、ストローク、画像ブリッティング — を公開し、 プラットフォームのアクセラレーテッド2Dバックエンドにコンパイルされます: macOS/iOSではCore Graphics、LinuxではCairo、WindowsではDirect2D、AndroidではSkia。

canvas.ts

import { Canvas, Color } from 'perry/ui';

// Compiles to Core Graphics on macOS, Cairo on Linux, etc.

const canvas = new Canvas({ width: 400, height: 300 });

canvas.onDraw((ctx) => {

ctx.fillStyle = Color.amber;

ctx.fillRect(10, 10, 100, 60);

ctx.strokeStyle = Color.blue;

ctx.lineWidth = 2;

ctx.beginPath();

ctx.arc(200, 150, 80, 0, Math.PI * 2);

ctx.stroke();

});

Tableウィジェット:NSTableViewがTypeScriptに

v0.2.163でTableウィジェットが追加されました — ライブラリ内で最も複雑なコンポーネントです。macOSでは 完全なdelegate/data sourceの接続を持つ NSTableView に対応します。 LinuxではGTK4の GtkTreeView を使用します。Windowsでは Win32の ListView コントロール。AndroidではJNIを通じて RecyclerView にバインドされます。

TypeScript APIは宣言的です:カラムを定義し、データソースを提供すれば、Perryがコンパイル時に プラットフォーム固有の接続を処理します。カラムソート、選択ハンドリング、行の高さ カスタマイズがすべてそのまま動作します。

table.ts

import { Table, Column } from 'perry/ui';

const table = new Table({

columns: [

new Column({ title: "Name", key: "name", width: 200 }),

new Column({ title: "Size", key: "size", width: 80 }),

],

rows: files, // TypeScript array of objects

onSelect: (row) => console.log(row.name),

});

perry/system モジュール

v0.2.155では perry/system も導入されました — ランタイムなしで プラットフォームのシステムAPIを公開するTypeScriptモジュールです:ファイルダイアログ、 保存ダイアログ、アラート、シート、キーチェーンアクセス、システム通知、マルチウィンドウ管理。

  • system.showOpenDialog() — ネイティブファイルピッカー(NSOpenPanel / GTK FileChooser / Win32 OPENFILENAME)
  • system.showSaveDialog() — ネイティブ保存ダイアログ
  • system.showAlert() — ネイティブアラートパネル
  • system.notify() — OS通知(UserNotifications / libnotify / WinRT)
  • system.keychain.get/set() — Keychain Services / Secret Service / Windows Credential Store
  • system.openWindow() — マルチウィンドウ管理

これらはすべてネイティブプラットフォームAPIを直接呼び出します — Electron IPCもWeb Viewブリッジもありません。 PerryはTypeScriptの呼び出しサイトをプラットフォームSDKへの直接的なネイティブ関数呼び出しにコンパイルします。

6プラットフォーム機能パリティ:v0.2.162

v0.2.162のマイルストーンはギャップを埋めることでした。このリリース前は、macOSが最も充実した 機能セットを持ち、iOSはほぼ揃っていましたが、Linux/Windows/Androidは遅れていました。v0.2.162は 6つのプラットフォームすべてを同じレベルに引き上げました:

  • macOS — AppKit、完全なウィジェットセット、Keychain、通知、マルチウィンドウ、ツールバー
  • iOS / iPadOS — UIKit、macOSとの完全なウィジェットパリティ、シーンライフサイクル
  • Android — JNIブリッジ、Android Views経由の全ウィジェット、NDKクロスコンパイル
  • Linux — GTK4、Tableを含む完全なウィジェットセット、ファイルダイアログ、libsecretキーチェーン
  • Windows — Win32、全ウィジェット、Windows Credential Store、WinRT通知

これは「1つのコードベース、6つのプラットフォーム」を願望ではなく現実にするマイルストーンです。 同じTypeScriptファイルが、一般的なユースケースに対してプラットフォーム固有の コードパスを必要とせず、6つすべてのターゲットでネイティブアプリにコンパイルされます。

自動バイナリサイズ削減

v0.2.153では自動バイナリサイズ削減が出荷されました — コンパイラは使用されていないコードパスを 積極的にデッドストリップし、到達不能なstdlib関数を排除し、リンク時にシンボル定義を 重複排除するようになりました。以前は約4 MBにコンパイルされていた典型的なCLIツールが、 ソースを変更することなく2 MB以下になります。

これは実際のデプロイメントにとって重要です。バイナリがデプロイメントの単位である場合 — サーバーにコピーしたり、 単一ファイルとして配布したり、コンテナに埋め込んだり — サイズは転送時間とストレージコストに 直接影響します。バイナリサイズを無料で半分にすることは意味のある改善です。

コンパイル時プラグインシステム

v0.2.152ではPerryのプラグインシステムが導入されました — そしてそれはTypeScriptエコシステムの 他のあらゆるプラグインシステムとはアーキテクチャ的に異なります。ランタイムプラグインローディングなし、 IPCなし、動的な require() なし。プラグインはPerryがビルド時に 解決しコンパイルするTypeScriptモジュールです。

結果:プラグインのランタイムオーバーヘッドは完全にゼロです。アプリケーションコードと同じバイナリにコンパイルされ、 プラグインコードとホストコード間は直接関数呼び出しです。プラグインを使わなければ、 バイナリにまったく含まれません。使えば、他のモジュールと同様にインライン化されます。

この背景にある哲学については プラグインシステムはパフォーマンスの税金で書きました。要約すると:ランタイムプラグインアーキテクチャはパフォーマンスと拡張性をトレードオフします。 ビルド時コンポジションは両方を実現します。

言語の改善

UIスプリントは単独で起こったわけではありません — コンパイラ自体も継続的により高機能になりました。 これらのリリースを通じて:

  • クラス式const Foo = class extends Bar {} が正しくコンパイルされるようになりました
  • ジェネレータ変換function*yield がネイティブステートマシンにコンパイルされます
  • クラスフィールドとしてのMap/Setprivate items = new Map() がコード生成で動作します
  • FFIパラメータ型強制 — ネイティブライブラリ呼び出しが型強制を自動的に処理します
  • バウンドメソッド参照this.method 参照がネイティブモジュール(fs、os、path)で動作します
  • string.match() — 完全サポートされるようになりました
  • path.isAbsolute()、マルチ引数 path.join()path.resolve()
  • Webターゲット — Perryはハイブリッドデプロイメント用のWeb互換出力にコンパイルできるようになりました

次のステップ

6プラットフォームのUIパリティが出荷されたので、次のフェーズは広さよりも深さです。現在取り組んでいるのは:

  • 完全なRegExpサポート(regex.test()string.matchAll()
  • ウィジェットシステムでのドラッグアンドドロップ、カスタムコンテキストメニュー、アクセシビリティラベル
  • Perry診断とコンパイル・オン・セーブのためのVS Code拡張機能
  • パッケージマネージャー統合 — Perryネイティブパッケージのインストールとコンパイルを1コマンドで
  • ブラウザデプロイメント用のWASMコンパイルターゲット
  • Worker スレッドによるマルチスレッディング

フォローしたい方は、 Perryリポジトリがオープンです。 ショーケース で既に構築されているものを確認するか、 ロードマップ で全体像をご覧ください。

この記事が気に入ったら、次の記事も受け取りませんか?

Perryのリリースと次の開発内容を短くお届け。

Your email is sent to Resend for the Perry newsletter. You can request unsubscribe or deletion at any time. Privacy notice