月曜日の祝日、陰陽師の週替りイベントの好機を逃すという悲しい思いをしまして。
いつも開いてるPC版の隣で通知とかするアプリがあればなーと思ったとき、Electronで作れるんでは?とその存在を思い出したのでした。
いつの時代も悔しさは己の闘志を奮起してくれるものです。
ElectronはもともとGitHubがAtom作るために生み出したやつ。
6年前からあって名前はよく聞いてたけど、Web技術でデスクトップアプリ化したいと思うものがなかったら使う機会ないよなーっていう存在だった。
逆にいうとWeb技術しか無くてもデスクトップアプリが作れるすごいフレームワークである。
試してみる
どんなものか様子見するなら、
APIのデモリポジトリで動作デモとサンプルソースが見れるやつと、
クイックスタートのリポジトリで
Hello Worldが起動するやつが動かせる。
どっちも中身はhtml/js/cssの組み合わせたもの。
Electronの実態はChromiumとNode.jsである。
Photoshopのエクステンションを思い出す…。
Electron Forge使ってみる
イチからアプリを作る手順はここに書いてある。
これはnpm initして必要なファイルを手動で追加していくやつだが、
諸々お手軽にしてくれるツールElectron Forgeを使うこともできる。
これだとコマンド3つ叩くだけでHello World状態になる。
yarn create electron-app my-app cd my-app yarn start
webpackテンプレートもある。
yarn create electron-app my-new-app --template=webpack
TypeScript使えないと死んでしまう人はこっち使うのがよさそう。
Electron Forgeだとアプリ化するのもコマンド1つ叩くだけである。
yarn run publish
ReactとかVueとかを使う
Webpackが動くならReactもVueも使えるわけで、Electron Forgeで生成したやつでVueが動くようにしてみた。
CSSはPostCSSのみにしておく。
いるものインストールして、
yarn add vue yarn add postcss postcss-loader file-loader --dev yarn add autoprefixer postcss-preset-env yarn add vue-loader vue-style-loader vue-template-compiler --dev
webpack.rules.jsに追加
{ test: /\.vue$/, loader: 'vue-loader', }
webpack.renderer.config.jsに追加
const rules = require('./webpack.rules'); const VueLoaderPlugin = require('vue-loader/lib/plugin') rules.push({ test: /\.css$/, use: [ 'vue-style-loader', { loader: 'css-loader', options: { importLoaders: 1 } }, 'postcss-loader' ], }); rules.push({ test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }); module.exports = { // Put your normal webpack config below here module: { rules, }, plugins: [ // make sure to include the plugin! new VueLoaderPlugin() ] };
renderer.jsにVueのコード入れて、
import Vue from "vue"; import App from "./App.vue"; Vue.config.productionTip = false; new Vue({ render: h => h(App) }).$mount("#app");
index.htmlのルート要素にID振って
<body> <div id="app"></div> </body>
App.vue作成する。
<template> <div class="content"> <h1>💖 Brahma!</h1> <p>Hello World!</p> </div> </template> <script> export default { name: "App", } </script> <style lang="css"> :root { --textColor: #333; --secondaryColor: lab(32.5 38.5 -47.6 / 90%); } body { background: url('./images/bg.png'); } .content { color: var(--textColor); } h1 { color: var(--secondaryColor); } </style>
で、yarn start
して立ち上がったアプリがエラー無く動いてたらおk。
※プロジェクト名を神々の名前にしてる名残があるけど気にしないでほしい…
electron-vueの利用
Vue CLIみたいなやつで始めたいならelectron-vueを使う手もありそうだった。
これも一応試してみたが、長くメンテされてないせいでそのままだとNode.js v12.0では動かない。
Webpack ReferenceError: process is not defined #871のコメントより、
以下3箇所修正する。
src/main/index.js
mainWindow = new BrowserWindow({ height: 563, useContentSize: true, width: 1000, webPreferences: { nodeIntegration: true // ←追加 } })
src/index.ejs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <% if (htmlWebpackPlugin.options.nodeModules) { %> <!-- Add `node_modules/` to global paths so `require` works properly in development --> <script> require('module').globalPaths.push('<%= htmlWebpackPlugin.options.nodeModules.replace(/\\/g, '\\\\') %>') </script> <% } %> </head> <body> <div id="app"> </div> <!-- Set `__static` path to static files in production --> <% if (!htmlWebpackPlugin.options.isBrowser && !htmlWebpackPlugin.options.isDevelopment) { %> <script> window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\') </script> <% } %> <!-- webpack builds are automatically injected --> </body> </html>
.electron-vue/webpack.renderer.js
new HtmlWebpackPlugin({ filename: 'index.html', template: path.resolve(__dirname, '../src/index.ejs'), minify: { collapseWhitespace: true, removeAttributeQuotes: true, removeComments: true }, isBrowser: false, isDevelopment: process.env.NODE_ENV !== 'production', nodeModules: process.env.NODE_ENV !== 'production' ? path.resolve(__dirname, '../node_modules') : false }),
で、起動したアプリをよく見るとElectronのバージョンが2系と古すぎるので、入れ替えて6系にする。
うまく動けばこんな感じ。
※spectronとか古いバージョンで入ったやつ全部入れ替える必要がある。
electron-nuxtの利用
electron-nuxtはelectron-vueのメンテされなさに業を煮やした(のかもしれない)有志が作ったNuxt.js版である。
前述のVue版はあらゆるところでエラーを吐くので、その解決に時間取られるくらいならこちらを使う方が精神衛生的にも良さそう。
npm install -g vue-cli vue init michalzaq12/electron-nuxt electron-nuxt cd electron-nuxt yarn yarn run dev
rendererディレクトリの中がNuxt.jsになっている。
よく見るとこれもElectron5系でちょっと古いしテストが両方とも動かなかった。
CSSをSassにするとunitテストでエラーを吐いたりもする。
絶賛開発中みたいだから商業用途にはリスクがありそう。
Nuxt.js + Electron
create-nuxt-appして生成したNuxt.jsのプロジェクトディレクトリにElectronを導入する、つまり全部手動でやってる人もいた。
Nuxt.js+Electronを試してみるv2
人が作ってるものは更新止まったりするし、古い状態で止まってるのを修正する手間考えると最初から自前でやっつけた方が早いことはままありますな。
electron-react-boilerplateの利用
Reactの方はelectron-react-boilerplateというのがあった。
ちゃんとメンテもされているようす。
git clone --depth 1 --single-branch --branch master https://github.com/electron-react-boilerplate/electron-react-boilerplate.git electron-react cd electron-react yarn
yarn dev
でDevelopmentモード起動
いろいろ試してたら時間切れになった😇
モチベが残れば記事も続きます…