Angular/SSRアプリケーションでPrisma/SQLiteを利用する際の注意点
※ 当ページには【広告/PR】を含む場合があります。
2025/07/03

SSRの仕組みを使う
「@angular/ssr」
import { createNodeRequestHandler } from '@angular/ssr/node';
import express from 'express';
import asyncify from 'express-asyncify';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';
import { devRoute } from './dev';
export function app(): express.Express {
const server = asyncify(express());
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../browser');
server.use(devRoute({
distFolderRaw: browserDistFolder
}));
return server;
}
export const server = app();
export const reqHandler = createNodeRequestHandler(server);
import { Router, static as static_ } from 'express';
import asyncify from 'express-asyncify';
import { writeResponseToNodeResponse, createWebRequestFromNodeRequest } from '@angular/ssr/node';
import { AngularAppEngine } from '@angular/ssr';
export const devRoute = ({ distFolderRaw }: { distFolderRaw: string }) => {
const devRouter = asyncify(Router({ mergeParams: true }));
const angularAppEngine = new AngularAppEngine();
// All regular routes use the Angular engine
devRouter.get(/(.*)/, async (req, res, next) => {
const _req = createWebRequestFromNodeRequest(req);
const _res = await angularAppEngine.handle(_req);
if (_res) {
if (req.url === '/error') {
const _resp = new Response(_res.body, {
status: 404,
headers: _res.headers
});
writeResponseToNodeResponse(_resp, res);
}
else {
writeResponseToNodeResponse(_res, res);
}
} else {
next()
}
});
return devRouter;
};
/api
import { Router, static as static_ } from 'express';
import asyncify from 'express-asyncify';
import { writeResponseToNodeResponse, createWebRequestFromNodeRequest } from '@angular/ssr/node';
import { AngularAppEngine } from '@angular/ssr';
//👇Prismaクライアントを追加
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export const devRouexport const devRoute = ({ distFolderRaw }: { distFolderRaw: string }) => {
const devRouter = asyncify(Router({ mergeParams: true }));
const angularAppEngine = new AngularAppEngine();
//👇/apiルートにアクセスしたときに適当なデータを取得できる?
devRouter.get('/api', async (req,res) => {
const price = await prisma.priceInfo.findUnique({
where: { id: 4 }
});
console.log(price);
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(foundUser, null, 3));
});
// All regular routes use the Angular engine
devRouter.get(/(.*)/, async (req, res, next) => {
const _req = createWebRequestFromNodeRequest(req);
const _res = await angularAppEngine.handle(_req);
if (_res) {
if (req.url === '/error') {
const _resp = new Response(_res.body, {
status: 404,
headers: _res.headers
});
writeResponseToNodeResponse(_resp, res);
}
else {
writeResponseToNodeResponse(_res, res);
}
} else {
next()
}
});
return devRouter;
};
/api
//...
private http = inject(HttpClient);
//...
this.http.get(`api`, { responseType: 'json' })
.pipe(catchError((err: any) => {return EMPTY;}));
#...
5:01:10 PM [vite] (ssr) Error when evaluating SSR module ./server.mjs: __dirname is not defined
#...
__dirname
angular.json
[architect] > [build] > [options]
externalDependencies
//...
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
//👇を追加
"externalDependencies": [
"@prisma/client"
],
//...
@prisma/client
➜ Local: http://localhost:1234/
➜ Network: http://172.19.0.2:1234/
#...
{
id: 4,
datetime: 2025-06-29T12:58:16.623Z,
boardInfo: '{"price":1000}',
productCodeId: '7548'
}

externalDependenciesの落とし穴
@prisma/client
generator client {
provider = "prisma-client-js"
//出力先を@prisma/client外に指定
output = "../build"
}
//...
prisma generate
build
angular.json
//...
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"externalDependencies": [
//👇試しに相対フォルダパスを指定
"./build"
],
//...
5:20:21 PM [vite] (ssr) Error when evaluating SSR module ./server.mjs: EISDIR: illegal operation on a directory, read build
//...
"compilerOptions": {
//...
//👇ディレクトリのエイリアスを設定
"paths": {
"prisma_client": [
"./build"
],
}
angular.json
//...
"externalDependencies": [
"prisma_client"
],
//...
5:24:26 PM [vite] (ssr) Error when evaluating SSR module ./server.mjs: Cannot find module 'prisma_client' imported from '/usr/src/app/.angular/vite-root/kubochart-viewer/server.mjs'
node_modules
externalDependencies
node_modules
yarn link(npm link)を使う
「yarn link(もしくはnpm link)」
prisma generate
generator client {
provider = "prisma-client-js"
//出力先を@prisma/client外に指定
output = "../build"
}
//...
../build
$ prisma generate
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
✔ Generated Prisma Client (v6.10.1) to ./build in 222ms
$ cd build/
$ ls
client.d.ts default.d.ts edge.d.ts index-browser.js index.js package.json schema.prisma wasm.js
client.js default.js edge.js index.d.ts libquery_engine-debian-openssl-3.0.x.so.node runtime wasm.d.ts
build
$ yarn link
yarn link v1.22.22
success Registered "prisma-client-9c30d2139563302f94cb830531764488cccf72fda868b2d7c729e640016f7629".
info You can now run `yarn link "prisma-client-9c30d2139563302f94cb830531764488cccf72fda868b2d7c729e640016f7629"` in the projects where you want to use this package and it will be used instead.
package.json
name
prisma-client-<ハッシュID>
//...
"paths": {
"prisma_client": [
"prisma-client-9c30d2139563302f94cb830531764488cccf72fda868b2d7c729e640016f7629"
]
}
//...
$ yarn link prisma-client-9c30d2139563302f94cb830531764488cccf72fda868b2d7c729e640016f7629
yarn link v1.22.22
success Using linked package for "prisma-client-9c30d2139563302f94cb830531764488cccf72fda868b2d7c729e640016f7629".
angular.json
//...
"externalDependencies": [
"prisma_client"
],
//...
prisma-client-<ハッシュID>
まとめ
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー