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から頑張るよりは良い感じなのではないかと思う。