Macの最近のブログ記事

Windows で開発している Electron のプロジェクトを、Dropbox でフォルダを共有して、俺のモバイル環境である macOS でも開発できるようにできないか・・・と思って、macOS で起動した VSCode でそのフォルダを共有したんだけど、ターミナルで npm start をすると何のエラーも出ないが、すでに作り終えている画面も出てこないという状態に。

ども俺は誤解していたのだが、そのフォルダにインストールされた Electron の node_modules フォルダ以下は、Windows 用、macOS 用でそれぞれ別の「バイナリ」ファイルが入ってるのね。なんとなく「JavaScript で書かれたライブラリ集」だと思い込んでた(^^;;;

というわけで、プロジェクトフォルダを Dropbox で共有(同期)したあと、node_modules フォルダだけを「同期しない」設定にして共有から外し、中身を一旦全て消してから、他の macOS 上の Electron プロジェクトの node_modules を上書きコピーしてやる。これで、node_modules 以外のファイル(js、HTML、CSSなどのファイル)だけ同期されるので、Windows と macOS で同じプロジェクトを触れるようになる。

こうして文章で書くとややこしく感じられるが、要は「node_modules は同期しない」だけのことなのでそんなにややこしい話ではない。
例えば macOS 側で「同期する」設定のまま node_modules を更新してしまい Windows でうまく動かなくなっても、node_modules だけ他の Winodows のプロジェクトからコピーしてくればいいだけの話である。(install し直してもいいが、修正した JSON ファイルとかに新しいファイルが上書きされたりするといやなので、他のプロジェクトからコピーしてくるのが一番じゃないかと思う)

ちなみに、上記の作業をしたあとで、PostgreSQLに接続するための pg モジュールなども各 OS 用にインストールし直す必要がある。

それをせず実行すると、

~/Dropbox/timetron % npm start  
npm notice run timetron@1.0.0 start
npm notice run electron .
App threw an error during load
Error: Cannot find module 'pg'
<以下略>

こんな風にエラーでエラーになっちゃう。こういう時はその OS 上で install をしなおせばいい。

~/Dropbox/timetron % npm install pg
npm error code EEXIST
npm error syscall mkdir
npm error path /Users/shinoda/.npm/_cacache/content-v2/sha512/f9/ba
npm error errno -13
npm error EACCES: permission denied, mkdir '/Users/shinoda/.npm/_cacache/content-v2/sha512/f9/ba'
npm error File exists: /Users/shinoda/.npm/_cacache/content-v2/sha512/f9/ba

あり?エラー。どうも、npm install のときに、一度 sudo して実行してしまったため、shinoda ではなく root 権限でキャッシュが書かれてしまったようだ。

~/Dropbox/timetron % sudo chown -R 501:20 "/Users/shinoda/.npm"
Password:<shinoda のパスワード>
~/Dropbox/timetron % npm install pg

これでOK

~/Dropbox/timetron % npm start     
npm notice run timetron@1.0.0 start
npm notice run electron .
Downloading Electron binary...

20261025_mac_electron1.jpg

これで、ばっちり Windows で開発していた画面がちゃんと起動した。動きもOK!!
案件がある度に開発環境をセットアップするため、いつの間にか macOS に PostgreSQL がバージョン 14 と 18 の二つ入っていた。
Homebrew で 14 を入れて、公式サイトの dmg ファイルで 18 を入れたようだ。

Homebrew のリストには 14 が、

~ % brew list | grep postgresql
postgresql@14

/Library/PostgreSQL の下に 18が入っている。

~ % ls -ld /Library/PostgreSQL/18
drwxr-xr-x@ 21 postgres  daemon  672  5月 28 06:49 /Library/PostgreSQL/18

ちなみに、18 は自動起動が設定されているようで、何もしなくてもデーモンが起動している。

~ % ps aux | grep PostgreSQL 
postgres           534   0.0  0.0 435512752   1120   ??  Ss   11 7月26   6:33.81 /Library/PostgreSQL/18/bin/postgres -D /Library/PostgreSQL/18/data
shinoda          78278   0.0  0.0 435300560   1360 s000  S+    4:24午後   0:00.01 grep PostgreSQL

しかし、psql コマンドは 14 の方にパスが通っているようだ。

~ % which psql
/opt/homebrew/bin/psql

というわけで、PostgreSQL 環境をきれいに一本化したいので、当然最新版の 18 の方を生かすことにする。

14 については自動起動の設定はされていないようなので(brew services start postgresql@14 すれば起動する)、単純に 14 のアンインストールと、psql のパスの付け替えをする。

~ % brew uninstall postgresql@14
Uninstalling /opt/homebrew/Cellar/postgresql@14/14.22... (3,337 files, 48.3MB)
==> Autoremoving 6 unneeded formulae:
<略>

途中、

Warning: The following openssl@3 configuration files have not been removed!
Warning: The following ca-certificates configuration files have not been removed!

というような警告が出るが、これは「postgresql@14 はアンインストールしたけど、openssl@3 は他に使ってるソフトがあるかもしれないので念の為残しておくね」というものなので無視。

次に、psql のパスを 18 に向ける。

~ % echo 'export PATH="/Library/PostgreSQL/18/bin:$PATH"' >> ~/.zshrc
~ % source ~/.zshrc
~ % which psql
/Library/PostgreSQL/18/bin/psql
~ % psql -V
psql (PostgreSQL) 18.3

これで OK。

~ % psql -U postgres
Password for user postgres: <パスワード入力:表示されない>
psql (18.3)
Type "help" for help.

postgres=# \db
       List of tablespaces
    Name    |  Owner   | Location 
------------+----------+----------
 pg_default | postgres | 
 pg_global  | postgres | 
(2 rows)

ちゃんと 18.3 の psql が起動している。
開発用のフォルダを作成し、そこをカレントディレクトリとして VSCode を起動する。

~ % cd ~/Desktop
~/Desktop % mkdir electron-test
~/Desktop % cd electron-test
~/Desktop/electron-test % code .
zsh: command not found: code

ありゃ?パスが通ってない?

パスを通すには、VSCode を使って登録するのが一番簡単である。
まず、アプリケーションフォルダの Visual Studio Code.app を実行。それから Shift + Command + P で検索バー(コマンドパレット)を表示。
「shell command」と入力してコマンド候補が表示されるので、
 
 Shell Command: install 'code' and optionally 'copilot' command in PATH
 ※ copilot を使ってない場合は、and optionally 'copilot' は表示してないかも
 
 を選択して実行。これでパスが通る。実際はどこかのファイルに実際のパス(/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code)が登録されたわけではなく、これ、/usr/local/bin の下に code のシンボリックリンク(Windows で言うショートカット、macOS のエイリアスと一緒)が作られている。
 
 ~/Desktop/electron-test % ls -la /usr/local/bin/code
lrwxr-xr-x  1 root  wheel  68 10月 24 20:43 /usr/local/bin/code -> /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code

/usr/local/bin は元々コマンド入力時の検索パスに入っているので、これでどこで 'code' と入力しても、ちゃんと VSCode が起動するようになる。

VSCode が起動したら、早速そこでターミナルを開き(Shift + Command + P で検索バーを開き「Terminal: Create New Terminal」を選択、実行)、そこで、npm init -y を実行。

~/Desktop/electron-test % npm init -y
  },
  "keywords": [],
  "type": "commonjs"
}

フォルダに package.json というファイルが作成される。
次に、このフォルダに Electron をインストールする。

~/Desktop/electron-test % npm install electron --save-dev

added 13 packages, and audited 14 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities

ちゃんと入った。フォルダの下(って言うのは DOS 時代の名残か(笑)。Windows や Mac で最初から「フォルダ」生活の人たちは「下」じゃなく「中」って言うのよね(笑))に node_modules フォルダなどができているはず。
これで開発の準備はできたので、次に main.js というファイルを作成。VSCode のエクスプローラー窓で右ボタンメニューを開き「新しいファイル...」を選択。ファイル名を main.js にする。

【main.js】

const { app, BrowserWindow } = require('electron')

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600
  })

  win.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// ウィンドウがすべて閉じられたときの挙動
// Windows や UNIX系の Window システムならアプリも終了
// Mac(darwin)なら窓を全て閉じてもアプリは生かしておく(Mac的な動き)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

同じように index.html を作成。

【index.html】

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Electronアプリ</title>
</head>
<body>
    <h1 style="text-align: center; margin-top: 50px;">
        ★見事に起動成功!(笑)
    </h1>
</body>
</html>

最後に、package.json を以下のように修正。

【package.json】

{
  "name": "electron-test",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "keywords": [],
  "type": "commonjs",
  "devDependencies": {
    "electron": "^45.0.0"
  }
}

