メインコンテンツへ飛ぶ

プロトコルハンドラの脆弱性の修正

· 読むのにかかる時間 1 分

遠隔コード実行の脆弱性が発見されました。これはカスタムプロトコルハンドラを使用している Electron アプリに影響します。 この脆弱性には CVE 識別子 CVE-2018-1000006 が割り当てられています。


影響を受けるプラットフォーム​

Windows 向けに設計された Electron アプリが影響を受けます。myapp:// のようなプロトコルのデフォルトハンドラに自身を登録することで起きる脆弱性です。

ネイティブコード、Windows レジストリ、Electron の app.setAsDefaultProtocolClient API を使用しているようなアプリは、プロトコルの登録方法に関係なく影響を受ける可能性があります。

macOS と Linux には、この問題での 脆弱性はありません。

緩和策​

この脆弱性に対する修正を含む新しいバージョンの Electron を公開しました。 1.8.2-beta.5、 1.7.12、 1.6.17 です。 Electron 開発者全員は、アプリをすぐに最新の安定バージョンに更新することを推奨します。

何らかの理由で Electron バージョンをアップグレードできない場合は、app.setAsDefaultProtocolClient を呼び出すときに、最後の引数として -- を追加します。これにより、Chromium がそれ以降の引数を解析しなくなります。 ダブルダッシュ - はコマンドオプションの終わりを示し、その後は位置引数のみを受け入れます。

app.setAsDefaultProtocolClient(protocol, process.execPath, [
'--your-switches-here',
'--',
]);

詳細については、app.setAsDefaultProtocolClient を参照してください。

Electron アプリを堅牢に保つベストプラクティスの詳細は、セキュリティチュートリアル を参照してください。

Electron の脆弱性を報告する場合は、security@electronjs.org にメールでご連絡お願いします。

Electron 2.0 以降 - セマンティックバージョニング

· 読むのにかかる時間 1 分

新しいメジャーバージョンの Electron が開発中です。そこで、バージョン管理戦略にいくつかの変更を加えます。 バージョン 2.0.0 から、Electron はセマンティックバージョニングに厳密に従います。


この変更によりメジャーバージョンが頻繁に上がるようになり、これは通常 Chromium 対応のメジャーアップデートになります。 また、パッチリリースにはバグ修正のみが含まれ、新機能を含みません。そのため、パッチリリースの安定性も向上します。

メジャーバージョンの単位

  • Chromium のバージョン更新
  • Node.js のメジャーバージョン更新
  • 互換性を破る Electron API の変更

マイナーバージョンの単位

  • Node.js のマイナーバージョン更新
  • 互換性を破らない Electron API の変更

パッチバージョンの単位

  • Node.js のパッチバージョン更新
  • Chromium パッチの修正関連
  • Electron のバグ修正

Electron の semver 範囲がより意味を持つようになるため、Electron をインストールする時は npm 既定の --save-dev フラグの使用を推奨します。これにより、バージョンの前に ^ が付けられ、マイナーやパッチの更新を安全にできます。

npm install --save-dev electron

バグ修正にのみ関心がある開発者は、チルダを前に付けた semver を使用するとよいでしょう。~2.0.0 は、新機能は導入せずに安定性を改善する修正のみを導入します。

詳細は、electronjs.org/docs/tutorial/electron-versioning を参照してください。

Electron の新しい国際化されたサイト

· 読むのにかかる時間 1 分

Electron の新しいウェブサイトは electronjs.org です! 静的な Jekyll サイトを Node.js ウェブサーバに置き換えました。これにより、サイトの国際化が柔軟になり、より魅力的な新機能への道が開かれました。


🌍 翻訳​

私たちは、世界中の開発者が Electron アプリ開発に着手できることを目標に、ウェブサイトの国際化プロセスを開始しました。 私たちは Crowdin という翻訳プラットフォームを使用しています。これは GitHub と統合されており、コンテンツが異なる言語に翻訳されると自動的にプルリクエストを開いて更新します。

簡体字中国語での Electron のナビゲーションバー

私たちはこれまで静かにこの取り組みを進めていました。75 人以上もの Electron コミュニティメンバーは、すでにプロジェクトを組織的に構築し、Web サイトの国際化と、Electron のドキュメントを 20 以上の言語に翻訳する取り組みに参加しています。 翻訳における世界中の 日毎の貢献数 では、特にフランス語、ベトナム語、インドネシア語、中国語の言語が抜きんでています。

各言語を選択してその言語の翻訳の進捗状況を確認するには、 electronjs.org/languages を参照してください。

Crowdin 上の翻訳状況

マルチリンガルの方で Electron のドキュメントやウェブサイトの翻訳に興味があれば、electron/electron-i18n のレポジトリにアクセスするか、Crowdin ですぐに翻訳を始められます。

現在 Crowdin の Electron 翻訳プロジェクトで有効な言語は 21 つです。 さらなる言語のサポート追加は簡単ですので、翻訳に興味があるもの翻訳したい言語がリストにない場合は、こちらからご連絡くだされば 有効にします。

レンダリング前の翻訳のドキュメント​

生の Markdown ファイルでドキュメントを読みたい場合でも、以下のようにすれば任意の言語で読むことができるようになりました。

git clone https://github.com/electron/electron-i18n
ls electron-i18n/content

アプリページ​

本日から、どのような Electron アプリでも、独自のページをこのサイト上へ簡単に作成できます。 例えば、Etcher や 1Clipboard や GraphQL Playground があります。ここではサイトの日本語版を示しています。

GraphQL プレイグラウンド

Electron には素晴らしいアプリがいくつもありますが、それらを見つけるのは簡単ではありませんし、すべての開発者がアプリを市場に出して頒布するために適切なウェブサイトを構築する時間やリソースを持っているわけではありません。

PNG アイコンファイルとアプリメタデータが少しあれば、特定のアプリに関する多くの情報を収集できます。 GitHub から収集したデータで、公開リポジトリがある全アプリのスクリーンショット、ダウンロードリンク、バージョン、リリースノート、README をアプリページに表示できるようになりました。 各アプリのアイコンから抽出したカラーパレットを使用しつつ、強調されたアクセシビリティの高い色 を作成し、各アプリページに視覚の分別をつけることもできます。

アプリのインデックスページ には、GraphQL GUI や p2p ツール のような面白いアプリを見つけられるように、カテゴリとキーワードフィルタが追加されました。

