1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Neutralino.js + Vite + Solid でデスクトップアプリを始めてみた

Last updated at Posted at 2024-05-25

環境

Windows 11, Node v18 でやりました

> node --version
v18.20.3
> npm --version
10.7.0

Neutralino をインストール

npm install -g @neutralinojs/neu

neu というコマンドがインストールされます。

テンプレートからプロジェクトを作成

PS D:\mitayuki67> neu create neut-example3 --template neutralinojs/neutralinojs-zero
neu: INFO Downloading neutralinojs/neutralinojs-zero template to neut-example3 directory...
neu: INFO Extracting template zip file...
neu: INFO Downloading Neutralinojs binaries..
neu: INFO Found the latest release tag v5.1.0 for neutralinojs...
neu: INFO Extracting binaries.zip file...
neu: INFO Finalizing and cleaning temp. files.
neu: INFO Downloading the Neutralinojs client..
neu: INFO Found the latest release tag v5.1.0 for neutralino.js...
neu: INFO Downloading the Neutralinojs types..
neu: INFO Finalizing and cleaning temp. files...
-------
neu: INFO Enter 'cd neut-example3 && neu run' to run your application.
  _   _            _             _ _             _
 | \ | | ___ _   _| |_ _ __ __ _| (_)_ __   ___ (_)___
 |  \| |/ _ \ | | | __| '__/ _` | | | '_ \ / _ \| / __|
 | |\  |  __/ |_| | |_| | | (_| | | | | | | (_) | \__ \
 |_| \_|\___|\__,_|\__|_|  \__,_|_|_|_| |_|\___// |___/
                                              |__/

Vite + solid プロジェクトを作成

www は不要なので削除し、solid-src ディレクトリを作ります。

PS D:\mitayuki67> cd .\neut-example3\
PS D:\mitayuki67\neut-example3> rm -r www
PS D:\mitayuki67\neut-example3> pnpm create vite@latest solid-src --template solid
.../18fad834751-5f84                     |   +1 +
.../18fad834751-5f84                     | Progress: resolved 1, reused 0, downloaded 1, added 1, done

Scaffolding project in D:\mitayuki67\neut-example3\solid-src...

Done. Now run:

  cd solid-src
  pnpm install
  pnpm run dev

PS D:\mitayuki67\neut-example3> cd .\solid-src\
PS D:\mitayuki67\neut-example3\solid-src> pnpm install
Packages: +82
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 120, reused 3, downloaded 79, added 82, done
node_modules/.pnpm/esbuild@0.20.2/node_modules/esbuild: Running postinstall script, done in 575ms

dependencies:
+ solid-js 1.8.17

devDependencies:
+ vite 5.2.11
+ vite-plugin-solid 2.10.2

Done in 7.1s

PS D:\mitayuki67\neut-example3> cd .\solid-src\
PS D:\mitayuki67\neut-example3\solid-src> pnpm build

> solid-src@0.0.0 build D:\mitayuki67\neut-example3\solid-src
> vite build

vite v5.2.11 building for production...
✓ 10 modules transformed.
dist/index.html                  0.46 kB │ gzip: 0.30 kB
dist/assets/index-D61y85IL.css   1.21 kB │ gzip: 0.62 kB
dist/assets/index-CJZJvNTb.js   10.60 kB │ gzip: 4.26 kB
✓ built in 492ms
PS D:\mitayuki67\neut-example3\solid-src> cd ..

neutralino.config.json を編集

  1. documentRoot, cli/resourcesPath/solid-src/dist/ に変える
  2. cli/clientLibrary を削除する
  3. modes/window を調整する(任意)
diff --git a/neutralino.config.json b/neutralino.config.json
index 7325a21..6b5d786 100644
--- a/neutralino.config.json
+++ b/neutralino.config.json
@@ -2,7 +2,7 @@
   "applicationId": "js.neutralino.zero",
   "version": "1.0.0",
   "defaultMode": "window",
-  "documentRoot": "/www/",
+  "documentRoot": "/solid-src/dist/",
   "url": "/",
   "enableServer": true,
   "enableNativeAPI": true,
@@ -13,17 +13,15 @@
     "window": {
       "title": "neut-example3",
       "width": 800,
-      "height": 500,
+      "height": 600,
       "minWidth": 400,
-      "minHeight": 200,
-      "icon": "/www/icon.png"
+      "minHeight": 200
     }
   },
   "cli": {
     "binaryName": "neut-example3",
-    "resourcesPath": "/www/",
+    "resourcesPath": "/solid-src/dist/",
     "extensionsPath": "/extensions/",
-    "clientLibrary": "/www/neutralino.js",
     "binaryVersion": "5.1.0",
     "clientVersion": "5.1.0"
   }

