私の環境では使えなかった。v18以降限定らしい。もし使えたらaxiosやelectron-fetchなどネットワーク通信用にパッケージをインストールせずに済みそう。

ブツ

インストール&実行

NAME='Electron.electron-fetch.20220824144925'
git clone https://github.com/ytyaru/$NAME
cd $NAME
npm install
npm start

準備

  1. GitHubアカウントを作成する
  2. repoスコープ権限をもったアクセストークンを作成する
  3. インストール&実行してアプリ終了する
    1. db/setting.jsonファイルが自動作成される
  4. db/setting.jsonに以下をセットしファイル保存する
    1. usernameに任意のGitHubユーザ名
    2. tokenrepoスコープ権限を持ったトークン
    3. repoに任意リポジトリ名(mytestrepo等)
  5. dst/mytestrepo/.gitが存在しないことを確認する(あればdstごと削除する)
  6. GitHub上に同名リモートリポジトリが存在しないことを確認する(あれば削除する)

実行

  1. npm startで起動またはアプリでCtrl+Shift+Rキーを押す(リロードする)
  2. git initコマンドが実行される
    • repo/リポジトリ名ディレクトリが作成され、その配下に.gitディレクトリが作成される
  3. createRepo実行後、アプリの開発者ツールのコンソールにJSON結果が表示される

なお、私の環境では以下エラーになった。

Uncaught (in promise) Error: Error invoking remote method 'fetch': ReferenceError: fetch is not defined

原因はNode.jsのバージョンだと思う。

$ node --version
v16.15.1

あれ、私の環境ってたぶん最新のはずだけどな。Electronを使ってみるのときパッケージnを使って最新版をインストールしているはず。とおもったらv16だった。

Node.jsのページをみてみると、2種類あるようだ。執筆時点で推奨版が16.17.0、最新版が18.8.0だった。よくわからんが、非推奨版なら18にできるってことかな? それは嫌だなぁ。

呼び名が不穏

というか推奨版最新版という呼び方がよくわからない。旧版最新版推奨版非推奨版ならわかるのだが。なにか不都合なことを隠そうとして言い換えているような不誠実であやしい言葉遣いにみえる。

ふつうのアプリなら何も考えず最新版のほうを入れるけど、対比されている対象が推奨版だというのが怖い。どう考えても推奨版のほうがよさげに見えるのだが。

推奨版最新版

たぶん意味としては安定版開発版だと思う。最新版はきっと不安定でバグがある可能性が高いのだろう。そうでなければ分ける必要もないし、nでその最新版のほうをインストールしているはず。実際は推奨版のほうがインストールされていたっぽいので、そうするだけの理由があるのだろう。

もし最新版でなく不安定版とか非推奨版みたいな名前にしたら誰もダウンロードしたがらないから最新版という綺麗な名前にしたのでは? 実際はどうなのか知らないけど、nによる推奨版をインストールするのが良い選択だと考えておこう。

新しい機能を試してみたい気持ちはあるけど、それでシステムクラッシュとかしたら目も当てられない。なのでここは推奨版だけを入れておく。

推奨版(LTS)

ダウンロードページをみるとLTS 推奨版と書いてある。ようするにLTSというのは推奨版のことらしい。ついでにLTSとはLong-Term Support、長期サポートの略だとか。用語が乱立してて混乱する。

情報源

Node.js v18 fetchによると外部パッケージのインストールなしでfetch APIが使えるようだ。でもv18以降限定らしい。しかもそれは推奨版ではないという。最新版を入れたら動作するかもしれないが、怖いので未確認。

LTSのリリーススケジュールとやらをみると、v18がアクティブになるのは2022-10-25みたい。あと二ヶ月後には推奨版になるようだ。それまで待つのが得策か。

今回のコードはv18以降なら動作すると思うので、コードだけアップしておくことにした。

コード抜粋

main.js

ipcMain.handle('fetch', async(event, url, options)=>{
    const res = await fetch(url, options).catch(e=>console.error(e));
    console.log(res)
    const json = await res.json()
    console.log(json)
    return json
})

preload.js

const {remote,contextBridge,ipcRenderer} =  require('electron');
contextBridge.exposeInMainWorld('myApi', {
    fetch:async(url, options)=>await ipcRenderer.invoke('fetch', url, options),
})

renderer.js

window.addEventListener('DOMContentLoaded', async(event) => {
    const setting = await Setting.load()
    const git = new Git(setting?.github)
    const hub = new GitHub(setting?.github)
    if (setting?.github?.repo) {
        const exists = await git.init(document.getElementById('github-repo').value)
        if (!exists) {
            const res = await window.myApi.fetch(
                `https://api.github.com/user/repos`,
                {
                    'method': 'POST',
                    'headers': {
                        'Authorization': `token ${setting.github.token}`,
                        'User-Agent': `${setting.github.username}`,
                        'Content-Type': 'application/json',
                    },
                    'body': JSON.stringify({
                        'name': `${setting.github.repo}`,
                        'description': 'リポジトリの説明',
                    }),
                },
            )
            console.log(res)
        }
    }
})