All Articles

Next.jsのServer ComponentsでLlamaIndexTSを使う際の設定

はじめに

Next.jsのプロジェクトでサーバーサイドでLlamaIndexTSを使用しようとしたところ

 ⨯ ./node_modules/onnxruntime-node/bin/napi-v3/darwin/arm64/onnxruntime_binding.node
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

のようなエラーが発生して、対処方法を調べたので残しておきます。

結論だけいうとnext.config.mjsに以下のような設定を追加すれば良いです。

experimental: {
  serverComponentsExternalPackages: ["sharp", "onnxruntime-node"],
},

Errorの再現

プロジェクトの設定

サンプルプロジェクトを作ります。

$ npx create-next-app@latest
Need to install the following packages:
[email protected]
Ok to proceed? (y)

✔ What is your project named? … nextjs-llamaindex-test
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes

Llamaindexを追加します。

$ cd nextjs-llamaindex-test/
$ npm i llamaindex

このときpackage.jsonの内容は以下のようになっています。

$ cat package.json
{
  "name": "nextjs-llamaindex-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "llamaindex": "^0.5.24",
    "next": "14.2.9",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "eslint": "^8",
    "eslint-config-next": "14.2.9",
    "postcss": "^8",
    "tailwindcss": "^3.4.1",
    "typescript": "^5"
  }
}

APIの追加

Test用のAPIを追加します。

$ mkdir -p app/api/complete
$ touch app/api/complete/route.ts

route.tsの中身はシンプルにリクエストのBodyから読み取った内容をLLMに渡して結果を返すだけにします。

import { NextResponse, NextRequest } from "next/server";
import { Groq } from "llamaindex";

export async function POST(request: NextRequest) {
  const { prompt } = await request.json();
  try {
    const llm = new Groq();
    const result = await llm.complete({ prompt });
    return NextResponse.json({ result: result.text });
  } catch (error) {
    return NextResponse.json({ error });
  }
}

今回はLLMにGroqを使用していますが何でもいいです。 Groqを使っている場合は環境変数GROQ_API_KEYにAPIキーを設定しておいてください。

エラーの再現

開発サーバーを立ち上げます。

$ npm run dev

localhost:3000にサーバーが立ち上がるので、リクエストを送ってみます。

$ curl -X POST -H "Content-Type: application/json" -d '{"prompt":"エラーが発生しますか?"}' localhost:3000/api/complete

すると、開発サーバーを立ち上げたターミナルに以下のようなエラーが出ていることが分かります。

 ⨯ ./node_modules/onnxruntime-node/bin/napi-v3/darwin/arm64/onnxruntime_binding.node
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

Import trace for requested module:
./node_modules/onnxruntime-node/bin/napi-v3/darwin/arm64/onnxruntime_binding.node
./node_modules/onnxruntime-node/bin/napi-v3/ sync ^\.\/.*\/.*\/onnxruntime_binding\.node$
./node_modules/onnxruntime-node/dist/binding.js
./node_modules/onnxruntime-node/dist/backend.js
./node_modules/onnxruntime-node/dist/index.js
./node_modules/@xenova/transformers/src/backends/onnx.js
./node_modules/@xenova/transformers/src/env.js
./node_modules/@xenova/transformers/src/transformers.js
./node_modules/llamaindex/dist/internal/deps/transformers.js
./node_modules/llamaindex/dist/embeddings/HuggingFaceEmbedding.js
./node_modules/llamaindex/dist/embeddings/index.js
./node_modules/llamaindex/dist/index.edge.js
./node_modules/llamaindex/dist/index.react-server.js
./app/api/complete/route.ts

エラー内容を見る限りllamaindex, transformers, onnxruntime-nodeのどこかで何か問題が起きてそうです。

エラーメッセージで検索してみると、このIssueがみつかりました。

Issueによるとnext.config.mjsに設定を追加すれば解決するとのことなので以下のように設定します。

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverComponentsExternalPackages: ["sharp", "onnxruntime-node"],
  },
};

export default nextConfig;

開発サーバーを再度立ち上げてリクエストを送ると正常に動いていることが確認できます。

$ curl -X POST -H "Content-Type: application/json" -d '{"prompt":"エラーが発生しますか?"}' localhost:3000/api/complete
{"result":"あなたが私にエラーを示すコードや文脈を提供しない限り、私は判断することができません。エラーメッセージと共に問題のコードを提供することで、私はエラーを修正するためのアドバイスを提供することができます。"}

Published Sep 11, 2024

スタートアップで働くデータエンジニア兼データサイエンティスト。興味の範囲はデータパイプラインの構築、データ分析、機械学習、クラウドなどなど。