tl;dr
electron-webpackでTypescript+Reactのelectronプロジェクト雛形を作りました。
多分すぐ陳腐化するので2020/08/26ブランチを切っています。
https://github.com/thalathalaylah/electron-webpack-ts-react-template/tree/2020/08/26
これはなに
electron-webpackってやつを使うとelectronのプロジェクトが簡単に作れるらしいぜ。
ということでTypescript+Reactのものを作ろうとしたら所々ハマったのでまとめます。
もしくは「create-react-appとtypescriptでelectronをやる」のリファイン。
環境
おおまかなものです。
細かくはリポジトリのpackage.jsonを見てください。
| 対象 | version |
|---|---|
| Mac | HighSierra 10.13.6 |
| yarn | 1.15.2 |
| electron | 10.0.0 |
| electron-webpack | 2.8.2 |
やったこと
commitのリンクを見出しにしていくので、細かい差分はそちらで確認してください。
electron-webpack導入
echo node_modules > .gitignore
yarn add electron-webpack electron webpack --dev
yarn add source-map-support
.gitignoreにnode_moduleを追加
あとは https://webpack.electron.build/development の通りにelectron-webpack, electron, webpack, source-map-supportを導入する。
source-map-supportは--devをつけずにaddしないと、パッケージ化する際に失敗する。
electron-webpack-quick-startのページを表示するアプリが起動する
echo dist >> .gitignore
.gitignoreにdistを追加。
{
"scripts": {
"dev": "electron-webpack dev"
},
......
}
package.jsonにdevコマンドを追加。
electron-webpack-quick-startの2020/08/04時点最新のsrc/main/index.js と src/renderer/index.js を同様のディレクトリ構造でコピー。
これらの作業もhttps://webpack.electron.build/development の通り。
この時点でyarn devコマンドを実行すると、electronアプリが起動する。
Typescript導入
yarn add typescript electron-webpack-ts --dev
typescriptとelectron-webpack-tsを導入。
{
"extends": "./node_modules/electron-webpack/tsconfig-base.json"
}
tsconfig.jsonを作成し、electron-webpackからextendsする設定を記述。
ここまでは https://webpack.electron.build/add-ons#typescript の通り。
yarn add @types/node@12 --dev
electron10系はnode12上で動くため、型情報は@types/node@12を利用する。
nodeの13系以上ではエラーが発生した。
その後、src/main/index.jsをsrc/main/index.tsにリネーム。
10行目のlet mainWindowで型が無いことをによりエラーが発生するため、 let mainWindow: BrowserWindow | null としておく。
この時点でyarn devコマンドを実行すると、再度electronアプリが起動できる状態になっている。
前コミットとの差はMainProcessのコードがTypescriptで動いていること。
React導入
yarn add @babel/preset-react --dev
{
......
"compilerOptions": { "jsx": "react" }
}
https://webpack.electron.build/add-ons#react-jsx の通り、jsxのコンパイルに必要なものを入れる。
yarn add react react-dom @types/react @types/react-dom --dev
React関連の依存を追加する。
その後、src/renderer/index.jsをsrc/renderer/index.tsxにリネームし、Reactの表示用コードを書く。
ここで、https://webpack.electron.build/development#use-of-html-webpack-plugin にある通り、ReactDOM.renderで最初に指定するcontainerはid=appのelementを取得する必要がある。
https://github.com/thalathalaylah/electron-webpack-ts-react-template/commit/39ea8ed47ee4203d8c142b0101826fab0a580e88#diff-6991cac75f36bcce6c7cdbad5540d934R5
ReactDevTools導入
yarn add electron-devtools-installer @types/electron-devtools-installer --dev
You may also try electron-devtools-installer
と、 https://github.com/electron/electron/blob/v10.0.0/docs/tutorial/devtools-extension.md にある通り、electron-devtools-installerを導入。
https://www.npmjs.com/package/electron-devtools-installer の通りにsrc/main/index.tsでReactDevToolsを読み込むようにする。
アプリをビルドできる
yarn add electron-builder --dev
electron-builderを導入。
{
"scripts" {
"dev": "electron-webpack dev",
+ "build": "electron-webpack && electron-builder --mac --x64"
}
+ "name": "electron-webpack-ts-react-template",
+ "version": "0.0.1",
......
}
- buildスクリプトを追加。今回はmac上なので
--macだが、OSによって適宜変える。 - nameはアプリの名前。
- versionは適宜つける。
-import installExtension, {
- REACT_DEVELOPER_TOOLS,
-} from 'electron-devtools-installer';
const isDevelopment = process.env.NODE_ENV !== 'production';
......
if (isDevelopment) {
- installExtension(REACT_DEVELOPER_TOOLS)
- .then((name) => console.log(`Added Extension: ${name}`))
- .catch((err) => console.log('An error occurred: ', err));
+ import('electron-devtools-installer').then((module) => {
+ module
+ .default(module.REACT_DEVELOPER_TOOLS)
+ .then((name) => console.log(`Added Extension: ${name}`))
+ .catch((err) => console.log('An error occurred: ', err));
+ });
window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`);
} else {
......
electron-devtools-installerはアプリ化した際に読み込めないようなので、開発時にのみ動的にimportするように変更する。
package.jsonでelectron-devtools-installerをdevDependencyからdependencyに移動することでも対処できる。
しかし、開発用の機能なのでdependencyに移動するのも良くないと考え、動的importを選択した。
ボタン追加
クリック可能なボタンを作成し、クリック時にconsoleに文字列を表示する。
nodeの力を使ってみる
Button.tsxでchildProcessをimportし、lsコマンドを実行、dev toolのconsoleに表示する。
これでローカルのリソースにアクセスできていることが確認できる。
そういうわけで
electron-webpackを使ってプロジェクト雛形を作ってみたが、つまづきが多かったのでまとめた。
create-react-appから頑張るよりは良い感じなのではないかと思う。