サイトで紹介したい Electron アプリがある方は、ぜひ electron/electron-apps リポジトリでプルリクエストを開いてください。

Homebrew でワンラインインストール​

macOS のパッケージマネージャー Homebrew には cask というサブコマンドがあります。brew cask install atom のようにすれば、ターミナル上のコマンド一つでデスクトップアプリを簡単にインストールできます。

人気の Electron アプリの Homebrew cask の名前の収集を開始し、cask があるすべてのアプリのページにインストールコマンド (macOS の訪問者向け) を表示するようにしました。

プラットフォームに合わせたインストールオプション: macOS、Windows、Linux

Homebrew cask の名前を持つすべてのアプリを表示するには、electronjs.org/apps?q=homebrew をご覧ください。 まだインデックスされていない cask のアプリをご存知でしたら、ぜひ追加してください!

🌐 新ドメイン​

このサイトを electron.atom.io から新しいドメインに移動しました: electronjs.org。

Electron プロジェクトは、ウェブ技術で構築した GitHub のオープンソーステキストエディタ Atom の中から生まれました。 Electron は元々 atom-shell と呼ばれていました。 最初に使用したアプリは Atom でしたが、ほどなくしてこの魔法のような Chromium + Node ランタイムがあらゆるタイプのアプリケーションにも利用できると気づきました。 Microsoft や Slack のような企業が atom-shell を利用し始めた頃、このプロジェクトには新しい名前が必要だろうということになりました。

そして "Electron" が生まれたのです。 2016 年の初め、GitHub は Atom と別に Electron の開発とメンテナンス特化の新チームを結成しました。 それ以来 Electron は何千ものアプリ開発者に採用されています。現在では多くの大企業に採用され、その多くが独自の Electron チームをも保有しています。

Atom や GitHub Desktop のような GitHub の Electron プロジェクトサポートも未だに私たちチームの優先事項です。しかし、新ドメインへの移行が Atom と Electron の技術的区別をより明確にできるであろうと願っています。

🐢🚀 どこでもNode.js​

以前の Electron ウェブサイトは、Ruby ベースの静的サイト生成ツールとして人気の Jekyll で構築していました。 Jekyll は静的ウェブサイトの構築に最適なツールですが、このウェブサイトではそれを使いこなせなくなり始めていました。 適切なリダイレクトや動的なコンテンツの描画等より動的な機能が欲しかったため、Node.js サーバーは当然の選択でした。

Electron のエコシステムには、Python から C++ や Bash まで、さまざまなプログラミング言語で書かれたコンポーネントのプロジェクトが含まれています。 しかし Electron の基礎は JavaScript であり、私たちのコミュニティで最も使用されている言語です。

ウェブサイトを Ruby から Node.js に移行することで、ウェブサイトに貢献したい人の敷居を低くすることが目標です。

⚡️ より簡単になったオープンソースへの参加​

Node.js (8 以降) と git をインストールしていれば、ローカルで簡単にサイトを動かせます。

git clone https://github.com/electron/electronjs.org
cd electronjs.org
npm install
npm run dev

この新しいウェブサイトはHerokuでホストされています。 デプロイパイプラインと アプリプレビュー 機能を使用しています。これにより、プルリクエストごとにアプリの動作するコピーを自動作成できます。 これにより、レビュアーはプルリクエストの実際の効果を、サイトの生き写しで簡単に確認できます。

🙏 貢献者への感謝​

Electron の改善に時間と労力を提供してくださった世界中の皆様に特別な感謝の意を表したいと思います。 オープンソースコミュニティの情熱が Electron の成功を大きく支えています。 ありがとうございます!

いいね!

Chromium RCE の脆弱性の修正

· 読むのにかかる時間 1 分

Google Chromium で、すべての最新バージョンの Electron に影響するリモートコード実行の脆弱性が発見されました。 リモートコンテンツにアクセスする Electron アプリは、sandbox オプション の有効に関係なく、このエクスプロイトに対する脆弱性があります。

1.7.8 と 1.6.14 の 2 つの新しいバージョンの Electron を公開しました。どちらもこの脆弱性の修正が含まれています。 Electron 開発者全員は、アプリをすぐに最新の安定バージョンに更新することを推奨します。

npm i electron@latest --save-dev

Electron アプリを堅牢に保つベストプラクティスの詳細は、セキュリティチュートリアル を参照してください。

Electron の脆弱性を報告したい場合は、security@electronjs.org までご連絡ください。

Electron での TypeScript サポートを発表

· 読むのにかかる時間 1 分

Electron npm パッケージに、Electron API 全体の詳細なアノテーションを提供する TypeScript 定義ファイルが含まれるようになりました。 これらのアノテーションは、たとえ純粋なJavaScriptを書いていていても、Electron の開発エクスペリエンスを向上させることができます。 ただnpm install electron を実行して、あなたのプロジェクトに最新の Electron の入力を取得できます。


TypeScript は、Microsoft が作成したオープンソースのプログラミング言語です。 これは、静的型をサポート追加することで言語を拡張する JavaScript のスーパーセットです。 TypeScript のコミュニティは近年急速に成長しています。そしてTypeScriptは、最近のStack Overflow開発者調査で 最も愛されているプログラミング言語にランクインしました。 TypeScript は「スケールする JavaScript」と説明されています。GitHub、SlackとMicrosoftのチームはこれを使って数百万人が使用する、スケーラブルな Electron アプリを作成しています。

TypeScript は、JavaScript により新しい多くの言語機能を提供しています。クラス、オブジェクトの破棄、非同期/待機などです。しかしその本当の差別化機能は**型アノテーション **です。 プログラムに期待される入出力データ型を宣言すると、コンパイル時にエラーを見つけることができ、バグを減らすことができます。そしてアノテーションはプログラムがどのように動作するかを形式的に説明することになります。

純粋な Javascript でライブラリが書かれている場合、ドキュメントを書くときには、その型はしばしば漠然と定義されます。 関数は、多くの場合、ドキュメントで指定された型よりも多くの型を受け入れることもありますし、関数にドキュメント化されていない、暗黙の型の制約を持つ場合があります。そのためにランタイムエラーが発生する可能性もあります。

TypeScript は 定義ファイル でこの問題を解決します。 TypeScript の定義ファイルには、ライブラリのすべての関数と、それらの関数で期待される入出力の型が記述されています。 ライブラリの作成者が公開ライブラリに TypeScript 定義ファイルをバンドルする場合、そのライブラリを使って開発するユーザーは、そのライブラリのAPIをエディタ内ですぐに調べられるようになります。そして、ライブラリのドキュメントを参照することなく、すぐに開発を開始できます。

