メインコンテンツへ飛ぶ

Webview の脆弱性の修正

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

Node.js インテグレーションを無効している Electron アプリケーションで、再度有効にできる脆弱性が発見されました。 この脆弱性には CVE 識別子 CVE-2018-1000136 が割り当てられています。


影響するアプリケーション

以下の すべて に当てはまる場合、そのアプリケーションは影響します。

  1. Electron 1.7, 1.8, か 2.0.0-beta で実行している
  2. 任意のリモートコードの実行を許可している
  3. Node.js インテグレーションを無効にしている
  4. webPreferences で webviewTag: false を明示的に宣言していない
  5. nativeWindowOption オプションを有効にしていない
  6. new-window イベントをインターセプトしておらず、提供された options タグを使用せずに event.newGuest を手動でオーバーライドしている

これはごく少数の Electron アプリケーションになりますが、予防としてすべてのアプリケーションはアップグレードすることを推奨します。

緩和策

この脆弱性は本日の 1.7.131.8.42.0.0-beta.5 のリリースで修正されました。

アプリケーションの Electron のバージョンをアップグレードできない開発者は、以下のコードで脆弱性を軽減できます。

app.on('web-contents-created', (event, win) => {
win.on(
'new-window',
(event, newURL, frameName, disposition, options, additionalFeatures) => {
if (!options.webPreferences) options.webPreferences = {};
options.webPreferences.nodeIntegration = false;
options.webPreferences.nodeIntegrationInWorker = false;
options.webPreferences.webviewTag = false;
delete options.webPreferences.preload;
},
);
});

// and *IF* you don't use WebViews at all,
// you might also want
app.on('web-contents-created', (event, win) => {
win.on('will-attach-webview', (event, webPreferences, params) => {
event.preventDefault();
});
});

詳細情報

この脆弱性は Trustwave SpiderLabs の Brendan Scarvell によって発見され、Electron プロジェクトに責任ある形で報告されました。

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

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

メールリスト に参加すると、リリースとセキュリティアップデートに関する更新情報を受信できます。

Web サイトのしゃっくり

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

先週、 electronjs.org で数分間のダウンタイムが発生しました。 この短い停止による影響でご迷惑をおかけして申し訳ありません。 本日、少しの調査の後、根本の原因を診断し、 修正 を行いました。


今後このようなダウンタイムを防ぐために、 Heroku threshold alerts をアプリで有効化しました。 失敗したリクエストや遅いレスポンスが一定のしきい値を超えて蓄積されるたびに、私たちのチームに通知され、素早く問題に対応できます。

すべての言語のオフラインドキュメント

あなたが Electron アプリを飛行機や地下のコーヒーショップで開発するとき、オフラインで参照するためにドキュメントのコピーが欲しい場合があるでしょう。 幸いにも、Markdown ファイルによる Electron ドキュメントは 20 以上の言語で利用できます。

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

GUI でのオフラインドキュメント

devdocs.io/electron は、 Electron だけでなく、 JavaScript 、 TypeScript 、 Node.js 、 React 、 Angular などのドキュメントを保存している便利な Web サイトです。 もちろん、参考となる Electron アプリもあります。 Electron サイトの devdocs-app をご参照ください。

devdocs-app

アプリをマウスやトラックパッドを使わずにインストールしたい方は、Electron Forge にある以下の install コマンドをお試しください。

npx electron-forge install egoist/devdocs-app

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

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

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


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

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

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

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

緩和策

この脆弱性に対する修正を含む新しいバージョンの Electron を公開しました。 1.8.2-beta.51.7.121.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 アプリでも、独自のページをこのサイト上へ簡単に作成できます。 例えば、Etcher1ClipboardGraphQL Playground があります。ここではサイトの日本語版を示しています。

GraphQL プレイグラウンド

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

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

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

サイトで紹介したい 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.81.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」と説明されています。GitHubSlackMicrosoftのチームはこれを使って数百万人が使用する、スケーラブルな Electron アプリを作成しています。

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

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

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

AngularVue.jsnode-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 をサポートしています。 AtomSublimevimその他のエディタにはコミュニティがメンテナンスしているプラグインがあります。

エディターを 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 で日本のソフトウェア開発者です。 JasperESDoc を開発しています。

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:dogcatdog のユーザをメンションした Issue
author:cat author:dogcatdog が作成した Issue
assignee:cat assignee:dogcatdog がアサインされた Issue
commenter:cat commenter:dogcatdog がコメントした Issue
involves:cat involves:dogcatbob が "関わりのある" Issue
team:animal/white-cat team:animal/black-doganimal/white-catanimal/black-dog をメンションした Issue

involves というのは mentionauthorassigneecommenter のいずれかであるということです。

レポジトリと Organization

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

orguser は同じです

属性

ストリームIssues
repo:cat/jump milestone:v1.0.0 milestone:v1.0.1cat/jump 内で v1.0.0v1.0.1 に割り当てられた Issue
repo:cat/jump label:bug label:blockercat/jump 内で bug blocker を割り当てた Issue
electron OR atomshellelectronatomshell を含む 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 APIPull 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);
});