LoginSignup
14
12

More than 1 year has passed since last update.

Vue の Component はもう import しなくていい【Storybook 対応】

Last updated at Posted at 2022-10-23

はじめに

ユニークビジョン株式会社 では

  • Vue.js + Vite
  • Storybook + Vite

な環境でフロントエンドを開発しています。
開発していると、コンポーネントを手動で import する単純作業が何度も発生してしまいます。
面倒なので import しなくて済む方法を探しました。

unplugin-vue-components

有名な plugin です。
導入はドキュメント通りに

npm i unplugin-vue-components -D
vite.config.ts
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
     Components({ /* options */ }),
  ],
})

で完了です。

これで

App.vue
<template>
  <div>
    <HelloWorld msg="Hello Vue 3.0 + Vite" />
  </div>
</template>

<script>
import HelloWorld from './src/components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

App.vue
<template>
  <div>
    <HelloWorld msg="Hello Vue 3.0 + Vite" />
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

こう書けるようになります。

型を読み込ませる

しかしこのままでは VSCode 上で型が効かない状態になってしまいます。
そこで、dts: true として、

vite.config.ts
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
     Components({
       dts: true,
     })
  ],
})
npm run serve

すると
image.png

components.d.ts が生成されます。これを tsconfig.json で include に含めます。

tsconfig.json
{
  "include": [
    "components.d.ts"
  ]
}

これで型を読み込んでくれるようになります!
その後は npm run serve している間、コンポーネントを作成すると型定義 components.d.ts に自動追加してくれるようです。
このファイルは .gitignore に含めるのが良さそうです。

Storybook でも使えるようにする

このままでは Storybook では 「import していないコンポーネントは import していない」と見なされてしまい、何も表示されません。

そこで、下記のように設定します。

.storybook/main.js
+const Components = require('unplugin-vue-components/vite');

module.exports = {
  stories: ['../src/**/*.stories.ts'],
  addons: [
    '@storybook/addon-essentials',
    '@storybook/addon-links',
  ],
  framework: '@storybook/vue3',
  core: {
    builder: '@storybook/builder-vite',
  },
+  async viteFinal(config) {
+    config.plugins.push(Components({
+      dts: true,
+      dirs: [
+        'src/components'
+      ],
+    }))
+
+    return config;
+  },
};

Storybook から unplugin-vue-components を設定する場合は、上記のようにコンポーネントのディレクトリを明確にする必要があるようです。しかも ../src ではなく src を指定する必要があることになかなか気付けず結構ハマりました。

これで Vue.js と Storybook でコンポーネントを import しなくて済むようになりました!

アプリ本体と Storybook で設定ファイルを共有する

単純に unplugin-vue-components の設定を外部に切り出すことでファイルを共通化できます。

unplugin.config.js
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Components = require('unplugin-vue-components/vite');

module.exports = Components({
  dts: true,
});
vite.config.ts
import Components from './unplugin.config.js'

export default defineConfig({
  plugins: [
-     Components({
-       dts: true,
-     })
+     Components
  ],
})
.storybook/main.js
-const Components = require('unplugin-vue-components/vite');
+const Components = require('../unplugin.config');

module.exports = {
  stories: ['../src/**/*.stories.ts'],
  addons: [
    '@storybook/addon-essentials',
    '@storybook/addon-links',
  ],
  framework: '@storybook/vue3',
  core: {
    builder: '@storybook/builder-vite',
  },
  async viteFinal(config) {
-    config.plugins.push(Components({
-      dts: true,
-      dirs: [
-        'src/components'
-      ],
-    }))
+    config.plugins.push(Components)

    return config;
  },
};

注意点

デフォルトでは、src/components 以下のコンポーネントのみ自動 import されます。もし、src/pages などから import している場合は、dirs オプションに src/pages を追加してください。

unplugin.config.js
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Components = require('unplugin-vue-components/vite');

module.exports = Components({
  dts: true,
  dirs: [
    'src/components', // デフォルトで読み込まれるディレクトリ
    'src/pages', // コンポーネントが入っているパスを追加する
  ],
});

参考

おわりに

弊社での開発の話やフロントエンド周りのことを呟いています。よければフォローお願いします。

14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12