AngularやVue.jsやnode-github(そして Electron も!)のように多くの人気の高いプロジェクトは自身の定義ファイルをコンパイルし、それをnpm の公開パッケージにバンドルしています。 独自の定義ファイルをバンドルしていないプロジェクトのために、DefinitelyTyped というコミュニティがメンテナンスする定義ファイルを扱う、サードパーティのエコシステムがあります。

インストール​

バージョン 1.6.10 以降の、Electron のすべてのリリースには独自の TypeScript 定義ファイルが含まれています。 Npm から electron パッケージをインストールすると、 electron.d.ts ファイルがインストールパッケージに自動的にバンドルされます。

Electron をインストールする 最も安全な方法は であり、正確なバージョン番号を使用することです:

npm install electron --save-dev --save-exact

または、 yarn を使っているなら:

yarn add electron --dev --exact

@types/electron や @types/nodeなどのサードパーティの定義を既に使用している場合は、衝突しないように、Electronプロジェクトからそれらの定義ファイルを削除する必要があります。

定義ファイルは、構造化 API ドキュメントから導出します。そのため、Electron の API ドキュメントと常に 一致します。 Electron をインストールするだけで、使用している Electron のバージョンの最新の TypeScript 定義が得られます。

使い方​

Electron の新しい TypeScript アノテーションをインストールして使用する方法の概要は、以下の短いデモスクリーンキャストをご覧ください。

Visual Studio Codeを使用している場合、これはすでにTypeScript をサポートしています。 Atom、Sublime、vimやその他のエディタにはコミュニティがメンテナンスしているプラグインがあります。

エディターを TypeScript にあわせて設定すると、オートコンプリートサジェスト、インラインメソッド参照、引数チェックなど、コンテキストに対応して動作します。

メソッドの自動補完

メソッドのリファレンス

引数のチェック

TypeScript を始める​

もしあなたが、TypeScript に詳しくなくかつ学びたいと考えているならこのMicrosoftの導入ビデオ をご覧ください。なぜTypeScriptが作られたか、TypeScriptの動作、使用方法などが説明されます。

また、TypeScript の公式サイトには ハンドブック と プレイグラウンド があります。

TypeScript は JavaScript のスーパーセットなので、既存の JavaScript コードはすでに有効な TypeScript です。 つまり、既存の JavaScript プロジェクトを徐々に TypeScript に移行し、必要に応じて新しい言語機能を追加していくことができるのです。

謝辞​

このプロジェクトは、Electron のオープンソースメンテナのコミュニティの協力なしには実現できませんでした。 Samuel Attard, Felix Rieseberg, Birunthan Mohanathas, Milan Burda, Brendan Forster, また、その他のバグの修正、文書の改善、技術ガイダンスの作成にたずさわっっていただいた多くのメンバーに感謝します。

サポート​

Electronの新しいTypeScript定義ファイルを使用して問題が発生した場合、 electron-typescript-definitions リポジトリにイシューを提出してください。

ハッピーTypeScripting!

今週のプロジェクト: Jasper

· 読むのにかかる時間 1 分

今週は GitHub 通知を管理する Electron ベースのツール、Jasper の作者にインタビューを伺いました。


こんにちは! あなたは誰ですか?​

私は Ryo Maruyama で日本のソフトウェア開発者です。 Jasper と ESDoc を開発しています。

Jasper とは何ですか?​

Jasper は GitHub 向けの柔軟で強力な Issue リーダーです。 github.com や GitHub Enterprise での Issue やプルリクエストに対応しています。

Jasper アプリスクリーンショット

どうしてこのアプリを制作したのですか?​

仕事や OSS の活動で GitHub を使っている人は、毎日のように大量の通知が届く傾向にあります。 通知を受け取る方法として、GitHub ではメールと ウェブ通知 を提供しています。 これらは数年前から使用していましたが、以下のような問題に直面しました。

  • メンションされた、コメントした、監視している Issue を見落としがちである。
  • 後で確認しようと Issue を頭の片隅に置いても、たまに忘れてしまうことがある。
  • Issue を忘れないために、ブラウザでタブがたくさん開いたままになる。
  • 自分に関係する Issue なのかどうかを全て確認するのは難しい。
  • 自分のチームの活動を全て把握しづらい。

こういった問題の対処に時間と労力を費やしていました。そこで効率的に解決するために GitHub 用の Issue リーダーを作ってみようと思い、Jasper の開発を始めました。

どういった人が Jasper を使用していますか?​

Jasper は、GitHub を利用する企業の開発者、デザイナー、マネージャーに利用されています。 もちろん、OSS 開発者の中にも使っている人がいます。 さらに GitHub の人も使っています!

Jasper はどのような仕組みですか?​

Jasper の設定を終えると、以下の画面が表示されます。 左から順に、"ストリームリスト"、"Issue リスト"、"Issue 本文" が表示されます。

Jasper 起動画面

この "ストリーム" は、Jasper の核となる機能です。 例えば、"eceltron/electron リポジトリの @zeke にアサインされた Issue" を見たい場合は、以下のようなストリームを作成します。

repo:electron/electron assignee:zeke is:issue

Jasper 起動画面 2

ストリームを作成して数秒待てば、条件を満たす Issue が表示されます。

Jasper 起動画面 3

ストリームではなにができますか?​

ストリームにはどのような条件が使えるのかご紹介します。

ユーザとチーム​

ストリームIssues
mentions:cat mentions:dogcat か dog のユーザをメンションした Issue
author:cat author:dogcat か dog が作成した Issue
assignee:cat assignee:dogcat か dog がアサインされた Issue
commenter:cat commenter:dogcat か dog がコメントした Issue
involves:cat involves:dogcat か bob が "関わりのある" Issue
team:animal/white-cat team:animal/black-doganimal/white-cat か animal/black-dog をメンションした Issue

involves というのは mention、author、assignee、commenter のいずれかであるということです。

レポジトリと Organization​

ストリームIssues
repo:cat/jump repo:dog/runcat/jump か dog/run 内での Issue
org:electron user:cat user:dogelectron か cat か dog 内での Issue

org と user は同じです

属性​

