ReactやVueのuseStateやrefのimportは省略できる

useStateやrefのimportは省略できる

ReactやVueで開発していると、新しいコンポーネントを作るたびにファイルの先頭でuseStateやrefなどをimportする必要があります。

TypeScript
// React
import { useState, useEffect } from 'react'

// Vue
import { ref, onMounted } from 'vue'

こうした決まり文句の記述は、unplugin-auto-importというプラグインを導入することで省略可能です。

unplugin-auto-importとは?

ビルド時に指定したライブラリのAPI(useState、refなど)を解析し、明示的なimport文がなくても自動的にimport処理を行ってくれるビルドツール向けプラグインです。

Viteなど主要なビルドツールに対応しており、ReactとVue のどちらでも利用できます。

導入と設定方法

以下のコマンドでパッケージをインストールします。(ReactとVue共通)

npm i -D unplugin-auto-import

React(Vite)での設定

vite.config.tsにunplugin-auto-import/viteを追加し、importsにreactを指定します。

vite.config.ts
import { defineConfig } from 'vite'
import react, { reactCompilerPreset } from '@vitejs/plugin-react'
import babel from '@rolldown/plugin-babel'
import AutoImport from 'unplugin-auto-import/vite'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    babel({ presets: [reactCompilerPreset()] }),
    AutoImport({
      imports: ['react'],
      dts: 'src/auto-imports.d.ts'
    })
  ],
})

vite.config.tsの設定が完了すれば、以下のようにimportでuseStateを読み込まないコードでもエラーを出さずに画面を表示して処理できるようになります。

App.tsx
// import { useState, useEffect, memo } from 'react' を書く必要がない😃

function App() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    document.title = 'import省略テスト'
  }, [])

  return (
    <button
      onClick={() => setCount((count) => count + 1)}
    >
      Count is {count}
    </button>
  )
}

export default memo(App)

※ Vite + React + TypeScript + React Compiler の環境なのでmemoは記述不要だが、エラーにならないことを確認していただくために書いています。

Vue(Vite)での設定

vite.config.tsのimportsにvueを指定します。

VueとReactのAutoImportの設定は同じではないため、注意が必要です。

vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: [
        'vue',
        'vue-router',
        'pinia',
      ],
      dts: 'src/auto-imports.d.ts',
      eslintrc: {
        enabled: true,
      },
    }),
  ],
})

vite.config.tsの設定が完了すれば、以下のようにimportでrefなどを読み込まないコードでもエラーを出さずに画面を表示して処理できるようになります。

HelloWorld.vue
<script setup lang="ts">
// import { ref, onMounted } from 'vue' を書く必要がない😃

const count = ref(0)

onMounted(() => {
  document.title = 'importテスト'
})
</script>

<template>
  <button @click="count++">
    Count is {{ count }}
  </button>
</template>

特定のものだけ自動インポートする方法

Reactだとmemoだけは自動インポートの対象外にして明示的にimportさせたいケースがあります。(React.memoを使っているや、constで定義されているなど)

そのようなときは「imports: ['react'],」ではなく、以下のようにreact: [] に使用するフックなどを指定して、memoは指定しないようにします。

vite.config.ts
import { defineConfig } from 'vite'
import react, { reactCompilerPreset } from '@vitejs/plugin-react'
import babel from '@rolldown/plugin-babel'
import AutoImport from 'unplugin-auto-import/vite'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    babel({ presets: [reactCompilerPreset()] }),
    AutoImport({
      imports: [
        {
          react: [
            'useState',
            'useEffect',
            'useCallback',
            'useMemo',
            'useRef',
            'useContext',
            'useReducer',
            // 'memo' は自動インポートしない
          ],
        },
      ],
      dts: 'src/auto-imports.d.ts',
  ],
})

Vueもvue: []で同様に明示的に自動importするものを設定できます。

vite.config.ts
// 中略
AutoImport({
  imports: [
    {
      vue: [
        'ref',
        'reactive',
        'computed',
        'watch',
        'watchEffect',
        'onMounted',
        'onUnmounted',
        // 'nextTick' は自動インポートしない
        // 'provide' は自動インポートしない
        // 'inject' は自動インポートしない
      ],
    },
  ],
  dts: 'src/auto-imports.d.ts',
}),

まとめ

  • ReactやVueのuseStateやrefのimportはunplugin-auto-importで省略できる
  • 「npm i -D unplugin-auto-import」でインストールできる
  • vite.config.tsに設定することで自動インポートになる