ここまで作ったら実行してみる。
ターミナルのコマンドラインから実行。

~/Desktop/electron-test % npm start
Debugger attached.
npm notice run electron-test@1.0.0 start
npm notice run electron .
Debugger attached.
Downloading Electron binary...
Debugger attached.
Waiting for the debugger to disconnect...
Debugger attached.

最初の1回目はちょっと起動まで時間がかかるが、無事画面が表示された。成功。

 20261024_electron1.jpg

これが一番シンプルな Electron のプログラム。

今更俺が説明するまでもないが(というか、俺が説明してしまうと間違いが混入してしまう恐れがあるが(笑))、Electron というのは Node.js(JavaScript) + Web 開発技術(HTML,CSS など)でデスクトップアプリを開発するためのライブラリ集&フレームワークである。

言葉をもう一度整理しておくと、

  • JavaScript ... 開発言語
  • Node.js ... 本来、ブラウザ(Chrome 等)上でしか実行できない JavaScript をローカルで実行できるようにした実行環境
  • npm .... Node.js 用の部品(ライブラリ等)の管理ツール。簡単に部品のインストールなどが行える(Perl で言えば CPAN みたいなもの)
  • Electron ... Node.js でデスクトップアプリを開発するためのライブラリ集&フレームワーク(開発基盤)

である。
ついでに、

  • VSCode ... テキストエディタと IDE(統合開発環境)を組み合わせたソースコードエディタ(実は Electron で作られている)

も。なんか、以前に比べるとひとつひとつのソフトウェアの役割が明確に分けられてなくて、説明が難しくなってるよね、最近は。

では、早速、npm で Electron をインストールする。

~ % npm install electron --save-dev

added 13 packages in 2s

1 package is looking for funding
  run `npm fund` for details
npm notice
npm notice New major version of npm available! 11.19.1 -> 12.2.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.1
npm notice To update run: npm install -g npm@12.2.1
npm notice

あっという間にインストール終了。
なんか、notice(通知)がたくさん出ている。
ただ、これは Electron のインストールが失敗をしたわけではなく、「npm のバージョンが 11.19.1 だけど、最新バージョンは 12.2.1 よ。 install コマンドで最新版が入るで」と言ってる。

今朝、Node.js を最新版にしたとき 11.19.1 に上がったんだけど、ああ、もしかして安定版が 11系で、開発版(不安定)が 12系なん?

よく知らないけど、最新版にする。

~ % sudo npm install -g npm@12.2.1
Password:XXXXXXXX<実際には表示されない>

removed 8 packages, and changed 77 packages in 3s

15 packages are looking for funding
  run `npm fund` for details
~ % npm -v                         
12.2.1

さあ、これでばっちり。macOS 上で動く Electron アプリを作ってみよう。
macOS 上に Electron の開発環境を作るために、まずは Node.js を最新にしたい。

~ % node -v
v22.11.0
~ % npm -v
10.9.0

・・・さて、以前、どうやってインストールしたかわからない
最新版にアップデートするには、最初にどうやってインストールしたかで方法が変わってくる。

