カテゴリー
【nodejsアプリ開発】pkg/Express.js/Svelteでポータブルなバイナリ起動のウェブブラウザアプリを作る
※ 当ページには【広告/PR】を含む場合があります。
2023/01/06

以前のブログの内容で、Nodejsアプリをバイナリアプリ化してくれる
pkgの魅力はなんと言ってもビルド後のバイナリサイズが小さいことです。
小さければ小さいほどプログラムを使ってもらえるユーザーに配布しやすくなるのがメリットです。
今回はこのpkgの利用を考えていく一例として、
Svelte側のSPAアプリを準備する
pkgとExpress.jsとSvelteのプロジェクトを全てひとまとめにして開発を進めても良いのですが、ここでは、アプリの中身をサッと変えられるように、バックエンドの実行処理側(pkg/Express.js)と、フロントエンド(Svelte)を分離したプロジェクトで別々に管理していきます。
まずはアプリの中身にあたる部分を「Svelte」と「Vite」で作っていきます。 なお、SvelteでなくてもAngularやVueやReactなど別のフレームワークで作っても結構です。
以前の回で、
今回は、そちらの内容を起点にして、適当なSvelteプロジェクトを以下のコマンドでビルドしてみます。
$ yarn build
#もしくは
$ ./node_modules/.bin vite build
ビルドするとVite:Svelteでの開発の場合、デフォルトでは
dist
$ tree dist/
dist/
├── assets
│ ├── index.501bb487.css
│ ├── index.a7c6f463.js
│ ├── hoge.a93068e7.svg
│ └── piyo.f6732df8.svg
├── favicon.png
└── index.html
どのJSフレームワークでもプロダクションビルドするほぼこんな感じで、ここではひとまずビルド出力したリソースファイル一式を準備できれば結構です。
次の節で、このアプリの中身を使うための
バイナリで動くpkg/Express.jsのバックエンドアプリを作成する
こちらが本題で、
pkg
まだpkgの使い方に慣れていない方は是非ともまずそちらを一読ください。
以降ではポイントを絞ってプロジェクトを作成していきます。
pkgプロジェクトの作成
適当なプロジェクトフォルダを作って、以下のように
package.json
{
"name": "pkg-express",
"version": "0.0.1",
"description": "To execise to use pkg with Express.js."
}
また今回はtypescriptでトランスパイルするので、以下のようにインストールを済ませておきましょう。
$ yarn add typescript tslib -D
typescriptの初期化(tsconfig.json)を行います。
$ yarn tsc --init
後は、
pkg
$ yarn add pkg -D
インストール後は、
package.json
{
"name": "pkg-express",
"version": "0.0.1",
"description": "To execise to use pkg with Express.js.",
"bin": "index.js",
"scripts": {
"pkg": "pkg",
"build": "tsc && yarn pkg ."
},
"devDependencies": {
"pkg": "^5.8.0",
"tslib": "^2.4.1",
"typescript": "^4.9.4"
}
}
ひとまず準備はこれでOKです。
Express.js用のコードを実装する
pkgアプリを作成した
Express.js
ここでのプロジェクト自体は至ってシンプルに作れますが、サーバー側のプログラムを作成するときに特有の考え方が凝縮されているため、
それはさておいて、以前「nexe」でExpress.jsのバイナリアプリ化の話はすでに紹介しておりました。
まずはプロジェクトにExpress.jsを導入します。
$ yarn add express -S
$ yarn add @types/express -D
次に
index.ts
import express from "express";
import { join } from 'path';
const endpoint = 'http://localhost:3000';
process.stdout.write(`\x1b[0;32m\x1b[6m👇をCtrl+クリックしてブラウザで開こう!\x1b[0m\n\x1b[0;43;1;37m${endpoint}\x1b[0m`);
const app = express();
const distFolder = join(process.cwd(), 'browser');
app.get('/', (req, res) => {
res.sendFile(distFolder + '/index.html');
});
app.get(`/*.*`, express.static(distFolder));
app.get(`/assets/*.*`, express.static(distFolder + '/assets/'));
app.listen(3000, () => {});
この時点ではまだSvelteで出力したアプリの中身を入れるためのルートフォルダを作っていませんが、ルートフォルダの名前を
browser
ローカルサーバーを起動してルートパス(
/
index.html
ただし、index.htmlを読み込んだ後に、さらに必要なファイルを読み込む場合がありますので、
/*.*
/assets/*.*
express.static
ちなみに標準出力させる文字をエスケープシークエンス(
\x1b[...
pkgバイナリアプリをビルド
次に
pkg
コマンドオプションにビルド設定をすべて指定していくのは結構しんどいので、package.jsonにpkgタグを作成し、ビルドオプションをそこに記述します。
{
"name": "pkg-express",
"version": "0.0.1",
"description": "To execise to use pkg with Express.js.",
"bin": "index.js",
"scripts": {
"pkg": "pkg",
"build": "tsc && yarn pkg ."
},
"pkg": {
"targets": ["latest-linux-x64"],
"outputPath": "dist"
},
"devDependencies": {
"pkg": "^5.8.0",
"tslib": "^2.4.1",
"typescript": "^4.6.4",
"@types/express": "^4.17.15"
},
"dependencies": {
"express": "^4.18.2"
}
}
エンドポイントとなるjsファイルは
"bin"
ではいよいよビルドの時間です。
$ yarn build
無事にビルドできたら
dist
$ tree dist
dist/
└── pkg-express
ちなみにバイナリのサイズを確認すると、
$ du -sSk dist/
47060 dist/
おおよそ47MB程度になっています。
ここからさらにzipで固めてまとめておくと、アプリ配布にも軽量かつ利便性が高いのではないかと思います。
DebianOS(Linux)でpkgバイナリアプリの起動確認
では最後にSvelteで作ったSPA(index.html側)と、pkg/Express.jsで作ったバイナリアプリを統合して、起動するか試してみましょう。
シェルスクリプトなどで2つのプロジェクトのビルド生成物を自動でまとめてくれるようにすれば楽なのですが、ここでは手動でまとめてみます。
まずは、バイナリプログラム・
pkg-express
browser
$ mkdir browser
$ ls
browser pkg-express
この
browser
dist
フォルダ構造の一例を挙げると、
$ tree
.
├── browser
│ ├── assets
│ │ ├── index.501bb487.css
│ │ ├── index.a7c6f463.js
│ │ ├── hoge.a93068e7.svg
│ │ └── piyo.f6732df8.svg
│ ├── favicon.png
│ └── index.html
└── pkg-express
のようになっていると思います。
なお、静的なリソース用に
assets
express.static(<アセットフォルダまでのパス>)
ということで、ようやく起動準備まで出来上がりました。
あとは実際に動かしてみましょう。
(※動作中のSPAアプリは適当に作った自作シューティングのデモを動かしています。デフォルトのViteのものではないのでご注意ください。)
これでネットが繋がっていなくてもスタンドアロンなHTMLゲーム等の実行環境が出来上がりました。
まとめ
ネットワーク環境がなくてもブラウザで動作するタイプのバイナリアプリの作り方を取り上げてみました。
最近のブラウザはかなり高性能なAPIが充実しており、アイデア次第ではかなり有用な使いみちが可能ではないかと思います。
今後また面白い使い道があれば、このブログにて紹介していこうかと思います。
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー