React+Viteで作成したSPAをブロックチェーンSymbol上で分散型ホスティング

2025/01/11に公開

React + Vite

プロジェクトの作成

my-projectプロジェクトを作成。

yarn create vite my-project --template react-ts

NPM パッケージをインストール

cd my-project
echo "nodeLinker: node-modules" > .yarnrc.yml
yarn

prettiervite-plugin-singlefileをインストール。

yarn add -D prettier vite-plugin-singlefile rollup

Prettier の設定

.prettierrc.jsonファイルを追加する。

.prettierrc.json
{
  "tabWidth": 2,
  "printWidth": 100,
  "trailingComma": "es5",
  "semi": false,
  "singleQuote": true
}

Vite の設定

vite.config.tsファイルを変更する。

vite.config.ts
import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
+import { viteSingleFile } from 'vite-plugin-singlefile'

// https://vite.dev/config/
export default defineConfig({
-  plugins: [react()],
+  plugins: [viteSingleFile()],
+  build: {
+    assetsInlineLimit: 10240, // 画像のインライン化サイズを指定(10KB以下の画像)
+  },
})

Git 無視リスト

yarn の管理しなくていいファイルを除外。
.gitignoreに追記する。

# yarn
.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

画像ファイルのコピーとソースの変更

assetsフォルダの中の画像のみインライン化されるので、publicフォルダにあるvite.svgassetsフォルダに移動させます。これに合わせてソースも変更します。

src/App.tsx
import { useState } from 'react'
import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
+import viteLogo from './assets/vite.svg'
import './App.css'

function App() {

トップにあるindex.html内に favicon がありますが、こちらはpublicフォルダからなのでインライン化されません。手動でインライン化する必要があります。
今回は特に拘りもないのでインライ化はせずそのままにします。

実際の開発の場合は、用途に合わせて画像も Metal 化をしたほうが良いと思います。

ビルド

yarn build

これでdistindex.htmlが作成されます。

Metal

Node.js v16 のみで動作するようなので?、Volta で Node.js のバージョンを指定してローカルインストールしてから使うようにします。

作業ディレクトリの作成

作業ディレクトリを作成して、npm 初期化します。

mkdir metal
cd metal
npm init -y

Node.js バージョンのピン留め

Volta を使用して、バージョンをピン留めします。

volta pin node@16
volta pin npm@6

Metal on Symbol のインストール

Node.js のバージョンを固定しているので、問題なくインストール出来るはずです。

npm i metal-on-symbol

ノード情報をセット

アナウンス先のノードの設定です。以下から適当なノードを選んで設定してください。

メインネットの場合
https://symbol.services/nodes

テストネットの場合
https://testnet.symbol.services/nodes

環境変数へ登録

コマンドで指定も出来ますが、面倒なので環境変数へ一時登録します。

コマンドプロンプトの場合
set NODE_URL=http://sakia.harvestasya.com:3000
パワーシェルの場合
$Env:NODE_URL="http://sakia.harvestasya.com:3000"

Forge(チェーンにアップロード)する

作成した SPA をmetalフォルダに格納している場合です。

npx metal forge index.html --seal 2

秘密鍵を聞かれるので、登録先のアカウントの秘密鍵を貼り付ける。
見積もられた手数料とと共にアナウンスするか聞かれるので YES を選択し承認を待ちます。
承認されるとこんな感じで結果が表示されます。

> npx metal forge index.html --seal 2
√ Signer's Private Key? ... ****************************************************************
Signer Address is TBZN46UIU5BFLJI46VB4JTHHCE5EN2RFLR7NX3A
Announcing 2 aggregate TXs with fee 22.712812 XYM total.
√ Are you sure announce these TXs? ... yes
Completed in 37.307 secs.

  --- Summary of Forging (Receipt) ---
  Metal ID: FeFHr8MCDpLVt2TAmMSFuYhrRtFs7sN3ssceDQvTQWpbP6
  Type: Account
  Source Account Address: TBZN46UIU5BFLJI46VB4JTHHCE5EN2RFLR7NX3A
  Target Account Address: TBZN46UIU5BFLJI46VB4JTHHCE5EN2RFLR7NX3A
  Metadata Key: 0F11F9994E46BBAB
  Additive: 0
  Text: ["seal1",152346,"text/html"]
  Data size: 152346 bytes
  # of Aggregate TXs: 2
  TX Fee: 22.712812 XYM
  Signer Address: TBZN46UIU5BFLJI46VB4JTHHCE5EN2RFLR7NX3A
  Network Type: 152

確認

Rest に Metal ID を添えてアクセすると登録したページが表示されます。

また、上記 2 つのノードは https にも対応しているので https 対応したページも作成できます。

Discussion