~ % which node
/usr/local/bin/node

こうして、どこに Node.js が存在しているかで推測できる。
/usr/local/bin/ なら、Node.js 公式サイトからインストーラー(.pkg ファイル)をダウンロードして入れた可能性が高いようだ。
そんな気がしてきた(笑)

それでもまだ Homebrew で入れた可能性もあるので、インストールリストにないかチェック。

~ % brew list node
✔︎ JSON API cask_tap_migrations.jws.json                                       Downloaded    2.2KB/  2.2KB
✔︎ JSON API formula_tap_migrations.jws.json                                    Downloaded    2.2KB/  2.2KB
✔︎ JSON API formula.jws.json                                                   Downloaded   34.9MB/ 34.9MB
✔︎ JSON API cask.jws.json                                                      Downloaded   20.9MB/ 20.9MB
Error: No such keg: /opt/homebrew/Cellar/node

やはり、公式サイトからパッケージを落としてきて入れた可能性大。

というわけで、Node.js 公式サイト(日本語) にアクセスし、最新のパッケージインストーラをとってくる。
から
を落とすんやね。

で、インストーラ実行。

20261024_node.jpg

普通に次へ次へといけば問題なく終了。

~ % node -v       
v24.22.1
~ % npm -v        
11.19.1

新しいバージョンになっている。ばっちし(笑)

というわけで、Electron のインストールに移るか。
macOS 版 Eclipse でビルドツールに Maven を指定して Spring Boot プロジェクトを作成していた。
で、プロジェクトの右ボタンメニューから「デバッグ」→「Spring Boot アプリケーション」を選択しビルドを始めると、なぜか Gradle によるビルドエラーが発生するのである。

上に書いたように、ビルドツールには Maven を指定してて、Gradle は使わない設定なのに・・・である。

エラーログをコピーしておくのを忘れたので正確な情報ではないが、「Gradle Core Plugins (plugin is not in 'org.gradle' namespace)」とか、build.gradle が not found だとか、そんな感じのエラーが出てた。

これらの解決方法はネットでググれば色々出てくるんだけど、いや、そうじゃないんやねん。はじめに書いたように、そもそも「Gradle なんか使ってない」ちゅう話なんやで。

20260504_eclipse1.jpg

結局、プロジェクトの右ボタンメニューで「プロパティ」→「プロジェクト・ファセット」でファセットの構成を行ったら、なんかエラーが出なくなった。
ファセットに Gradle は最初から無かったけど。

というわけで、これが本当に原因だったかどうかはわからないが、また同じ状況になったときのためにメモしとく。
macOS では、日本語入力の OFF/ON はスペースキーの左にある「英数」キー(日本語OFF)と、右にある「かな」キー(日本語ON)で行う。例えば「かな」キーを押せば必ず日本語入力になるし、「英数」キーを押せば必ず日本語入力は OFF になる。Windows のように「あれ?今日本語入力だっけ?」と悩むことはない。

Windows だとよくあるでしょ?半角で入力しようと思って「半角/全角|漢字」キー押したのに、すでに半角だったので全角になっちゃったなんてこと(笑)

Mac のキーボードには「半角/全角|漢字」キー、「カタカナ/ひらがな|ローマ字」キーというものは存在しない。
Windows の「半角/全角|漢字」キーのように、日本語入力を交互に OFF/ON 切替するのは、Ctrl キー + スペースキーで行う。

20250423_ime1.jpg

で、うちの MacBook Air では Parallels Desktop 20 for Mac という VMシステムの上で Windows11 Pro を動かしているのだが、当然、「半角/全角|漢字」キーがないので日本語入力への切り替えがキーボードでは行えない。マウスでタスクバー上の IME の文字アイコンをクリックして切り替えるとかしないといけない。不便・・・

というわけで、macOS を使っているときと同じように「英数」「かな」キーを使って日本語入力を切り替えられるようにする。

方法は簡単で、Windows11 の「設定」画面を開き、「時刻と言語」→「言語と地域」→「オプション」(日本語のオプション)→Microsoft IME」(オプション)→ 「キータッチのカスタマイズ」で、「キーの割り当て」をONにし、

無変換キー→「IME-オフ」
変換キー→「IME-オン」
Ctrl + Space →「IME-オン/オフ」

を選択するだけである。これで、macOS 同様、「英数」キー、「かな」キーで日本語入力の OFF/ON が可能となる。

ネット上でググると、IME のバージョンを古いものに戻さないとダメという話が見つかるが、あれは古いバージョンの Parallels や Windows OS での話。俺環境は、2025/4/23 現在で最新の macOS、Windows11、Parallels となっているので、上記のような対応でばっちり。わざわざ IME を古いバージョンに戻す必要はない。

20250423_ime2.jpg

ちなみに、ちなみに、「以前のバージョンの Microsoft IME を使う」を ON にしていると、「キータッチのカスタマイズ」で「キーの割り当て」機能が使えないので、すぐに「以前のバージョンを使う」は OFF にしよう。

「Cyberduck であればトンネリング SSH 接続の設定ができるみたいなんで、そっちにするか・・・(^^;;;」

って書いたんだけど、全然ダメやん・・・SFTP で接続できんやん・・・

SFTP 接続しようとすると「Broken pipe. 接続試行は拒否されました。サーバーがダウンしているか、ネットワーク設定が正しくない可能性があります。」ってエラーが出て全然ダメ。


20241208_cyberduck1.jpg
サーバの方の /var/log/secure を見てみると、

Dec  8 16:07:01 hogehogeserv sshd[13662]: Did not receive identification string from 106.XXX.XXX.XXX port 51585

なんて出てる。むーん・・・

手動で ssh 接続はできているし、何より FileZilla による接続はできている。というわけで Cyberduck だけの問題?

もしかして、サーバ側の sshd のバージョンが古いとか、鍵認証しないとダメとかなん?いやあ、そんなの大きなお世話やなあ・・・
セキュリティについて、どこまで必要で、どこまで対応するかはこっちの問題。俺が決める領域やん。

原因わかんないので、Cyberduck はゴミ箱行きやな。
FileZilla という FTP ソフトは SSH トンネリング接続ができない。

例えば、IPアドレスでアクセス制限されているサーバに、接続許可されているサーバを経由して接続するのをトンネリング接続というんだけど(接続許可されているサーバがポートフォワードという方法を使って、「俺です」って嘘ついてデータのやり取りをするわけ)、FileZilla という macOS でよく使われているソフトにはその機能がない。

なので、SSH ソフトを使ってトンネリングできる環境(ポートフォワード設定)を作って、FileZilla でそれを利用する形になる。

外出先でどうしてもお客さんのサーバのデータを確認しないといけなくなったときはトンネリング接続で SFTP を利用しないといけない。Windows PC が手元にあったら WinSCP という素晴らしいソフトがあるので(毎年寄付してます!(笑))いいんだけど、Macbook Air しか持ってないときは困るのよね。

というわけで、やり方をメモしておく。

1.手元の macOS 上でターミナルを2つ起動する

2.ターミナル1でローカルからリモート方向へのトンネリングのための SSH 接続を行う

トンネリング時の入り口(SFTP接続時に指定する自分自身(localhost))のポート番号):14649
最終的に接続したいサーバの IP アドレス:210.XXX.XXX.XXX
最終的に接続したいサーバのポート番号:22(SSH 接続)

(例)14649:210.XXX.XXX.XXX:22

接続を許可されているサーバ(踏み台)のユーザ:shinoda
接続を許可されているサーバ(踏み台)のホスト名:chinko.exsample.com
接続を許可されているサーバ(踏み台)の接続先ポート番号:22(SSH接続)

(例)shinoda@chinko.exsample.com -p 22