ストリームIssues
repo:cat/jump milestone:v1.0.0 milestone:v1.0.1cat/jump 内で v1.0.0 か v1.0.1 に割り当てられた Issue
repo:cat/jump label:bug label:blockercat/jump 内で bug と blocker を割り当てた Issue
electron OR atomshellelectron か atomshell を含む Issue

レビュー状況​

ストリームIssues
is:pr review:requiredcat/jump 内のレビューが必要な Issue
is:pr review-requested:catcat のレビューが必要な Issue。
まだレビューされていないものになります。
is:pr reviewed-by:catcat がレビューした Issue

これらを見てお気づきかもしれませんが、ストリームには GitHub の検索クエリが使えます。 ストリームや検索クエリの使い方については、以下の URL を参照してください。

Jasper には、未読 Issue 管理、未読コメント管理、お気に入り、更新の通知、Issue のフィルタリング、キーボードショートカットなどの機能もあります。

Jasper は有料製品ですか? おいくらですか?​

Jasper は $12 です。 また、30 日間の 無料体験版 もあります。

Electron で Jasper を構築することにしたのはなぜですか?​

Electron のこういったところが気に入っています。

  • JavaScript/CSS/HTML でアプリを開発できる。
  • Windows、Mac、Linux プラットフォーム向けに構築できる。
  • Electron は活発に開発されており大きなコミュニティがある。

これらの特長により、迅速にシンプルなデスクトップアプリケーションが開発できます。 素晴らしいことです! あなたもプロダクトのアイデアがあれば、是非 Electron の利用を検討してみてください。

Jasper 開発の際に直面した課題はありますか?​

"ストリーム" の概念を考え出すところで苦労しました。 最初は GitHub の Notifications API を使おうと考えました。 しかし、特定のユースケースに対応していないと気づきました。 その後 Notification API に加えて、Issues API と Pull Requests API の利用も検討しました。 それでも、望んでいたものにはなりませんでした。 そこで、いろいろな方法を考えていくうちに、GitHub のSearch API をポーリングするのが最も柔軟だと気づきました。 ここまでに約 1 ヶ月の実験期間を要しましたが、その後 2 日でストリームの概念を取り入れた Jasper のプロトタイプを実装しました。

注: ポーリングは最大で 10 秒に 1 回までとなっています。 GitHub API の制限からすれば余裕を持たせてあります。

今後の予定は何ですか?​

今後は以下のような機能を開発予定です。

  • フィルタ付きストリーム: ストリーム内の Issue をフィルタリングするような、フィルタを付けたストリームです。 SQL のビューのようなものです。
  • 複数アカウント: github.com と GHE の両方を利用できるようにします。
  • パフォーマンス改善: 今のところ WebView での Issue 読み込みは通常のブラウザよりも遅くなっています。

更新情報は @jasperappio の Twitter を確認してください。

今週のプロジェクト: WebTorrent

· 読むのにかかる時間 1 分

今週は @feross と @dcposch が WebTorrent についてお話しします。WebTorrent は、ユーザーをつなぎ合わせて分配された分散型ブラウザ間ネットワークを形成する、ウェブベースのトレントクライアントです。


WebTorrent とは?​

WebTorrent は、ブラウザーで動く初のトレントクライアントです。 全て JavaScript で書かれており、P2P 転送に WebRTC を使用できます。 ブラウザのプラグイン、拡張機能、インストールは不要です。

公開のウェブ標準を使用して、WebTorrent はウェブサイトのユーザーを結び付け、効率的なファイル転送のために分配された分散型ブラウザ間ネットワークを形成します。

WebTorrent の実際のデモは webtorrent.io で見ることができます。

webtorrent ホームページ

これが凄いと言われるのはなぜですか?​

YouTube のようだけれども、訪問者がサイトコンテンツのホストを助けるビデオサイトを想像してください。 WebTorrent で強化されたウェブサイトは、利用者が多いほどより高速で強靭になります。

ブラウザ間通信は仲介者を排除し、人々が各々の条件で通信できます。 クライアント/サーバーは不要です。ピアのネットワークがあれば、みな平等です。 WebTorrent は、ウェブを再分散化する道程の初めの一歩です。

Electron はどこに登場するのですか?​

約 1 年前、デスクトップアプリ版 WebTorrent である WebTorrent デスクトップ を作成することにしました。

WebTorrent デスクトッププレイヤーウインドウ

私たちは、以下の 3 つの理由の下に WebTorrent デスクトップを作りました。

  1. 簡潔、軽量、広告なしのオープンソーストレントアプリが欲しい
  2. 優良なストリーミングサポート付きトレントアプリが欲しい
  3. BitTorrent と WebTorrent ネットワークを繋ぐ "ハイブリッドクライアント" が欲しい

トレントは既にウェブブラウザでダウンロードできるのに、なぜデスクトップアプリなのですか?​

初めに、WebTorrent 設計の背景を少しだけお話しましょう。

webtorrent デスクトップロゴ

黎明期の頃、BitTorrent は TCP を転送プロトコルとして使用していました。 その後、TCP よりも優れた性能と更なるメリットを持った uTP が登場しました。 すべての上流トレントクライアントは最終的に uTP を採用し、現在はどちらのプロトコルでも BitTorrent を使用できます。 WebRTC プロトコルは次の必然的な段階です。 すべてのデスクトップ BitTorrent クライアントと数百万のウェブブラウザで構成される 1 つの巨大な P2P ネットワーク — これはウェブブラウザとの相互運用性を保証します。

"ウェブピア" (ウェブブラウザで実行されるトレントピア) は、数百万の新しいピアを追加し、BitTorrent を多数の新しいユースケースに広めることで、BitTorrent ネットワークを強化します。 WebTorrent は、既存の BitTorrent クライアントが WebTorrent サポートを簡単に追加できるように、できるだけ BitTorrent 仕様に準拠しています。

Vuze のような一部のトレントアプリはウェブピアを既にサポートしていますが、他のアプリのサポート追加を待ちたくはありませんでした。 **元来、WebTorrent デスクトップは WebTorrent プロトコルの採用を促進する手段でした。**誰もが使いたくなるような素晴らしいトレントアプリを作成することで、ウェブピア (ウェブサイト上のユーザなど) とトレントを共有できるネットワーク内のピア数を増やすのです。

あまり知られていないような、興味深いトレントの用法はありますか?​

