Kobito for Windows をリリース + 技術的な補足, package.json の公開
Kobito for Windows開発の @mizchi です。
開発開始から約半年、ソロ作業の期間も長かったのですが、ようやくリリースできました。
Kobito for Windows – ソフトウェア開発者のためのMarkdownによる情報記録・共有ソフト
というわけで、今日はKobito for Windowsの開発コンセプトとElectronやReactを採用した理由について書いていこうと思います。Rails界隈ではGemfileを公開する文化があるようですが、今回はnode.js / npmのそれであるpackage.jsonを公開します。
Kobito on Electronの開発コンセプト
- Web技術でKobitoを実装してWin/Macでソースを一本化
- 既存のKobitoの問題点を解決
- 単純なマークアップエディタとしての使い勝手を向上
開発開始時点で、Qiita / Qiita:Team でのWindowsユーザの増加に伴い、より多くのユーザーにリーチするためにWindows版の開発が急務になっていました。
また、既存のMac版に対しても改善候補がいくつか上がっており、それらも合わせてスクラッチで開発することにしました。
Electronの採用理由
- 既存のKobitoがObjectiveCで書かれており、他の環境へ移植困難
- 強みであるWeb技術が活かせる
- 既存のQiitaとコンポーネント資産とノウハウを共有したい
これらの理由が合わさってElectronを採用にするに至りました。言うまでもないことですが、SPA(シングルページアプリケーション)を設計できる技術があることが前提になっています。
主な採用言語/ライブラリ/環境
- Electron
- React
- TypeScript
- CoffeeScript
Reactの運用
なぜReactか、という解説はここ最近、散々説明された記事が出ていることなので特に解説しませんが、主目的は高速に複雑なUIが組める、ということにあります。
今回はjsxは一切使わずreact-jadeを使いました。fluxフレームワークは画面遷移を表現できるものが少なく、結局 mizchi/arda を自作しました。
react-jadeは便利な半面、それなりに不満もあって、置き換えるためにreinyというテンプレートエンジンを自作し始めたのですが、まだまだバギーでreact-jadeを置き換えるには至っていません。
Markdownコンパイラ
Markdownをプレビューするアプリケーション、というコアバリューを考えるに、高速にプレビューができ、分量が多くなっても速度が低下しない、というのは一番大事にしたい部分でした。
Reactの実装例の一つにMarkdownをプレビューするのものがあるのですが、KobitoのようなMarkdownをリアルタイムプレビューするという用途に使うと頻繁にReactがクラッシュすることがわかりました。とくに分量が多いドキュメントで顕著で、また速度にも問題がありました。
React公式の例通りに実装すると、dangerouslySetInnerHtmlという見ての通り危険なAPIでHTMLを直接挿入することになるのですが、これを避けるために、markdownを直接react-elementに変換するようなコンパイラを作成しました。
ここで試せます
辛かった点
- 自動アップデータの自作
- Electronのビルドが日によって頻繁に失敗する
- CodeMirrorのIME周り
- Markdownの細かい挙動が実装によってまちまち
気が向いたらQiitaで細かいものTIPSでも書いていこうと思います。
package.json
privateリポジトリへの参照や、無関係な情報は差し引いてあります。
{
"name": "kobito",
"version": "1.0.1",
"description": "Kobito for Windows",
"scripts": {
"test": "$(npm bin)/mocha --require espower-coffee/guess test/spec-helper.coffee test/components/*.coffee test/contexts/*.coffee test/domains/*.coffee test/utils/*.coffee",
"coffeelint": "$(npm bin)/coffeelint src/**/*.coffee src/**/**/*.coffee src/*.coffee",
"tslint": "$(npm bin)/gulp tslint"
},
"dependencies": {
"arda": "0.13.1",
"bluebird": "2.9.24",
"codemirror": "mizchi/CodeMirror#7cbc16c214b2cd0d97556407d87ffdab9f75898c",
"emosa": "^0.1.0",
"font-awesome": "^4.2.0",
"highlight.js": "^8.4.0",
"jquery": "^2.1.1",
"lodash": "^3.0.0",
"marked": "^0.3.3",
"md2react": "^0.6.3",
"moment": "2.9.0",
"mousetrap": "^1.5.2",
"qiita-js": "0.3.1",
"qs": "^2.3.3",
"react": "^0.13.0",
"stone-skin": "0.1.2",
"weakmap": "0.0.6",
"whatwg-fetch": "^0.7.0"
},
"devDependencies": {
"browserify": "^9.0.8",
"brfs": "^1.4.0",
"cheerio": "^0.19.0",
"coffee-script": "^1.9.2",
"coffeelint": "^1.9.2",
"dtsm": "^0.9.1",
"envify": "^3.2.0",
"espower-coffee": "^0.10.0",
"factory-dog": "0.0.2",
"gulp": "^3.8.10",
"gulp-coffee": "^2.2.0",
"gulp-plumber": "^1.0.0",
"gulp-react-jade": "mizchi/gulp-react-jade#9cfde076190054c29ec4922fc3fe0a178f17b897",
"gulp-rename": "^1.2.0",
"gulp-sass": "2.0.0",
"gulp-shell": "^0.4.1",
"gulp-sourcemaps": "^1.3.0",
"gulp-tslint": "^2.0.0",
"jsdom": "5.0.0",
"licensify": "^1.1.0",
"localStorage": "^1.0.3",
"mocha": "^2.1.0",
"power-assert": "^0.10.0",
"sinon": "^1.12.2",
"tslint": "^2.1.1",
"typescript": "1.4.1",
"xmldom": "^0.1.19"
}
}
あえてimmutable-js や rx.js は採用していません。既に十分に実験的なプロジェクトであることや、採用によってモジュールのポータビリティが低下すること(Qiitaに持ち込めない)、実際に試してみた感触として今回のアプリにはこれらがもたらすメリットが導入の複雑さを上回りそうになかったのが理由です。
将来的に採用する可能性はあります。
解説資料
勉強会で発表した際の資料です
また VirtualDOM Advent Calendar 2014 – Qiita と 一人React.js Advent Calendar 2014 – Qiita の各種資料には大変お世話になりました。この場を借りて感謝の意を伝えたいと思います。
Windowsユーザーの方はぜひこちらからご利用ください。Kobito for Windows – ソフトウェア開発者のためのMarkdownによる情報記録・共有ソフト
最後に
Incrementsではelectronを使って〜したいエンジニアを募集しています
https://www.wantedly.com/projects/18729