ArNextの紹介: Arweave&Vercelへ同時にデプロイできるNext.jsフレームワーク
原文: ArNext
ArNextは、同じコードベースをVercelとArweaveの両方にデプロイできるNextJSベースのフレームワークです。
これにより、これまで不可能だったクラウドを活用したあらゆる種類のパフォーマンス最適化をpermaappに適用することが可能になります。
PermaAppsの制限
Permaappsは、Arweave上にデプロイされたSPA(シングルページアプリケーション)であり、デプロイ前にアプリをビルドするために完全なSSG(静的サイト生成)が必要です。Permaappsは伝統的に、サーバーサイドルーティングがないため、SPA内でのクライアントサイドのハッシュルーティングのみを許可しています。
permaappの例:
permaappsには多くの制限があります。
- SSR(サーバーサイドレンダリング)がないため、動的コンテンツの読み込みが非常に遅い。
- クライアントサイドのハッシュルーティングでは、ルートURLのみがアクセス可能。ハッシュなしの通常のブラウザルーティングでは、リロード時にアクセスできないページに移動してしまう。
- 動的に生成されたページではソーシャルメディアカードが機能しない。Javascriptで動的に生成されたメタタグはX(旧Twitter)などのソーシャルアプリで読み込まれないため、ルートページ用の1つのカードしか持てない。
- SSR、ISR、エッジCDNなどのサーバーサイドの最適化が不可能。
これらの制限により、permaappsは実用的に数百万人のユーザーをオンボーディングすることができません。
ArNextの機能
ArNextアプリは基本的にNextJSアプリですが、一連のハックを通じて同じコードベースから同一のpermaappをビルドすることもできます。これは、VercelではSSR、Arweaveではクライアントサイドルーティングを備えたマルチページSPA(!?)です。
- 同一のアプリをVercelとArweaveの両方にデプロイできます。
- Arweaveにデプロイされたpermaappsは検閲耐性のある永続的なバックアップとして機能します。
- Vercelにデプロイされたアプリには、あらゆる種類のクラウドを活用した最適化を適用できます。
- アプリは静的に生成されたマルチページサイトとして機能しますが、ページが読み込まれると、クライアントサイドルーティングを備えたSPAとして機能します。
サーバーサイドのパフォーマンス強化
以下のVercelにデプロイされたpermaappのパフォーマンスと、上記のArweaveにデプロイされたものを比較してみてください。
Vercel上のものはISR(インクリメンタル静的再生成)により非常に高速です。
動的ページ用のOpenGraphタグ
また、動的に生成されたページのオープングラフメタタグはSSRで有効化されています。
ハッシュルーティングが不要に
Arweaveにデプロイされたpermaappsではハッシュルーティングが不要になりました。
これはArweave Manifests v0.2.0のfallback
を活用することで可能になりました。
ArNextは、修正版のarkbを使用して、fallback
付きの最適化されたマニフェストを生成します。
アセット用の相対パスを動的に生成
NextJSコードベースから静的なpermaappをビルドする最大の課題は、静的ファイルのリンクです。Arweaveゲートウェイはサブディレクトリ型URLでpermaappsをデプロイしますが、そのサブディレクトリ名はビルドされたファイルのハッシュであるため、アプリをビルドする前に知ることができません。NextJSではbasePath
を使用してサブディレクトリデプロイ用のアプリをビルドできますが、ビルド前にハッシュを知らなければ使用できません。また、basePath
は絶対パスのみを許可します。そのため、これは使用できません。
アセットの相対パスをURLに読み込まれた後に動的に計算して挿入する必要がありますが、NextJSはそのような操作を許可していません。実際、主要なWebフレームワークはそのようなファイルリンクを許可していません。
この問題を解決するために、3つのハックが組み合わされています。
- 相対パスを動的に計算し、HTMLヘッドにタグを挿入する(_document.js)
- アプリコードのビルド後にアセットタグを手動で書き換え、不要なhtmlファイルを削除し、実行時に正しいパスを生成するためにwebpackが生成したjsファイルを修正する(arweave.mjs)
- デプロイ前に修正されたarkbで適切な
manifest.json
を生成する(deploy.js)
ArNextアプリの構築方法
ArNextアプリの作成
npx create-arnext-app myapp
cd myapp && yarn
yarn dev
Vercelにデプロイ
vercel --prod
Arweave向けにビルド
yarn arweave
これで、Arweaveにデプロイするための静的アプリがlocalhost:3000で実行されています。
Arweaveにデプロイ
arkbを使用
yarn deploy -w WALLET_PATH
Turboを使用
Turboを使用したデプロイには、Turbo Creditsで資金提供されたウォレットが必要です。
yarn deploy:turbo -w WALLET_PATH
各ファイルのアップロード情報、生成されたArweaveマニフェスト、マニフェストのアップロードレスポンスを含むJSONオブジェクトがコンソールに表示されます。デプロイのマニフェストIDはmanifestResponse.id
で確認できます。
ArNext ユーティリティ
VercelとArweaveの両方で同じように動作させるために、NextJSアプリコードにいくつかの小さな変更を加える必要があります。
現在、ArNextはNextJSのページルーターとArweave用のreact-router-dom
のみをサポートしています。
Link / useParams / useRouter
Link
、useParams
、useRouter
をarnext
のものに置き換えます。これによりnext/router
とreact-router-dom
が連携します。
import { Link, useParams, useRouter } from "arnext"
export default function Post() {
const router = useRouter() // router.push(pathname)
const { id } = useParams()
...
return <Link href={`/post/${id}`}>/post/{id}</Link>
}
getStaticProps / ssr
getStaticProps
をssr
でラップします。
import { ssr } from "arnext"
export const getStaticProps = ssr(async ({}) => {
...
return { props }
})
移行ガイド
現在、ArNextはsrc
ディレクトリとJSを使用しないページルーターでのみ動作します。
既存のNextJSアプリがある場合は、以下の手順に従ってください。create-arnext-app
を使用してソースコードを手動でコピーする方が手間が少ないかもしれません。
- サポートされていない機能を削除する
ArNextは現時点で特定のNextJS機能をサポートしていません。あなたのアプリが以下の機能を使用している場合は、代替の実装方法を見つけてください。
- Typescript
- Appルーター
-
src
ディレクトリ next/font/local
next/image
-
next/router
はpush
のみサポート
これらは将来のリリースでサポートされる予定です。
- 必要な依存関係をインストールする。
yarn add arnext
yarn add arnext-arkb cheerio cross-env starknet @ardrive/turbo-sdk --dev
-
next.config.mjs
で設定をラップする。
/** @type {import('next').NextConfig} */
import arnext from "arnext/config"
const nextConfig = { reactStrictMode: true }
export default arnext(nextConfig)
-
_document.js
のHead
を置き換える。
import { Html, Main, NextScript } from "next/document"
import { Head } from "arnext"
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
-
_app.js
のComponent
をArNext
に置き換える。
import { ArNext } from "arnext"
export default function App(props) {
return <ArNext {...props} />
}
-
getStaticProps
をssr
でラップする
import { ssr } from "arnext"
export const getStaticProps = ssr(async ({}) => {
...
return { props }
})
-
Link
、useParams
、useRouter
をarnext
のものに置き換える。
import { Link, useParams, useRouter } from "arnext"
export default function Post() {
const router = useRouter() // router.push(pathname)
const { id } = useParams()
...
return <Link href={`/post/${id}`}>/post/{id}</Link>
}
-
arweave.mjs
ファイルをアプリのルートディレクトリにコピーする。 -
スクリプトコマンドを
package.json
に追加する。
{
...
"scripts": {
"arweave": "npm run build:arweave && npx serve -s out",
"deploy": "node node_modules/arnext-arkb deploy out",
"deploy:turbo": "turbo upload-folder --folder-path out",
"build:arweave": "cross-env NEXT_PUBLIC_DEPLOY_TARGET='arweave' next build && node arweave.mjs",
...
},
...
}
- Arweave向けにビルドする
yarn arweave
Arweaveにデプロイするための静的版NextJSアプリがlocalhost:3000で実行されているはずです。
- Arweaveにデプロイする
すべてが正常に動作していれば、arkb
またはturbo
を使用してアプリをデプロイできます。
yarn deploy -w KEYFILE
yarn deploy:turbo -w KEYFILE

Empowering your applications with a high-performance, scalable, decentralized, and reliable database solution 👉 linktr.ee/weavedb
Discussion