WebTorrent の一番すごい用法というと、ピアアシスト配信でしょう。 Wikipedia や インターネットアーカイブ などの非営利プロジェクトは、訪問者にリソースを提供してもらうことで帯域幅とホスティングコストを削減できます。 人気コンテンツは、ブラウザ間で迅速かつ安価に提供できます。 たまにしかアクセスされないコンテンツは、オリジンサーバーから HTTP 経由で確実に提供できます。

インターネットアーカイブはトレントファイルを実際に既に更新しているため、WebTorrent でうまく動作します。 なので、サイトにインターネットアーカイブのコンテンツを埋め込みたい場合でも、トレントでアーカイブのホスティングコストを削減し、アーカイブ側は実際にウェブをアーカイブすることに資金を注げます。

CDN から P2P を介したアプリ配信といった、面白いビジネスユースケースもあります。

WebTorrent を使うお気に入りのプロジェクトはありますか?​

gaia アプリスクリーンショット

WebTorrent で作られた一番すごいものといえば、間違いなく、Gaia 3D Star Map でしょう。 これは、ぬるぬる動く天の川の 3D インタラクティブシミュレーションです。 データはトレントから直接ブラウザに読み込まれます。 銀河系を飛び回り、私たち人間が宇宙の広大さに比べてどれだけ小さいかを実感すると同時に畏敬の念を抱きます。

この作成方法は、著者の Charlie Hoey が WebGL と WebTorrent で天体図を作成した方法を説明しているブログ記事 Torrenting The Galaxy で読むことができます。

brave ロゴ

また、私たちは Brave の大ファンです。 Brave は、広告とトラッカーを自動的にブロックして、ウェブをより高速で安全にするブラウザです。 最近、Brave はトレントサポートを追加しました。そのため、従来のトレントを外部アプリなしで閲覧 できます。 この機能は WebTorrent で動作しています。

そのため、ほとんどのブラウザーが PDF ファイルを描画できるように、Brave はマグネットリンクとトレントファイルを描画できます。 これらは、ブラウザがネイティブでサポートするただの別種のコンテンツです。

なんと、Brave の共同創設者の 1 人は、WebTorrent の作成に使われた言語 JavaScript の作成者 Brendan Eich です。その Brave が WebTorrent 統合を選んだなんてとてもカッコよくないですか?

Electron で WebTorrent デスクトップを構築することにしたのはなぜですか?​

WebTorrent デスクトップメインウインドウ

Electron アプリはすべてのアプリに Chrome コンテンツモジュール全体を含むため、"肥大化" していると言われています。 これは、場合によっては部分的に当てはまります (Electron アプリインストーラーは通常 ~40MB ですが、OS 固有のアプリインストーラーでは通常 ~20MB)。

しかし、WebTorrent デスクトップの場合、Electron のほぼすべての機能を使用しますし、通常の操作では何十もの Chrome 機能を使用します。 プラットフォームごとにこれらの機能をゼロから実装していれば、アプリを構築するのに数ヶ月から数年かかるか、単一のプラットフォームでしかリリースできなかったでしょう。

アイデアを実現するため、Electron の Dock 統合 (ダウンロード進捗を表示)、メニューバー統合 (バックグラウンド実行)、プロトコルハンドラーの登録 (マグネットリンクを開く)、powerSaveBlocker (映像再生中のスリープ防止)、自動更新 といった機能を使用しました。 Chrome の機能については、<video> タグ (多種に渡る動画形式の再生)、<track> (字幕対応用)、ドラッグアンドドロップ対応、WebRTC (ネイティブアプリでの使用は難しい) など、色々と使用しています。

言うまでもなく、トレントエンジンは多くの Node API が存在することを前提とした JavaScript で記述されています。特に、require('net') と require('dgram') によって TCP と UDP ソケットをサポートしています。

まとめると、Electron は私たちが必要としていたもので、堅牢で洗練されたアプリを記録的な速さで配信するために必要で正確な機能群を備えていました。

Electron の好きなところは何ですか?​

WebTorrent ライブラリは、オープンソースサイドプロジェクトとして 2 年間開発中です。 **WebTorrent デスクトップは 4 週間で作成しました。**アプリを非常に迅速に構築して配信できたのは Electron であることが主な理由です。

jQuery を使用する世代のフロントエンドプログラマーを Node.js がサーバープログラミングに導いたのと同じで、Electron はウェブや Node.js の開発に精通している人なら誰でもネイティブアプリ開発に手を出せるようにします。 Electron は非常に強力です。

ウェブサイトとデスクトップクライアントはコードを共有していますか?​

はい、webtorrent npm パッケージ は、Node.js、ブラウザ、Electron で動作します。 全く同じコードがすべての環境で実行できる — これが JavaScript の美です。 これが今日の万国共通の実行環境です。 Java Applets は "一度書けば、どこでも動く" アプリを約束しましたが、その理想は多くの理由で実際には実現しませんでした。 Electron は、他のどのプラットフォームよりも、本当にその理想に接近しています。

WebTorrent デスクトップ構築の際に直面した課題はありますか?​

アプリの初期版では、UI パフォーマンスの向上に苦労しました。 メインアプリウィンドウを描画するレンダラープロセスと同じ所にトレントエンジンを配置していました。このため、予想どおり、トレントエンジンからの激しい CPU 演算 (ピアから受信したトレントピースの検証など) が発生した場合は常に低速になっていました。

これを修正するため、トレントエンジンを IPC を介して通信する 2 つ目の非表示のレンダラープロセスに移動しました。 こうすれば、そのプロセスが短時間に多くの CPU を使用する場合でも、UI スレッドは影響を受けません。 滑らかなスクロールとアニメーションには非常に満足です。

注釈: WebRTC (レンダラーでのみ使用可能) にアクセスする必要があるため、"メイン" プロセスではなく、レンダラープロセスにトレントエンジンを配置する必要がありました。

Electron はどういった領域で改善されるべきでしょうか?​

本番用のアプリを構築して配信する方法や、特にコード署名や自動更新などのトリッキーなテーマについて、より良いドキュメントを望んでいます。 私たちは、ソースコードを研究して Twitter で尋ねてベストプラクティスについて学ぶ必要がありました!

WebTorrent デスクトップは開発終了ですか? それとも、今後何かありますか?​

現行の WebTorrent デスクトップは素晴らしいと思いますが、改善の余地は常にあります。 現在、細かい点の修正、パフォーマンス、字幕サポート、映像コーデックサポートの改善に取り組んでいます。

プロジェクトの参加に興味がある場合は、私たちの GitHub ページ を見てください!

他の開発者に役立つ Electron 開発のノウハウはありますか?​

WebTorrent デスクトップのコントリビューターの 1 人である Feross は、最近 NodeConf Argentina で "Electron の世界: JavaScript でクロスプラットフォームアプリを構築" という講演を行い、洗練された Electron アプリをリリースするための便利なヒントを紹介しました。 この講演は、あなたが基本的な実用アプリを持っている段階にいて、それを次のレベルの洗練と専門的な領域に昇華させようとしているのであれば非常に役立ちます。

動画はこちら:

スライドはこちら:

もう一人の WebTorrent のコントリビューターである DC は、アプリを洗練されたネイティブにするための できることのチェックリスト を書きました。 コード例が付いており、macOS Dock 統合、ドラッグアンドドロップ、デスクトップ通知、アプリの読み込みを速くするなどをカバーしています。

Touch Bar サポート

· 読むのにかかる時間 1 分

Electron の 1.6.3 ベータリリースは macOS の Touch Bar に対する初期サポートを含みます。


新しい Touch Bar API により、ボタン、ラベル、ポップオーバー、カラーピッカー、スペーサを追加することができます。 これらの要素は動的に更新され、対話が起こった際にはイベントが発生します。

この API の最初のリリースに過ぎないため、いくつかの Electron のリリースの間に進化していくでしょう。 詳しい更新内容についてはリリースノートを参照してください。なんらかの問題が生じているか、機能が欠けている場合は、 Issue を開いてください。

このバージョンは npm install electron@beta でインストールできます。詳細は Electron ドキュメントの TouchBar 及び BrowserWindow を参照してください。

@MarshallOfSound による Electron への貢献に大いなる感謝を表します。 🎉

Touch Bar の例​

Touch Bar の Gif

以下は Touch Bar を用いたシンプルなスロットゲームの例です。 Touch Bar の作成方法、アイテムにスタイルを適用する方法、ウィンドウと関連付ける方法、ボタンクリックイベントを扱う方法、ラベルを動的に更新する方法を示しています。

const { app, BrowserWindow, TouchBar } = require('electron');

const { TouchBarButton, TouchBarLabel, TouchBarSpacer } = TouchBar;

let spinning = false;

// リールのラベル
const reel1 = new TouchBarLabel();
const reel2 = new TouchBarLabel();
const reel3 = new TouchBarLabel();

// スピン結果のラベル
const result = new TouchBarLabel();

// スピンのボタン
const spin = new TouchBarButton({
label: '🎰 Spin',
backgroundColor: '#7851A9',
click: () => {
// 既にスピン中であれば無視する
if (spinning) {
return;
}

spinning = true;
result.label = '';

let timeout = 10;
const spinLength = 4 * 1000; // 4 秒
const startTime = Date.now();

const spinReels = () => {
updateReels();

if (Date.now() - startTime >= spinLength) {
finishSpin();
} else {
// スピンするごとに少しづつ遅くする
timeout *= 1.1;
setTimeout(spinReels, timeout);
}
};

spinReels();
},
});

const getRandomValue = () => {
const values = ['🍒', '💎', '7️⃣', '🍊', '🔔', '⭐', '🍇', '🍀'];
return values[Math.floor(Math.random() * values.length)];
};

const updateReels = () => {
reel1.label = getRandomValue();
reel2.label = getRandomValue();
reel3.label = getRandomValue();
};

const finishSpin = () => {
const uniqueValues = new Set([reel1.label, reel2.label, reel3.label]).size;
if (uniqueValues === 1) {
// 3 つの値すべてが同じ
result.label = '💰 Jackpot!';
result.textColor = '#FDFF00';
} else if (uniqueValues === 2) {
// 2 つの値が同じ
result.label = '😍 Winner!';
result.textColor = '#FDFF00';
} else {
// どの値も異なる
result.label = '🙁 Spin Again';
result.textColor = null;
}
spinning = false;
};

const touchBar = new TouchBar([
spin,
new TouchBarSpacer({ size: 'large' }),
reel1,
new TouchBarSpacer({ size: 'small' }),
reel2,
new TouchBarSpacer({ size: 'small' }),
reel3,
new TouchBarSpacer({ size: 'large' }),
result,
]);

let window;

app.once('ready', () => {
window = new BrowserWindow({
frame: false,
titleBarStyle: 'hidden-inset',
width: 200,
height: 200,
backgroundColor: '#000',
});
window.loadURL('about:blank');
window.setTouchBar(touchBar);
});

今週のプロジェクト: Voltra

· 読むのにかかる時間 1 分

今週は、Aprile Elcich さんと Paolo Fragomeni さんにお会いして、Electron を搭載した音楽プレイヤー Voltra についてお話を伺いました。


Voltra とは何ですか?​

Voltra は、自分の音楽を所有したい人のための音楽プレイヤーです。 すでに持っているものから新しい音楽を見つけたり、購入したりできるストアでもあります。 広告なしで、デスクトップとモバイル向けのクロスプラットフォームです。 情報収集もしません。

voltra-artistview

Voltra はどんな人が対象ですか?​

音楽を聴くすべての人です。

Voltra を作ったきっかけは何ですか?​

ラジオは昔からリスナーの大きなシェアを獲得しています。 今や電波からインターネットへと移行しています。 オンデマンドで音楽をレンタルできるようにもなりました - ラジオの復活です! そのために多くの新しい製品やサービスが登場しています。しかし、ストリーミングラジオはまだ、音楽とその視聴手段を掌握されています。

私たちは、自分が持っている音楽というものに全面的にこだわったプロダクトを望みました。 アーティストやレーベルから直接、新しい音楽を発見したり購入したりすることを容易にするものです。

無料版はありますか?​

デスクトッププレイヤーは完全に無料です。 あなたの音楽を販売するのも無料です! 当サイトに広告はありません。

このアプリは無料なので、後にオープンソース化するかもしれません。 今のところそれを管理する余裕はありません。 機能や採り入れる方向性についても、とても具体的なアイデアを持っています。 活発なベータコミュニティもあり、そのフィードバックを大切にしています。

どうやって収益化するのですか?​

プレミアム機能があります!

Voltra Audio Archive は、音楽に特化したクラウドバックアップサービスです。 データブロックを圧縮、共有はしません。 あなたの音楽コレクションは、物理的なバックアップです。

アーティストやレーベル向けの プロ会員 は、アナリティクスやプロアーティストのウェブページなど、より関連する視聴者に届けるためのツールを提供しています。

Voltra は何が特色なのですか?​

デザインとユーザビリティは、私たちにとって非常に重要です。 リスナーの皆様に、煩わせない視聴体験を提供したいのです! 興味深い音楽プレーヤーやストアはすでにいくつか出ています。 しかし、その多くは作者が思っているよりも高度で使いづらいのです。 一人でも多くの人が Voltra を利用できるようにしたいです。

また、アーティストやレーベルからの引き抜きはしていません。 これが差別化しているポイントです。 アーティストが自分の音楽を市場に出すための障壁を下げるには、本当に重要なことなのです。

どのようなデザイン & 技術的な決定をしましたか?​

Voltra をデザインするにあたって、ネイティブアプリやウェブの UI の慣習を考慮し、何を削るかということもたくさん考えました。 私たちには、ここ数ヶ月の間で批判的なフィードバックをくれた活発なプライベートベータグループがいます。

人々は、アルバムアートや写真を本当に大切にしているということがわかりました。 多くのプレイヤーはファイルのリストでしかありません。 アルバムアートは物理アルバムを所有するにあたって格好いい所の一つですが、Voltra デスクトップアプリではこの点を強調したいと思いました。

voltra-albumview

他人のファイルに手を出さないようにも気をつけました。 ファイルを見るだけなので、それ自体は好きな場所に置くことができます。名前を変更したり、移動したりすることはありません。 プロセスが実行されていなくても新規ファイルを追跡できるように、見ているディレクトリの状態を追跡する埋め込みデータベースがあります。

Voltra 構築の際に直面した課題はありますか?​

パフォーマンスを重視して、そこに時間をかけました。 最初はフレームワークから始めましたが、バニラ JavaScript に移行しました。 経験上、フレームワークが提供する一般的な抽象化は、導入することによるパフォーマンスの対価や儀式的な記述を上回ります。

現在はとても巨大なコレクションにも対応しています。 大きなコレクションであれば数万もの画像になるでしょう! Node.js のファイルシステムモジュールをレンダラープロセスから直接利用できるようにしたことで、DOM イベントに基づいた大量の画像の超高速での遅延ロード/アンロードが非常に簡単になりました。

一般的に、setImmediate と requestIdleCallback は、UI の応答性を維持しながら多くの処理を実行するにあたってとてつもなく重要な道具です。 具体的には、CPU に依存するタスクを別のプロセスに分散させることで、ユーザーインターフェースの応答性を保つことができます。 たとえば、実際のオーディオコンテキストを別のプロセスに移動し、ビジーな UI による潜在的な中断を IPC を介した通信で回避しました。

Electron で Voltra を構築することにしたのはなぜですか?​

ブラウザのサンドボックスはとても制限されていますが、私たちはウェブプレイヤーも開発しています。 しかし、私たちはウェブプレイヤーも開発しています。 そのため、2 つの実装間でほぼ 100% のコードを共有できるのは大きな利点です。

実際には、Swift でネイティブアプリを構築するところから始めました。 一番の問題点は、多くの再発明をしていることでした。 ウェブには世界最大のオープンソースエコシステムがあります。 そこで、すぐに Electron に切り替えました。

最も重要なのは、Electron で一度開発すれば、すべての主要なプラットフォームで Just Work™ するということです。 保証はありませんが、各プラットフォームのためのネイティブコーディングのコストは、Electron を導入するコストを確実に上回っています。

Electron の好きなところは何ですか?​

問題解決!: Node.js のネットワークスタックと Chromium のプレゼンテーション層が一緒になっていることこそが、問題解決の秘訣です。

適性: ウェブスタックだけなので、文字通りチーム全員が製品の構築に関われます。

コミュニティ: 高度に組織化されたコミュニティがあり、コミュニケーション手段が発達しています。 このようなサポートを受けながら開発を進められることはとても素晴らしいことです。

Electron はどういったところを改善できるでしょうか?​

Electron に 1 つのパッケージャを推奨してもらいたいです。 Node にとってのパッケージマネージャーと同様に、Electron にとってもパッケージマネージャーは重要です。 ユーザーランドには複数のパッケージャーがあり、それぞれが興味深い機能を備えていますが、それぞれにもバグがあります。 コミュニティのコンセンサスが得られれば、貢献者が費やすエネルギーの方向性が定められるでしょう。

今後の予定は何ですか?​

私たちは現在モバイルアプリを開発中で、アーティストやレーベルと協力して彼らの音楽を Voltra ショップに追加しています。 そこのあなた! アーティストやレーベルの方であれば、ぜひご登録ください! 目標の 1000 万曲を達成しましたら、ショップをオープンする予定です。

Electron の舞台裏: Chromium をライブラリとしてビルドする

· 読むのにかかる時間 1 分

Electron は、Google のオープンソースプロジェクト Chromium をベースにしています。このプロジェクトは、他のプロジェクトで使用することを想定していません。 この記事では、Electron のライブラリとしての Chromium がどのように構築されているのか、またビルドシステムがどのように進化してきたのかを紹介します。


CEF の利用​

Chromium Embedded Framework (CEF) は、Chromium をライブラリ化し、Chromium のコードベースに基づいて安定した API を提供するプロジェクトです。 黎明期の Atom エディタや NW.js では CEF を使用していました。

安定した API を維持するために、CEF は Chromium の詳細をすべて隠蔽し、独自のインターフェースで Chromium の API をラップします。 そのため、Node.js をウェブページに統合するような、内部の Chromium API にアクセスする必要があったとき、CEF の利点が障害になりました。

そのため、結局 Electron も NW.js も Chromium の API を直接使うように切り替えました。

Chromium を部品としてビルドする​

Chromium は公式には外部プロジェクトをサポートしていませんが、コードベースはモジュール化されており、Chromium をベースに小さなブラウザを簡単に構築できます。 ブラウザインターフェイスを提供するコアモジュールは、コンテンツモジュールと呼ばれています。

コンテンツモジュールでプロジェクトを開発する際は、Chromium をプロジェクトの部品としてビルドするのが一番簡単です。 このためには、まず Chromium のソースコードをチェックアウトしてから、プロジェクトを Chromium の DEPS ファイルに追加します。

NW.js や Electron の非常に初期のバージョンでは、このようなビルド方法を使用しています。

この欠点は、Chromium がとても大きいコードベースであるため、相応に強力な マシンでビルドする必要があるということです。 一般的なラップトップであれば、5 時間以上かかります。 そのため、貢献できる開発者の数に多大な影響を与え、開発も遅くなりかねません。

単一の共有ライブラリとして Chromium をビルドする​

コンテンツモジュールのユーザからすれば、ほとんどの場合で Electron が Chromium のコードを修正する必要はないので、Electron のビルドを改善する明白な方法は Chromium を共有ライブラリとしてビルドして Electron 内でそれをリンクすることです。 これにより、開発者は Electron に貢献する際に Chromium すべてをビルドする必要がなくなります。

libchromiumcontent プロジェクトは @aroben によってこのために作成されました。 これは、Chromium のコンテンツモジュールを共有ライブラリとしてビルドし、Chromium のヘッダとビルド済みバイナリをダウンロードできるようにします。 libchromiumcontent の初期バージョンのコードは こちらのリンクに あります。

libchromiumcontent の一部として brightray プロジェクトも生まれました。これはコンテンツモジュールの周りに薄い層を提供します。

libchromiumcontent と brightray を併用することで、開発者は Chromium のビルドの詳細に踏み込まずに素早くブラウザをビルドできます。 そして、プロジェクトをビルドするための高速なネットワークと強力なマシンが必要なくなります。

Electron 以外に、Breach ブラウザ のように、この方法でビルドされた Chromium をベースにしたプロジェクトもあります。

エクスポートしたシンボルのフィルタリング​

Windows では、単一の共有ライブラリでエクスポートできるシンボル数に制限があります。 Chromium のコードベースが大きくなるにつれ、libchromiumcontent がエクスポートするシンボル数はすぐに制限を超えてしまいました。

これは、DLL ファイル生成時に不要なシンボルをフィルタリングすることで解決しました。 リンカに .def ファイルを供給し、スクリプトで 名前空間の配下のシンボルをエクスポートすべきかどうか判断 することで動作させました。

このアプローチを取ることで、Chromium がエクスポートされたシンボルを新しく追加し続けても、libchromiumcontent はより多くシンボルを削除することで共有ライブラリファイルを生成できるようになりました。

コンポーネントビルド​

libchromiumcontent の次の段階の話をする前に、まずは Chromium におけるコンポーネントビルドの概念を紹介しておきます。

巨大プロジェクトであるため、Chromium ではビルド時のリンクの段階で非常に長い時間がかかってしまいます。 大抵、開発者がちょっとした変更を加えると、最終的な出力が得られるまで 10 分ほどかかります。 これを解決するため、Chromium ではコンポーネントビルドを導入しました。Chromium 内の各モジュールを分離された共有ライブラリとしてビルドすることで、最終的なリンク作業に費やす時間が気にならないようにしました。

生バイナリの頒布​

Chromium が成長を続ける中で、Chromium のエクスポートされたシンボルがあまりにも多くなり、コンテンツモジュールや Webkit のシンボルですらも制限を超えるようになりました。 シンボルを削減するだけでは、使用可能な共有ライブラリを生成できなくなったのです。

最終的に、単一の共有ライブラリを生成する代わりに Chromium の生バイナリを頒布 しなければなりませんでした。

先ほど紹介したように、Chromium には 2 つのビルドモードがあります。 生のバイナリを頒布した結果、libchromiumcontent ではバイナリに対して 2 種類のディストリビューションを頒布しなければならなくなりました。 1 つは static_library ビルドと呼ばれるもので、Chromium の通常ビルドで生成された各モジュールすべての静的ライブラリをインクルードします。 もう 1 つは shared_library で、コンポーネントビルドで生成された各モジュールの共有ライブラリすべてをインクルードします。

Electron では、デバッグ版を libchromiumcontent の shared_library 版とリンクしています。これは、ダウンロードが少なく、最終的な実行ファイルをリンクする際に時間がかからないためです。 また、リリース版の Electron は libchromiumcontent の static_library 版とリンクしています。コンパイラはデバッグに重要なシンボルを完全に生成でき、リンカはどのオブジェクトファイルが必要かそうでないかを知っているため、より良い最適化を行えます。

そのため、通常の開発において開発者はデバッグ版をビルドするだけでよく、良好なネットワークや強力なマシンは不要です。 リリース版では、ビルドにより良いハードウェアを必要としますが、より最適化されたバイナリを生成できます。

gn の更新​

世界的に見ても最大級のプロジェクトであるため、通常のビルドシステムはほとんど Chromium のビルドには適していません。Chromium チームは独自のビルドツールを開発しています。

初期バージョンの Chromium はビルドシステムとして gyp を使用していましたが、動作が遅く、複雑なプロジェクトでは設定ファイルがわかりづらくなるという問題がありました。 何年もの開発の後に、Chromium はビルドシステムを gn に切り替えました。こちらの方がはるかに高速で明確なアーキテクチャとなっています。

gn の改良点の一つは、オブジェクトファイルのグループを表す source_set を導入したことです。 gyp では、各モジュールは static_library か shared_library のいずれかで表現されます。Chromium の通常のビルドでは、各モジュールの静的ライブラリを生成し、最終的な実行ファイルへリンクしていました。 gn を使うと、各モジュールはオブジェクトファイルの集まりだけを生成し、最終的な実行ファイルには全オブジェクトファイルをリンクするだけなので、中間の静的ライブラリファイルは生成されなくなります。

しかし、この改善は libchromiumcontent に大きなお世話でした。なぜなら、中間の静的ライブラリファイルは libchromiumcontent が実際に必要としていたのです。

これを解決する最初の試みは、静的ライブラリファイルを生成するように gn にパッチを当てる ことでした、これで問題は解決しましたが、まともな解決策には程遠いものでした。

2 つ目の試みは、@alespergl による、オブジェクトファイルのリストからカスタムの静的ライブラリを生成する ものでした。 これは、最初にダミービルドを実行して生成されたオブジェクトファイルのリストを収集してから、gn にそのリストを与えて静的ライブラリを実際にビルドするという仕掛けでした。 これは Chromium のソースコードを最小限変更しただけで、Electron のビルドアーキテクチャはそのままです。

概要​

このように、Electron を Chromium の一部として構築するのに比べて、ライブラリとして Chromium を構築するにはより多くの労力と継続的なメンテナンスが必要になります。 しかし、後者は Electron のビルドに強力なハードウェアが不要となるため、より多くの開発者が Electron をビルドして貢献できるようになります。 この努力はそれだけの価値があります。