storybookjs / builder-vite

A builder plugin to run and build Storybooks with Vite
MIT License
891 stars 107 forks source link

Vue3 Vite - Component is missing template or render function #138

Closed Kotoriii closed 2 years ago

Kotoriii commented 2 years ago

I have a fresh "@storybook/vue3": "6.4.0-beta.25" installation, where I removed the examples and tried adding an extremely basic story. The story appears in the sidebar, but the component is not rendering, and I get the following warning:

runtime-core.esm-bundler.js:6871 [Vue warn]: Component is missing template or render function. 

link.stories.js

import Link from '../app/javascript/my_app/components/Link.vue';

export default {
  title: 'My App/Link',
  component: Link,
};

export const Default = () => ({
  components: { Link },
  template: '<Link>More</Link>',
});

Link.vue

<template>
  <a v-bind="$props" class="text-blue-600">
    <slot></slot>
  </a>
</template>

main.js

const { resolve } = require('path');
const { loadConfigFromFile, mergeConfig } = require("vite");

module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials"
  ],
  "framework": "@storybook/vue3",
  "core": {
    "builder": "storybook-builder-vite"
  },
  async viteFinal(config, { configType }) {
    const { config: userConfig } = await loadConfigFromFile(
      resolve(__dirname, "../vite.config.js")
    );

    return mergeConfig(config, {
      ...userConfig,
      resolve: {
        alias: {
          ...userConfig.resolve.alias,
          vue: 'node_modules/vue3/dist/vue.esm-bundler.js'
        }
      }
    });
  },
}

vite.config.js

import { resolve } from 'path';
import { defineConfig } from 'vite';
import RubyPlugin from 'vite-plugin-ruby';
import vue from '@vitejs/plugin-vue';
import eslintPlugin from 'vite-plugin-eslint';

export default defineConfig({
  resolve: {
    alias: {
      vue: 'vue3',
      'vue-router': 'vue-router4',
      vuex: 'vuex4',
      '@': resolve(__dirname, 'app/javascript/my_app/'),
      assets: resolve(__dirname, 'app/javascript/assets'),
      'tailwind.config.js': resolve(__dirname, 'app/javascript/my_app/tailwind.config.js'),
    },
  },
  plugins: [RubyPlugin(), vue(), eslintPlugin()],
  css: {
    postcss: {
      plugins: [require('tailwindcss')('./app/javascript/my_app/tailwind.config.js')],
    },
  },
  optimizeDeps: {
    include: ['tailwind.config.js']
  },
});

Any ideas?

Kotoriii commented 2 years ago

The problem was the vue() plugin

IanVS commented 2 years ago

Glad you found the problem!

olemarius commented 2 years ago

@Kotoriii I'm stuck with the same problem, please share how you fixed it? :-)

IanVS commented 2 years ago

@olemarius you're just not having any luck, are you? :(

olemarius commented 2 years ago

@IanVS haha yea been struggling with getting things to work for a while now. At least I got it to work in a test repo, but getting it to work in a pretty complex set up saas application is a bit more tricky. But at least storybook starts now, only thing missing is the components actually being rendered.

olemarius commented 2 years ago

@IanVS finally got it working! Here's the repo.

https://github.com/olemarius/storybook-builder-vite-example-vue-in-isolation

Edit: Oops, made it Private first. Changed to Public now.

The error occurs when @vitejs/plugin-vue is added. I was importing my vite.config.ts file where I need the vue() plugin, but when I handled vite's config seperately in main.js it worked.

I also added some plugins and alias that I use in my project to make sure it work.

    async viteFinal(config) {
        config.resolve.alias['@'] = resolve(__dirname, '../src');
        config.plugins.push(WindiCSS());
        Icons({
            scale: 1,
            compiler: 'vue3',
            autoInstall: true
        });
        Components({
            dts: true,
            dirs: [
                'src/components',
                'src/pages/Orienteering/components'
            ],
            deep: true,
            resolvers: IconsResolver({
                componentPrefix: 'icon'
            }),
        });
        config.plugins.push(
            vueI18n({
                runtimeOnly: false,
                include: [
                    resolve(__dirname, './src/locales/**'),
                ]
            })
        );
        // enabling this will cause 'Component is missing template or render function' error
        // config.plugins.push(vue())

        return config;
    },