先に結論
Vueのテンプレートタグ内で以下のようなインスタンスの初期化をしてはいけません。
<template>
<div v-for="booking in allBookingsByCategory(categoryId)" :key="`${booking.id}`">
<div class="patient-name">
<!-- 下記がNG -->
{{ new PatientNameService(booking).fullName }}
</div>
</div>
</template>
発生したエラーの詳細
本番環境にてClass constructor XXX cannot be invoked without 'new'
というエラーが発生しました。
原因
<template>
タグ内でインスタンスの初期化を行っている部分にて、エラーが発生していました。
冒頭にも挙げた下記のようなコードです。
<template>
<div v-for="booking in allBookingsByCategory(categoryId)" :key="`${booking.id}`">
<div class="patient-name">
<!-- 下記がNG -->
{{ new PatientNameService(booking).fullName }}
</div>
</div>
</template>
<script setup lang="ts">
/**
* 該当カテゴリから予約一覧を取得
* @param categoryId
*/
const allBookingsByCategory = (categoryId: string) => {
const slotCategory = props.categories[categoryId]
if (!slotCategory) return []
return slotCategory.bookings
}
</script>
対応
<template>
タグ内でインスタンスの初期化を行わないようにして、<script>
タグ内でインスタンスの初期化を行い、プロパティとして追加するようにしました。
<template>
<div v-for="booking in allBookingsByCategory(categoryId)" :key="`${booking.id}`">
<div class="patient-name">
<!-- 単純にプロパティにアクセスするように修正 -->
{{ booking.patientFullName }}
</div>
</div>
</template>
<script setup lang="ts">
/**
* 該当カテゴリから予約一覧を取得
* @param categoryId
*/
const allBookingsByCategory = (categoryId: string) => {
const slotCategory = props.categories[categoryId]
if (!slotCategory) return []
// ここで patientFullName を取得してプロパティとして追加する
return slotCategory.bookings.map((booking) => {
const patientFullName = new PatientNameService(booking).fullName
return { ...booking, patientFullName }
})
}
</script>
厄介だったこと
この問題は開発環境では発生しません⚠️
コンパイルされた成果物にてのみ発生します。
開発環境でうまく動いたのでと安心していると、いざビルドした成果物をデプロイした本番環境にて動かない、ということにもなり得るので注意が必要です。
明確な発生のメカニズムは分かっていませんが、ビルド時にminifyが走って<template>
タグ内でクラス名を見つけられない、というようなことが起きているのではと推測しています。
参照