小举人 マニュアル

↑↓ で選択 Enter で開く Esc で閉じる

Vite関連プラグイン

普段使っている Vite プラグイン:auto-import、components、pages、layouts など。

約5分で読めます
このページの内容

普段の Vite 開発で使っているプラグインをまとめておきます。

#unplugin-auto-import

Vue 3 関連の API を自動インポートします。vue、vue-router、vue-i18n、@vueuse/head、@vueuse/core などからの自動インポートに対応しています。

動作イメージ

// 変更前
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)

// 変更後
const count = ref(0)
const doubled = computed(() => count.value * 2)

// 変更前
import { useState } from 'react'
export function Counter() {
  const [count, setCount] = useState(0)
  return <div>{count}</div>
}

// 変更後
export function Counter() {
  const [count, setCount] = useState(0)
  return <div>{count}</div>
}

インストール

npm i -D unplugin-auto-import

完全な設定

import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    AutoImport({
      imports: ['vue', 'vue-router', 'vue-i18n', '@vueuse/head', '@vueuse/core'],
      dts: 'src/auto-import.d.ts',
      // auto-import.d.ts の生成先は選べます(デフォルトはルートディレクトリ)。'src/auto-import.d.ts' に設定することをおすすめします
    }),
  ],
})

仕組み:コード補完のために、auto-imports.d.ts ファイルが自動生成されます。以下のような内容です。

// Generated by 'unplugin-auto-import'
// We suggest you to commit this file into source control
declare global {
  const ref: typeof import('vue')['ref']
  const reactive: typeof import('vue')['reactive']
  const computed: typeof import('vue')['computed']
  const createApp: typeof import('vue')['createApp']
  const watch: typeof import('vue')['watch']
  const customRef: typeof import('vue')['customRef']
  const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
}
export {}

caution 注意:ローカルインポートがないため、定義へのジャンプをすると、まず auto-imports.d.ts に飛び、そこから元の定義へ移動することになります。

#リアクティビティの糖衣構文

Reactivity Transform | Vue.js (vuejs.org)

$ref を使うと、利用時に .value が不要になります。以下はデモです。

import { $ref, $$ } from 'vue/macros' // $ref は vue/macros パッケージに含まれます

// bind ref as a variable
let count = $ref(0)

// assignments are reactive
count++

// get the actual ref
console.log($$(count)) // { value: 1 }
  • $() を使うと、リアクティブオブジェクトを分割代入でき、.value を書かずに済みます
  • $$() を使うと、元のリアクティブオブジェクトを取得できます

vite.config.ts に reactivityTransform: true を追加します

plugins: [
  vue({
    reactivityTransform: true,
  }),
]

unplugin-auto-import でインポートできる vue/macros を使えば、手動の import は不要です。

AutoImport({
  imports: ['vue/macros'],
  dts: true,
})

#unplugin-vue-components

UI ライブラリを必要に応じて自動インポートします。Element Plus や Ant Design Vue など、多くのコンポーネントライブラリがこの方式を推奨しています。

インストール

npm install unplugin-vue-components -D
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
import {
  ElementPlusResolver,
  AntDesignVueResolver,
  VantResolver,
  HeadlessUiResolver,
  ElementUiResolver
} from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    Components({
      // UI ライブラリのリゾルバー。独自に定義することもできます
      resolvers: [
        ElementPlusResolver(),
        AntDesignVueResolver(),
        VantResolver(),
        HeadlessUiResolver(),
        ElementUiResolver()
      ]
    })
  ]

プラグインは、UI ライブラリのコンポーネントとそのパスを記した components.d.ts ファイルを生成します。以下のような内容です。

// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/vue-next/pull/3399

declare module 'vue' {
  export interface GlobalComponents {
    ElAside: typeof import('element-plus/es')['ElAside']
    ElButton: typeof import('element-plus/es')['ElButton']
    ElContainer: typeof import('element-plus/es')['ElContainer']
    ElHeader: typeof import('element-plus/es')['ElHeader']
    ElIcon: typeof import('element-plus/es')['ElIcon']
    ElMain: typeof import('element-plus/es')['ElMain']
  }
}

export {}

一度使ったコンポーネントはすべて自動でインポートされ、自分で作ったコンポーネントもインポートできます。

import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    Components({
      // コンポーネントの場所を指定します。デフォルトは src/components
      dirs: ['src/components'],
      extensions: ['vue'],
      // 設定ファイルの生成先
      dts: 'src/components.d.ts',
    }),
  ],
})

#unplugin-vue-define-options/vite

script setup の糖衣構文で、defineOptions を使ってコンポーネントの name、inheritAttrs、props、emits を定義できます。

インストール

npm i unplugin-vue-define-options
import { defineConfig } from 'vite'
import DefineOptions from 'unplugin-vue-define-options/vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue(), DefineOptions()],
})

tsconfig.json で types を次のように設定します。

{
  "compilerOptions": {
    "types": ["unplugin-vue-define-options"]
  }
}

これを設定しないと、TS プロジェクトでは 「名前 'defineOptions' が見つかりません」 と表示されます。使い方は次のとおりです。

<script setup lang="ts">
import { useSlots } from 'vue'
defineOptions({
  name: 'Foo',
  inheritAttrs: false,
  props: {
    msg: { type: String, default: 'bar' },
  },
  emits: ['change', 'update'],
})
const slots = useSlots()
</script>

出力

<script lang="ts">
export default {
  name: 'Foo',
  inheritAttrs: false,
  props: {
    msg: { type: String, default: 'bar' },
  },
  emits: ['change', 'update'],
}
</script>

<script setup>
const slots = useSlots()
</script>

コンポーネント名を設定するだけでよければ、vite-plugin-vue-setup-extend のほうが合っているかもしれません。script に name 属性を追加するだけで済みます。

<template>
  <div>hello world {{ a }}</div>
</template>

<script lang="ts" setup name="App">
const a = 1
</script>

#vite-plugin-mock

ローカルと本番環境で使えるモックサービスを提供します。

インストール

npm i mockjs vite-plugin-mock
import { UserConfigExport, ConfigEnv } from 'vite'

import { viteMockServe } from 'vite-plugin-mock'
import vue from '@vitejs/plugin-vue'

export default ({ command }: ConfigEnv): UserConfigExport => {
  return {
    plugins: [
      vue(),
      viteMockServe({
        // default
        mockPath: 'mock',
        localEnabled: command === 'serve',
      }),
    ],
  }
}

#vite-plugin-pages

ファイルシステムに基づく動的ルーティングです。

インストール

npm install -D vite-plugin-pages
npm install vue-router
import Pages from 'vite-plugin-pages'

export default {
  plugins: [
    Pages({
      dirs: 'src/views',
    }),
  ],
}

従来の routes の書き方

// 1. ルートコンポーネントを定義します。
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }

// 2. いくつかのルートを定義します
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]

// 3. ルーターインスタンスを作成し、`routes` オプションを渡します
const router = VueRouter.createRouter({
  routes,
})

このプラグインは、pages(views)配下のすべての vue ファイルをルートとして読み込みます。独自のルーティングルールがあり、nuxt.js に近い仕組みです。

import { createRouter } from 'vue-router'
import routes from '~pages'

const router = createRouter({
  // ...
  routes,
})

#vite-plugin-vue-layouts

vite-plugin-pages と組み合わせて使うと、生成されたページルートの上に動的なレイアウト機能を追加できます。

インストール

npm install -D vite-plugin-vue-layouts
import Vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'
import Layouts from 'vite-plugin-vue-layouts'

export default {
  plugins: [Vue(), Pages(), Layouts()],
}

対応するページの単一ファイルコンポーネントにレイアウトの設定を追加すると、ルーティング時にその設定に従ってレイアウトが切り替わり、ページが対応するレイアウトファイルの中に埋め込まれます。

<route lang="yaml">
meta:
  layout: users
</route>

#vite-plugin-purge-icons

Iconify のアイコンを手軽に使えます。

インストール

 pnpm add @iconify/iconify
 pnpm add vite-plugin-purge-icons @iconify/json -D
import PurgeIcons from 'vite-plugin-purge-icons'

export default {
  plugins: [
    PurgeIcons({
      /* PurgeIcons Options */
    }),
  ],
}

main.js で @purge-icons/generated をインポートします

import { createApp } from 'vue'
import App from './App.vue'

import '@iconify/iconify'
import '@purge-icons/generated'

createApp(App).mount('#app')

使い方

HTML ファイルで、class に iconify、data-icon に Iconify の対応アイコンを指定します(公式サイトからそのままコピーできます)。

<span class="iconify" data-icon="system-uicons:browser-alt" data-inline="false" />

もちろん、自分で Icon コンポーネントを作って、次のように使うこともできます。

<Icon icon="ion:settings-outline" :size="30" />

あるいは、Vue 3 版の Iconify for Vue を使うこともできます。

#vite-plugin-windicss

インストール

npm i -D vite-plugin-windicss windicss
import WindiCSS from 'vite-plugin-windicss'

export default {
  plugins: [WindiCSS()],
}

Windi CSS を使う主な理由は、属性化モード(attributify)がとても便利だからです(今後のトレンドになると思っています)。属性化はデフォルトでは任意機能で、windi の設定で有効にできます。

import { defineConfig } from 'windicss/helpers'

export default defineConfig({
  attributify: true,
})

必要に応じて、次のように使います。

<button bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600" text="sm white" font="mono light" p="y-2 x-4" border="2 rounded blue-200">Button</button>

構文

(variant[:-]{1})*key? = "((variant:)*value)*"

#vite-plugin-node

Vite を Node.js の開発サーバーとして使えるようにします。

まだ実際に試せていません。ただ、面白そうだと思っただけです。

#まとめ

しばらく Vite で開発していますが、開発体験にはとても満足しています。その理由の大部分は、上記のプラグインにあるのは間違いありません。今回は、いくつかのプロジェクトを見直して、これらのプラグインの使われ方を確認しました。ここでは、よく使うものだけをまとめました。その他のプラグインは awesome-vite で確認できます。

参考記事:

尤大推薦のツール unplugin-vue-components:手作業のインポートから解放される(コンポーネント、Element-ui などの UI ライブラリ、Vue hooks など)- 掘金 (juejin.cn)

Vite 2 よく使うプラグイン編(三)- 応用プラグイン - 掘金 (juejin.cn)

Vite の効率的なプラグインのおすすめ - 掘金 (juejin.cn)

vitejs/awesome-vite: ⚡️ A curated list of awesome things related to Vite.js (github.com)