前回の記事にてポケモン一覧・詳細を表示するWebアプリを作成しました。
今回・次回はそのソースを少し改造して、macOSアプリ(とついでにWindowsアプリ)を作って行こうと思います。
方針としては、前回のソースにelectronを適用していきます。
electronは簡単に言うとWebページ(html+js+css)をパッケージングしてmacやWindowsのアプリとして起動可能にしてくれるプラグインです。アプリ(exe、appファイル)内部には「node+chronium」が一緒にパッケージングされるためアプリサイズは大きくなってしまいますが、1ソースでクライアントアプリが作れるのは魅力的です。
世間的にはatomやVSCodeもelectronで作られているそうです。
準備
前回の続きです。追加は特にありません。
Vue UIを使ってプロジェクトの設定を行う
せっかくなので前回同様Vue UIからelectronのインストールを行います。
UI左部メニューの「依存」>「依存をインストール」からelectronを検索し、開発依存としてインストールします。大げさなように見えますが、要はnpm i --save-dev electron
と同じです。
プログラムの修正
2点だけ、プログラムを修正します。
まずはルート直下に、以下のファイル(index.js)を追加します。
const electron = require("electron"); const app = electron.app; const BrowserWindow = electron.BrowserWindow; const url = process.env.NODE_ENV === "DEV" ? "http://localhost:8080/" : `file://${__dirname}/dist/index.html`; app.on("ready", () => { let window = new BrowserWindow({ width: 800, height: 600 }); window.loadURL(url); window.webContents.openDevTools(); }); app.on("window-all-closed", () => { app.quit(); });
electronの起動用ルートファイルになります。
electronオブジェクトに描画するHTML(URL)を指定し描画します。
また、作成するapp(exe)独自の設定もここで行います。例えば以下のようなものを設定することができますが、詳細は割愛します。
- 作成app(exe)ファイルのアイコン
- 画面上部コンテキストメニューの作成
- アプリケーション起動時処理
- アプリケーション終了時処理
- 等々
次に、package.jsonにアプリ起動用のscriptを追記します。赤字部分が追記部分です。
{ "name": "pokemon", "version": "0.1.0", "private": true, "scripts": { "serve": "NODE_ENV=DEV vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint", + "el-dev": "NODE_ENV=DEV vue-cli-service serve & sleep 5 && NODE_ENV=DEV electron index.js" }, "dependencies": { "axios": "^0.18.0", "vue": "^2.5.17", "vue-class-component": "^6.0.0", "vue-property-decorator": "^7.0.0", "vue-router": "^3.0.1", "vuex": "^3.0.1", "vuex-class": "^0.3.1" }, "devDependencies": { "@vue/cli-plugin-babel": "^3.2.0", "@vue/cli-plugin-eslint": "^3.2.1", "@vue/cli-plugin-typescript": "^3.2.0", "@vue/cli-service": "^3.2.0", "@vue/eslint-config-prettier": "^4.0.0", "@vue/eslint-config-typescript": "^3.2.0", "babel-eslint": "^10.0.1", "electron": "^3.0.12", "eslint": "^5.8.0", "eslint-plugin-vue": "^5.0.0-0", "typescript": "^3.0.0", "vue-template-compiler": "^2.5.17" }, "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ "plugin:vue/essential", "@vue/prettier", "@vue/typescript" ], "rules": {}, "parserOptions": { "parser": "typescript-eslint-parser" } }, "postcss": { "plugins": { "autoprefixer": {} } }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] }
vue-cli-serviceでサーバーを起動し、前回のWebアプリを裏で動かしています。
その後electron index.js
でクライアントアプリを起動するようにしています。
このように開発中は「Webサーバーに描画されるHTMLをクライアントアプリに描画する」という作りとなっているため、上記index.jsでは
const url = process.env.NODE_ENV === "DEV" ? "http://localhost:8080/" : `file://${__dirname}/dist/index.html`;
というように環境変数によってurlを切り替えるようにしています。また、package.jsonのスクリプトでもNODE_ENV=DEV
を渡すようにしています。
プログラムの実行
package.jsonのscriptに追記しているため、vue UIの「プロジェクトタスク」にも追加されています。
「タスクの開始」を押すと実行され、以下のような画面が表示されます。
Webアプリと同じような画面ですが、一つのクライアントアプリとして専用のコンテキストメニューが表示されています。(特にいじっていないので、electronとしてデフォルトのコンテキストメニューが上記画面では表示されています)
開発モードの表示・非表示もコンテキストメニューから切り替えることが出来、開発者コンソールでデバッグをすることが可能です。(Chromeの開発者コンソールと同じです)
このようにelectronを使えば、Webアプリをそのまま同じソースでクライアントアプリに構築していくことが可能です。次回はアプリファイルへのパッケージングを行います。
参考URL:
- electron(https://electronjs.org/docs)