~ % ssh -L 14649:210.XXX.XXX.XXX:22 shinoda@chinko.exsample.com -p 22
shinoda@chinko.exsample.com's password: <chinko.exsample.com にログインするときのパスワード>
Last login: Sun Dec  8 09:34:15 2024 from kd1061550.manman.exsample.com

ログインしたら、そのターミナルは閉じずにそのまま置いておく(exit すると、掘られた「トンネル」も閉じる)

3.ターミナル2で、トンネリング時の入り口ポートが接続待ちになっていることを確認

~ % netstat -na | grep 14649
tcp4       0      0  127.0.0.1.14649        *.*                    LISTEN
tcp6       0      0  ::1.14649              *.*                    LISTEN

port 14649 が LISTEN(接続待ち)になっている

4.FileZilla でローカルホストに接続

サイトマネージャを開き、トンネリング接続のための設定を行う

プロトコル:SFTP
ホスト:localhost
ポート:14649
ログオンタイプ:通常
ユーザー:最終的に接続したいサーバのログインユーザ
パスワード:最終的に接続したいサーバのログインユーザのパスワード

上記設定で接続を行えば、localhost(自分自身 macOS)→接続を許可されているサーバ(踏み台)→最終的に接続したいサーバ という経路で接続される。
「最終的に接続したいサーバ」から見たら、「接続を許可されているサーバ(踏み台)」から接続してきていると思っているが、実はこっそり掘ったトンネルを通って localhost が接続しているという形。

上記の動きを、FileZilla ではなくターミナル上で確認してみることもできる。
ターミナル2で以下のように、「最終的に接続したいサーバ」にログインできることを確認する
(以下の例は、初めての接続だったので、「このホスト、本物?信用していい?」と聞かれてます(笑))

~ % ssh -l root localhost -p 14649
The authenticity of host '[localhost]:14649 ([::1]:14649)' can't be established.
ED25519 key fingerprint is SHA256:4hlxCQFIfF<略>+0Cf0.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:14649' (ED25519) to the list of known hosts.
最終的に接続したいサーバのログインユーザ@localhost's password: <最終的に接続したいサーバのログインユーザのパスワード>
Last login: Sun Dec  8 09:28:46 2024 from 159.XXX.XXX.XXX

これで、「最終的に接続したいサーバ」にログインできれば「トンネル」が作られているということ。

・・・いやぁ、面倒くさいな(笑)。

Cyberduck であればトンネリング SSH 接続の設定ができるみたいなんで、そっちにするか・・・(^^;;;
macOS のターミナルで表示されるプロンプトは糞長い。

shinoda@shinodamarasukenoMacBook-Air ~ %

てな感じで、ターミナルの幅の半分がプロンプトみたいな・・・
(ちなみに、このときは自分のホームディレクトリにいたからこの程度で済んでいるが、他のディレクトリがカレントだったら、そのパスも表示されるので更に長くなる)

けっこう苦痛なのだが、ターミナルを使うこともあまりないのでほっていた。でも、最近シェルであれこれ作業することが増えてきたので、やっぱ苦痛・・・

ということで、プロンプトを変更する。
ちなみに、macOS Sequoia の標準シェルは zch のようだ。

shinoda@shinodamarasukenoMacBook-Air ~ % cat > .zshrc
PROMPT="%d %# "
^D
shinoda@shinodamarasukenoMacBook-Air ~ % source ~/.zshrc
/Users/shinoda %

お、いいねえ。でも、これだとホームディレクトリ名もフルパスで出ちゃうので、ホームディレクトリは「チルダ」を表示するようにしよう。

/Users/shinoda % cat > .zshrc
PROMPT="%~ %# "
^D
/Users/shinoda % source ~/.zshrc
~ % 

ばっちり、オーケー(^_^)

ちなみに、^D というのは Ctrl + D のことね。念の為(笑)

このアーカイブについて

このページには、過去に書かれたブログ記事のうちMacカテゴリに属しているものが含まれています。

前のカテゴリはAndroidです。

次のカテゴリはUNIXやLinuxです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら