unplugin-vue-markdownを使ったらデプロイ時エラーになった話
個人サイトで、ブログなど更新が続いていく機能については記事をmarkdownで書きたい一方、その中身を書くのを楽にするためにVue.jsの機能を使いたい!という時に使えるのがこのunplugin-vue-markdownというライブラリです。
このライブラリを使ったアプリをVercelで公開した際にビルドが失敗したので、その原因と解決方法を残しておきます。
症状
Expected ">" but found "class" のようなエラーがビルド時に表示される
dev環境ではエラーはない
原因
<script setup lang="ts"> のlang="ts" TypeScriptを使用していること
解決方法
普通の<script setup> にするか、<script setup lang="js">にする
雑記
このissueに全て書いてありました。
Vue.jsがTypeScriptを本格的にサポートし始めたのは3.3 からであり、Vue.jsの長い歴史の中で言うとつい2,3年前ということになります。このissueも1,2年前のものであり、重大な部類の問題であるにも関わらずまだ解決していない[1]ことから、Vue.jsでTypeScriptを使うにあたっての問題が浮上したなあという形です。
おまけ:unplugin-vue-markdownの活用事例
Zenn上にunplugin-vue-markdownの記事が一件もなかったので、実際どう使っているのかも紹介します。
Umadepthというグローバル版ウマ娘の個人ガイドを開いていて、その中のガイド本編の部分に使っています。ゲーム用語でいうとサポカの画像を出す部分
サポカの型定義
export type CardType = "speed" | "stamina" | "power" | "guts" | "wit" | "pals";
export type CardRarity = "ssr" | "sr" | "any";
const supportCardSpeedSSR = [サポカ名を列挙]
export type SupportCardSpeedSSRProps = {
type: "speed";
rarity: "ssr";
name: SupportCardSpeedSSR;
width?: number;
description?: string;
};
export type SupportCardProps =
| SupportCardSpeedSSRProps
| SupportCardSpeedSRProps
| SupportCardStaminaSSRProps
| SupportCardStaminaSRProps
| SupportCardPowerSSRProps
| SupportCardPowerSRProps
| SupportCardGutsSSRProps
| SupportCardGutsSRProps
| SupportCardWitSSRProps
| SupportCardWitSRProps
| SupportCardPalsProps
コンポーネント
<script setup lang="ts">
import { ref } from 'vue';
import type { SupportCardProps } from '@/types/supportCardType';
const props = withDefaults(
defineProps<SupportCardProps>(),
{
rarity: "ssr",
width: 100
}
);
const supportImagePath = `/images/supports/${props.type}/${props.rarity}/${props.name}.jpg`;
const fallbackImagePath = '/images/supports/Agemasen.jpg';
const currentImagePath = ref(supportImagePath);
const handleImageError = () => {
currentImagePath.value = fallbackImagePath;
};
</script>
<template>
<div :style="{ width: `${props.width}px` }">
<figure class="image">
<img :src="currentImagePath" :alt="props.name" @error="handleImageError" />
<figcaption v-if="props.description">{{ props.description }}</figcaption>
</figure>
</div>
</template>
mdの一部
### Deck
#### Core
<CardRow> // CardRowは画像を配置するFlexBoxみたいなコンポーネント
<SupportCard type="wit" rarity="ssr" name="Hoge Hoge" />
<SupportCard type="wit" rarity="ssr" name="Hoge Hoge" />
<SupportCard type="wit" rarity="ssr" name="Hoge Hoge" />
<SupportCard type="speed" rarity="ssr" name="Hoge Hoge" />
<SupportCard type="speed" rarity="ssr" name="Hoge Hoge" />
</CardRow>
Flexで表示したり、同じサイズの要素としてポンポン配置したい時にコンポーネントとして作った上でmd上に置けるのが便利です。
-
2025/09に最新リリースがあったり、Anthony Fuさんが関わっていることから死んでいるわけではないと思います ↩︎
Discussion