実行

PS D:\mitayuki67\neut-example3> neu run
neu: INFO Starting process: neutralino-win_x64.exe  --load-dir-res --path=. --export-auth-info --neu-dev-extension --neu-dev-auto-reload
neu: INFO neu CLI connected with the application.

実行できました

image.png

ネイティブAPIをインストール

solid-src> pnpm add @neutralinojs/lib
Packages: +1
+
Progress: resolved 121, reused 82, downloaded 1, added 1, done

dependencies:
+ @neutralinojs/lib 5.1.0

Done in 3.4s

index.html__neutralino_globals.js をインポートするように追加します。

index.html
    <title>Vite + Solid</title>
    <script src="__neutralino_globals.js"></script>
  </head>

filesytem.readDirectory を追加してみます。

neutralino.config.json
  "nativeAllowList": [
    "app.*",
    "filesystem.readDirectory"
  ],
...
  "cli": {
    "binaryName": "neut-example3",
    "resourcesPath": "/solid-src/dist/",
    "extensionsPath": "/extensions/",
    "frontendLibrary": {
      "patchFile": "/solid-src/index.html",
      "devUrl": "http://localhost:5173",
      "projectPath": "/solid-src/",
      "initCommand": "pnpm install",
      "devCommand": "pnpm dev",
      "buildCommand": "pnpm run build"
    },
    "binaryVersion": "5.1.0",
    "clientVersion": "5.1.0"
  }

frontendLibrary/patchFile とは、デバッグ実行のためにソースコード中の __neutralino_globals.jshttp://localhost:ポート番号/__neutralino_globals.js に置換する設定です。
これが置換されたままだとビルドしても実行できないので、neu build する前に戻す必要があります。

index.jsx
/* @refresh reload */
import { render } from 'solid-js/web'

import './index.css'
import App from './App'

import { init } from "@neutralinojs/lib"

const root = document.getElementById('root')

render(() => <App />, root)

if (window.NL_PORT == undefined) {
    window.location.reload()
}
init()

前述した __neutralino_global.js で環境変数の NL_PORT などを設定しているのですが、デバッグ実行だと patchfile が書き換わる前に実行されてしまうせいか、サーバーかクライアントのどちらかをリロードしないと実行できません。そこで未定義なら reload しています。しかし、これはデバッグ実行にしか影響がないので、本番コードには含めないほうが良いかもしれません。

App.jsx
import { createEffect, createSignal } from 'solid-js'
import solidLogo from './assets/solid.svg'
import viteLogo from '/vite.svg'
import './App.css'

import { filesystem } from "@neutralinojs/lib"

function App() {
  const [count, setCount] = createSignal(0)
  const [data, setData] = createSignal("")

  createEffect(() => {
    filesystem.readDirectory('./').then((data) => {
      setData(data.map((each)=>each.entry).join('|'))
    }).catch((err) => {
      console.log(err)
    })
  })

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} class="logo" alt="Vite logo" />
        </a>
        <a href="https://solidjs.com" target="_blank">
          <img src={solidLogo} class="logo solid" alt="Solid logo" />
        </a>
      </div>
      <h1>Vite + Solid</h1>
      <div class="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count()}
        </button>
        <p>
          Edit <code>src/App.jsx</code> and save to test HMR
        </p>
      </div>
      <p class="read-the-docs">
        Click on the Vite and Solid logos to learn more
      </p>
      <p>
        data: {data()}
      </p>
    </>
  )
}

export default App

filesystem から適当にカレントディレクトリのファイル一覧を表示させてみます。

image.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?