Electron (旧称: Atom-Shell)は, Atomエディタを開発するために生まれた
クロスプラットフォームデスクトップアプリケーションエンジンです。
簡単に言うと、HTML+CSS+Javascript(Node.js)+Chromiumを用いてデスクトップアプリケーションを作成できるという便利なエンジンです。
・クロスプラットフォーム型の実行フレームワーク 👉 Mac、Windows、Linux上で動く
・Webの技術(HTML5やJavaScript)で作ったものをデスクトップアプリケーション化できる
・オープンソース、商用利用可能
・開発元はGitHub社 (もともとはAtomエディタのために作られた)
・Slack ・Atom ・Kobito ・Docker GUI ・Visual Studio Code (Microsoft)
今回の自分の開発環境は次のようになっています.OSはWindowsを使いましたがNode.js(npm)が使えれば何でもとくには関係ないと思います.
- Windows 10 Pro
- Node.js v11.13.0
- npm 6.9.0
今回の開発はVue CLIを使って行いました.適当にググってみるとVue CLIの2と3の情報があり使い方も違っているので注意です.今回はVue CLI 3を使っています. npmを使ってグローバルにVue CLI 3をインストールします.
$ npm install -g @vue/cli
$ vue --version
3.4.0下のコマンドを実行すると、ブラウザが立ち上がる。 以下にできる内容をまとめた。
vue ui
プロジェクトの作成をしたら「npm run serve」によって起動します。
cd hello-project
npm run serve
「npm run」は「packeage.jsonのscripts」に追加されているコマンドが実行されるので、 「serve」に書かれた「vue-cli-service serve」が実行されます。
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},パッケージのインストールをするとpackage.jsonなどに書き込まれる。
プロジェクトを作成したら右上のメニューにインストールボタンがある。
vue add @vue/eslint
次にパッケージによって選択肢が出るので、選択するとインストールされる。
オプションをつけると選択画面なしでインストールできる。
vue add @vue/eslint --config airbnb
npm runで実行できるコマンドは「vue ui」のからGUIで操作ができる。
- 作成したプロジェクトを選択する。
- GUIの左端のタスクを押すと一覧が表示される。
・設定するであろう内容 ・webpackで実装していたプロジェクトをVueCLI3に移行する手順。
webpack.config.jsなどに書いていた設定はこちらに書く。 プロジェクトに「vue.config.js」ファイルを追加する。 他の設定値は公式リファレンスから参照
module.exports = {
pages: {
index: {
// 最初に実行されるファイル名
entry: 'src/index.js',
// テンプレートファイル
template: 'public/index.html',
// 出力されるファイル名
filename: 'index.html',
// タイトルの設定
// <title><%= htmlWebpackPlugin.options.title %></title>
title: 'Index Page',
// チャンクの指定
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
// サブページをせっているするとエントリーページのファイル以外はこちらが参照される。
// テンプレートファイルは、 `public/subpage.html`
// public/subpage.htmlがなかったら `public/index.html`が呼び出される。
// 出力されるファイル名は `subpage.html`となる。
subpage: 'src/subpage/main.js'
},
// キャッシュバスティングのためにファイル名にハッシュをつけている。
// デフォルトでtrueなので、falseの場合のみ指定
filenameHashing: true,
// ポートなどの設定
devServer: {
port: 5000,
contentBase: path.resolve(__dirname, 'public'),
host: 'localhost',
},
css: {
// 毎回読み込んでおくscssファイルの指定
loaderOptions: {
sass: {
data: `@import "@/val.scss";`
}
}
},
configureWebpack: {
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': path.resolve(__dirname, 'src/'),
}
},
plugins: [
// plugin
]
}
}packege.jsonの例。 パッケージを最新にしておかないとエラーする。
{
"name": "なまえ",
"version": "0.1.0",
"scripts": {
"lint": "vue-cli-service lint",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --mode develop",
"build_prod": "vue-cli-service build"
},
"dependencies": {
"@babel/runtime": "^7.2.0",
"vue": "^2.5.16",
"vuex": "^3.0.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.2.0",
"@vue/cli-plugin-eslint": "^3.2.0",
"@vue/cli-service": "^3.2.0",
"@vue/eslint-config-standard": "^4.0.0",
"@vue/test-utils": "^1.0.0-beta.24",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"css-loader": "^0.26.2",
"node-sass": "^4.9.0",
"sass-loader": "^7.0.1",
"vue-template-compiler": "^2.5.16",
}
}
必要なら下の設定も記述。
// eslintの設定。「.eslintrcファイル」に書いても良い。
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended",
"@vue/standard"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
// postcssの設定。「.postcssrcファイル」に書いても良い。
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
// browserslistの設定
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
vue.config.jsの設定を変更したらビルドし直す。
npm run build
エラーがある場合は、以下のように出る。 「*」が付いている箇所がエラーなので、そこをチェックして直す。
These dependencies were not found:
// 今回は、「vue.config.js」に書かれている、
// 「src/index.js」と「subpage/main.js」が見つからないというエラーだった。
* /Users/tomo/github/vue_cli3/hello-world/src/index.js in multi ./src/index.js
* /Users/tomo/github/vue_cli3/hello-world/src/subpage/main.js in multi ./src/subpage/main.js
せっかくWebアプリを作るならカッコいいデザインで作りたいです.VuetifyはVue.jsに対応したマテリアルデザインのCSSフレームワークです.UIコンポーネントがいろいろと揃っているのと,ドキュメントもしっかりとしているのでお手軽にカッコいい画面が作れます.
Vuetifyは既存のアプリに自前でnpm install,importして使っていくことも簡単にできますが,今回はVue CLIから追加して使いました.このときも対話形式となっていますが,今回はDefaultを選択しました.
$ vue add vuetifyインストールの他,Vuetifyのimportや必要なCSSの読み込みも行うようにファイルが更新されています.また先ほど確認したWelcomeページもVuetify仕様に更新されています. これだけでVuetifyを使っていく準備はOKです.
はじめにプロジェクトを作成するときにRouterやVuexを選択していると,すぐに使っていける状態になっています.どちらもちょっとしたWebアプリを作るような段階からでも便利なものになっていると思うので,ぜひVue.jsの入門段階からでも触ってみるといいと思います.
Vue RouterはVue.js公式ルータです.複数のページの切り替えを簡単に実現することができます.
すでにrouter.jsがプロジェクト内に存在しているので,その中を見れば使い方はなんとなくわかるかと思います.pathで指定したURLとcomponentで指定したVueコンポーネントが結びつきます.nameは任意ですが名前を付けておくとその名前を利用して遷移先を定義することができます.
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: () => import('./views/About.vue')
}
]
})その他の詳しい使い方はこちらで確認してください. https://router.vuejs.org/ja/
VuexはVue.jsアプリケーションの状態を保持するコンテナです.複数のVueコンポーネント間で共通のデータを扱うことができます.
通常は親子関係のあるVueコンポーネント間ではpropとemitを使って情報を受け渡すことができますが,直接的な親子関係にないVueコンポーネント間では直接的には情報のやり取りが行えず構造が複雑になってしまいます.Vuexを使うとこれをシンプルに解決することができます.
こちらもすでにstore.jsがプロジェクト内に存在しています.簡単な例としてstateとmutationsに実装を追加しています.stateに共有したいデータ,mutationsにそのデータの更新処理を定義します.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
}
})stateの情報を取得するときにはstore.stateから,mutationsの処理を呼びさすときにはstore.commitを使って呼び出すことができます.
<template>
<p>{{$store.state.count}}</p>
</template>
<script>
export default {
mounted: function () {
this.$store.commit('increment')
}
}
</script>
その他の詳しい使い方はこちらで確認してください. https://vuex.vuejs.org/ja/
最後におまけ要素ですが,Vue.jsで作ったWebアプリをElectronアプリにして動かしてみます. ElectronはWindows/macOS/Linuxで実行できるデスクトップアプリをHTML+CSS+JavaScriptといったWeb技術で開発できるフレームワークです.有名どころだとAtomやVSCodeがElectronでできています. Vue CLI 3を使うと簡単にElectronで動かすことができたので紹介します.
まずは次のコマンドでelectron-builderをインストールします.バージョンの選択がありましたが今回は4.0.0を選択しました.(自分の環境だと3はエラーが出てインストールできませんでした.)
$ vue add electron-builderpackage.jsonを見るとnpm-scriptsにElectron関連のコマンドが追加になっています.electron:serveやelectron:buildから起動や実行ファイルのビルドを行うことができます.
$ npm run electron:serve # Electronで起動
$ npm run electron:build # 実行ファイルの生成まず、package.json内に以下のプロパティを設定している必要がある。
- name
- description
- version
- author
また、electron-builder自身の設定もpackage.json内に記述する。
dependenciesやscriptsと並列にbuildというプロパティを設定する。
"build": {
"appId": "com.electron.worc",
"mac": {
"target": "dmg"
},
"directories": {
"output": "docs"
}
}アプリの識別子。
MacではCFBundleIdentifier、WindowsではApplication User Model IDとして用いられる。
デフォルトはcom.electron.${name}という形式。
Apple Developer Programに登録していないと警告が出るが、そのままパッケージングは進められる。
起動パラメータで選択、ただし他のOSで作成は環境面で難しいのでDockerを利用するか、GIT ACTIONSを利用するのがよい
electron-builder --mac --x64 --publish never
electron-builder --win --x64 --publish never
electron-builder --linux --x64 --publish never
ここまで作ったReadUsをよりデスクトップアプリケーションらしくするために, メニューを追加してみます.
ユーザがREADMEの探索元となるディレクトリを指定できるようにしてみます. 既にfileUtilには, 探索起点ディレクトリであるbaseDirを引数として指定できるようにしてあるため, あとはUI部分を作るだけです.
Electronには, アプリケーションメニューとコンテキストメニューの2種類があります. アプリケーションメニューはメニューバーに表示されるメニュー, コンテキストメニューは画面を右クリックした際に表示されるメニューです.
今回はアプリケーションメニューを追加します. アプリケーションメニューはBrowserProcess側で追加を行うため, background.jsを下記のようにします.
'use strict';
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const Menu = electron.Menu;
const {crashReporter, dialog} = require('electron');
crashReporter.start({
productName: 'YourName',
companyName: 'YourCompany',
submitURL: 'https://your-domain.com/url-to-submit',
autoSubmit: true
});
app.on('window-all-closed', function() {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('ready', function() {
// メニューをアプリケーションに追加
Menu.setApplicationMenu(menu);
openWindow(process.cwd());
});
function openWindow (baseDir) {
let win = new BrowserWindow({width: 800, height: 600});
win.loadURL('file://' + __dirname + '/index.html?baseDir=' + encodeURIComponent(baseDir));
win.on('closed', function () {
win = null;
});
}
// メニュー情報の作成
const template = [
{
label: 'ReadUs',
submenu: [
{label: 'Quit',
accelerator: 'Command+Q',
click: function () {
app.quit();
}}
]
}, {
label: 'File',
submenu: [
{
label: 'Open',
accelerator: 'Command+O',
click: function () {
// 「ファイルを開く」ダイアログの呼び出し
dialog.showOpenDialog({properties: ['openDirectory']}, function (baseDir) {
if (baseDir && baseDir[0]) {
openWindow(baseDir[0]);
}
})
}
}
]
}, {
label: 'View',
submenu: [
{label: 'Reload',
accelerator: 'Command+R',
click: function () {
BrowserWindow.getFocusedWindow().reload();
}},
{
label: 'Toggle DevTools',
accelerator: 'Alt+Command+I',
click: function () {
BrowserWindow.getFocusedWindow().toggleDevTools();
}
}
]
}
];
const menu = Menu.buildFromTemplate(template);MenuモジュールのbuildFromTemplate関数にtemplateを与え, アプリケーションの起動時(app.on('ready', ...))にて, setApplicationMenuを実行することでアプリケーションメニューを追加しています.
メニューの元となっているtemplateについて, acceleratorでショートカットキーの指定, clickにクリックされた際に動作するハンドラ関数を設定可能です.
ユーザにディレクトリを開かせるOpenメニューを含め, 追加したメニューは以下の4つです.
- ReadUs
- Quit: アプリケーションを終了させる.
- File
- Open: 探索の起点となるディレクトリを選択させ, 新規にRendererProcessを立ち上げる.
- View
- Reload: RendererProcessを再描画させる.
- Toggle Devtools: Chromiumの開発者ツールの表示を切り替える.
Openメニューでは, Electronのdialogモジュールを使っています. dialogモジュールのshowOpenDialog関数は「ファイルを開く」ダイアログを表示することができます.
今回はディレクトリを開かせたいので, openDirectoryプロパティをセットしました.
dialogモジュールにはshowOpenDialog以外にも数種類のダイアログを表示するための機能が備わっています(詳細)
ViewメニューのReload, Toggle Devtoolsの2つは, エンドユーザにとっては無くても構わないのですが, 開発時に便利な機能です. 両方ともBrowserWindow自体に備わっている機能を利用しています.
さて, Openメニューで選択したディレクトリ情報は, RendererProcess側にクエリストリングとして渡しています.
先述のindex.jsにてvar baseDir = process.cwd() としていた箇所を下記で置き換えれば, ディレクトリパスの受け渡し処理が完成します.
var matched = location.search.match(/baseDir=([^&]*)/);
var baseDir = matched && decodeURIComponent(matched[1]);
VueCLI3導入とできることまとめ https://qiita.com/bokotomo/items/8dc619cc271f4c69658a
Vue.jsでちょっとSPAなWebアプリ作ってみたときのメモ https://qiita.com/y-tsutsu/items/e8544ec5fe1b9a69ea35
electron-builderを使ってdmgファイルを生成する http://shibe97.hatenablog.com/entry/2017/02/17/090000
Electronでアプリケーションを作ってみよう https://qiita.com/Quramy/items/a4be32769366cfe55778
Electronの環境構築(for Windows) https://qiita.com/TigRig/items/64d55b5fc5483b01c3b5













