wheatjs/vite-plugin-vue-type-imports

Error importing types with combining with Storybook Build

TylerOliver opened this issue · 20 comments

The plugin does not appear to be functioning when using the ViteFinal overrides from Storybook. See minimal reproduction repo

https://github.com/TylerOliver/vite-plugin-vue-type-imports-reproduction

Important reference files are

.storybook/main.ts
src/components/*

Here's the error in the console:

3:48:27 PM [vite] Internal server error: [@vue/compiler-sfc] type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type.

/home/tyler/work/ts-repro-project/src/components/Button.vue
14 |    //     (e: 'click'): void;
15 |    // }
16 |    const props = defineProps<ButtonProps>()
   |                              ^^^^^^^^^^^
17 |    const emit = defineEmits<ButtonEmits>()
18 |  
  Plugin: vite:vue
  File: /home/tyler/work/ts-repro-project/src/components/Button.vue
      at error (/home/tyler/work/ts-repro-project/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:3426:15)
      at processDefineProps (/home/tyler/work/ts-repro-project/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:3462:17)
      at Object.compileScript (/home/tyler/work/ts-repro-project/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:3907:43)
      at resolveScript (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4295:23)
      at genScriptCode (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4567:18)
      at transformMain (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4467:43)
      at TransformContext.transform (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4821:16)
      at Object.transform (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/server/pluginContainer.ts:509:43)
      at doTransform (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/server/transformRequest.ts:160:27)
3:48:42 PM [vite] page reload src/components/Button.vue
3:48:43 PM [vite] Internal server error: [@vue/compiler-sfc] type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type.

/home/tyler/work/ts-repro-project/src/components/Button.vue
14 |    //     (e: 'click'): void;
15 |    // }
16 |    const props = defineProps<ButtonProps>()
   |                              ^^^^^^^^^^^
17 |    const emit = defineEmits<ButtonEmits>()
18 |  
  Plugin: vite:vue
  File: /home/tyler/work/ts-repro-project/src/components/Button.vue
      at error (/home/tyler/work/ts-repro-project/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:3426:15)
      at processDefineProps (/home/tyler/work/ts-repro-project/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:3462:17)
      at Object.compileScript (/home/tyler/work/ts-repro-project/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:3907:43)
      at resolveScript (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4295:23)
      at genScriptCode (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4567:18)
      at transformMain (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4467:43)
      at TransformContext.transform (/home/tyler/work/ts-repro-project/node_modules/@vitejs/plugin-vue/dist/index.js:4821:16)
      at Object.transform (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/server/pluginContainer.ts:509:43)
      at doTransform (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/server/transformRequest.ts:160:27)

Realized I had implemented my config slightly incorrectly, now getting the following error:

ERR! SyntaxError: Unexpected token ] in JSON at position 291
ERR!     at JSON.parse (<anonymous>)
ERR!     at Object.config (/home/tyler/work/ts-repro-project/node_modules/vite-plugin-vue-type-imports/dist/index.js:127:29)
ERR!     at resolveConfig (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/config.ts:307:19)
ERR!     at createServer (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/server/index.ts:323:18)
ERR!     at Object.start (/home/tyler/work/ts-repro-project/node_modules/storybook-builder-vite/index.js:33:20)
ERR!     at async Promise.all (index 0)
ERR!     at storybookDevServer (/home/tyler/work/ts-repro-project/node_modules/@storybook/core-server/dist/cjs/dev-server.js:126:28)
ERR!     at buildDevStandalone (/home/tyler/work/ts-repro-project/node_modules/@storybook/core-server/dist/cjs/build-dev.js:115:31)
ERR!     at buildDev (/home/tyler/work/ts-repro-project/node_modules/@storybook/core-server/dist/cjs/build-dev.js:161:5)
ERR!  SyntaxError: Unexpected token ] in JSON at position 291
ERR!     at JSON.parse (<anonymous>)
ERR!     at Object.config (/home/tyler/work/ts-repro-project/node_modules/vite-plugin-vue-type-imports/dist/index.js:127:29)
ERR!     at resolveConfig (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/config.ts:307:19)
ERR!     at createServer (/home/tyler/work/ts-repro-project/node_modules/vite/src/node/server/index.ts:323:18)
ERR!     at Object.start (/home/tyler/work/ts-repro-project/node_modules/storybook-builder-vite/index.js:33:20)
ERR!     at async Promise.all (index 0)
ERR!     at storybookDevServer (/home/tyler/work/ts-repro-project/node_modules/@storybook/core-server/dist/cjs/dev-server.js:126:28)
ERR!     at buildDevStandalone (/home/tyler/work/ts-repro-project/node_modules/@storybook/core-server/dist/cjs/build-dev.js:115:31)
ERR!     at buildDev (/home/tyler/work/ts-repro-project/node_modules/@storybook/core-server/dist/cjs/build-dev.js:161:5)

Ohh, yeah I know what's going on. I'll get a fix out by tonight, thanks for reporting this!

That's great to hear! I can't wait!

Sorry for the delay, can you try installing the latest version and see if that works for you @TylerOliver

@wheatjs Hello, I am working with @TylerOliver. When we try to run storybook with the 0.1.2 version of the plugin we get the following error:

3:23:30 PM [vite] Failed to load source map for /node_modules/.vite/@mdx-js_react.js?v=d9c7d837.
3:23:30 PM [vite] Failed to load source map for /node_modules/.vite/@storybook_addon-docs.js?v=d9c7d837.
3:23:40 PM [vite] ✨ dependencies updated, reloading page...
3:23:50 PM [vite] Internal server error: [@vue/compiler-sfc] `defineProps()` in <script setup> cannot reference locally declared variables because it will be hoisted outside of the setup() function. If your component options require initialization in the module scope, use a separate normal <script> to export the options instead.

C:/Users/chris/Documents/Repositories/component-library/src/components/Button/Button.vue
31 |    const props = withDefaults(defineProps<ButtonProps>(), {
32 |      ariaLabel: "",
33 |      type: BUTTON_TYPES.primary,
   |            ^^^^^^^^^^^^
34 |      color: COLORS.primary,
35 |      buttonText: "",
  Plugin: vite:vue
  File: C:/Users/chris/Documents/Repositories/component-library/src/components/Button/Button.vue
      at error (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vue\compiler-sfc\dist\compiler-sfc.cjs.js:3426:15)
      at C:\Users\chris\Documents\Repositories\component-library\node_modules\@vue\compiler-sfc\dist\compiler-sfc.cjs.js:3607:17
      at Object.enter (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vue\compiler-core\dist\compiler-core.cjs.js:3025:21)
      at SyncWalker.visit (C:\Users\chris\Documents\Repositories\component-library\node_modules\estree-walker\dist\umd\estree-walker.js:116:17)
      at SyncWalker.visit (C:\Users\chris\Documents\Repositories\component-library\node_modules\estree-walker\dist\umd\estree-walker.js:153:12)
      at SyncWalker.visit (C:\Users\chris\Documents\Repositories\component-library\node_modules\estree-walker\dist\umd\estree-walker.js:153:12)
      at SyncWalker.visit (C:\Users\chris\Documents\Repositories\component-library\node_modules\estree-walker\dist\umd\estree-walker.js:146:19)
      at Object.walk (C:\Users\chris\Documents\Repositories\component-library\node_modules\estree-walker\dist\umd\estree-walker.js:322:19)
      at Object.walkIdentifiers (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vue\compiler-core\dist\compiler-core.cjs.js:3011:18)
      at checkInvalidScopeReference (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vue\compiler-sfc\dist\compiler-sfc.cjs.js:3605:21)
      at Object.compileScript (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vue\compiler-sfc\dist\compiler-sfc.cjs.js:3999:5)
      at resolveScript (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vitejs\plugin-vue\dist\index.js:4295:23)
      at genScriptCode (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vitejs\plugin-vue\dist\index.js:4567:18)
      at transformMain (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vitejs\plugin-vue\dist\index.js:4467:43)
      at TransformContext.transform (C:\Users\chris\Documents\Repositories\component-library\node_modules\@vitejs\plugin-vue\dist\index.js:4821:16)
      at Object.transform (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite\src\node\server\pluginContainer.ts:509:43)
3:23:51 PM [vite] Internal server error: Cannot read property 'value' of null
  Plugin: vite-plugin-vue-type-imports
  File: C:/Users/chris/Documents/Repositories/component-library/src/components/AlertModal/AlertModal.vue
      at addExport (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite-plugin-vue-type-imports\dist\index.js:26032:29)
      at getAvailableExportsFromAst (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite-plugin-vue-type-imports\dist\index.js:26039:7)
      at extractTypesFromSource (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite-plugin-vue-type-imports\dist\index.js:26126:59)
      at C:\Users\chris\Documents\Repositories\component-library\node_modules\vite-plugin-vue-type-imports\dist\index.js:26224:22
      at async Promise.all (index 1)
      at transform (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite-plugin-vue-type-imports\dist\index.js:26219:26)
      at TransformContext.transform (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite-plugin-vue-type-imports\dist\index.js:26281:15)
      at Object.transform (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite\src\node\server\pluginContainer.ts:509:20)
      at doTransform (C:\Users\chris\Documents\Repositories\component-library\node_modules\vite\src\node\server\transformRequest.ts:160:27)

In case it helps, here is the storybook main.ts:

import { resolve } from "path";
import VueTypeImports from "vite-plugin-vue-type-imports";

module.exports = {
  "stories": [
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-actions",
    "@storybook/addon-links",
    "@storybook/addon-essentials"
  ],
  "framework": "@storybook/vue3",
  "core": {
    "builder": "storybook-builder-vite"
  },
  async viteFinal(config, { configType }) {
    return {
      ...config,
      resolve: {
        alias: {
          "@": `${resolve(__dirname, "../src")}`,
          vue: "vue/dist/vue.esm-bundler.js",
        },
      },
      plugins: [
        ...config.plugins,
        VueTypeImports(),
      ]
    }
  }
}

Let me know if there is anything else I can provide to help with this.
Thank you for your help!

Can you provide a minimal reproduction for this?

The minimal reproduction is the same with updated package dependencies. I'll push up the package update
https://github.com/TylerOliver/vite-plugin-vue-type-imports-reproduction

On second look it does work in the minimum reproduction, but not in ours. I'll have to investigate further to see what additional dependencies could be causing the issue.

@TylerOliver did you ever get this working? I have the exact same issue as you (using storybook-vite + vue 3)

@spacedawwwg @wheatjs I never figured out what was missing; we ended up abandoning Vue 3 until Vuetify releases fully on Vue 3

I use this plugin nicely with storybook.

const VueJsx = require("@vitejs/plugin-vue-jsx")
const VueTypeImports = require('vite-plugin-vue-type-imports')

module.exports = {
  framework: "@storybook/vue3",
  ...,
  viteFinal: async (config) => {
    config.plugins.push(VueJsx(), VueTypeImports['default']())
    return config;
  },
}

I bumped into some issue with es6 import, so I turned to use require

@mockingjet I followed the same as above, but get this:
image

10:22:13 [vite] Internal server error: Cannot read properties of null (reading 'value')
  Plugin: vite-plugin-vue-type-imports
  File: /Path/project-name/packages/core/components/src/UolExample/UolExample.vue
      at addExport (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26036:29)
      at getAvailableExportsFromAst (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26043:7)
      at extractTypesFromSource (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26130:59)
      at async /Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26228:22
      at async Promise.all (index 0)
      at async transform (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26223:26)
      at async TransformContext.transform (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26285:15)
      at async Object.transform (/Path/project-name/node_modules/vite/dist/node/chunks/dep-f5552faa.js:36985:30)
      at async doTransform (/Path/project-name/node_modules/vite/dist/node/chunks/dep-f5552faa.js:52060:29)

@mockingjet I followed the same as above, but get this: image

10:22:13 [vite] Internal server error: Cannot read properties of null (reading 'value')
  Plugin: vite-plugin-vue-type-imports
  File: /Path/project-name/packages/core/components/src/UolExample/UolExample.vue
      at addExport (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26036:29)
      at getAvailableExportsFromAst (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26043:7)
      at extractTypesFromSource (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26130:59)
      at async /Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26228:22
      at async Promise.all (index 0)
      at async transform (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26223:26)
      at async TransformContext.transform (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26285:15)
      at async Object.transform (/Path/project-name/node_modules/vite/dist/node/chunks/dep-f5552faa.js:36985:30)
      at async doTransform (/Path/project-name/node_modules/vite/dist/node/chunks/dep-f5552faa.js:52060:29)

me too , I try the way as above ,I dont get error like your, but still :

[vite] Internal server error: [@vue/compiler-sfc] type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type.

maybe it is a mistake to use storybook/vite-builder in my project...

If anyone is able to provide a reproduction I can attempt to fix this. Otherwise I can't really do anything

If anyone is able to provide a reproduction I can attempt to fix this. Otherwise I can't really do anything

https://github.com/Nauxscript/unuseless-ui/tree/test
that's a my test project, run pnpm run storybook will be throw the error:

[vite] Internal server error: [@vue/compiler-sfc] type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type.

image

my repo is init by this template https://github.com/antfu/vitesse-lite and add the storybook (vite version) by command:

npx sb init --builder storybook-builder-vite

hope it help, thank u !

Zolyn commented

@mockingjet I followed the same as above, but get this: image

10:22:13 [vite] Internal server error: Cannot read properties of null (reading 'value')
  Plugin: vite-plugin-vue-type-imports
  File: /Path/project-name/packages/core/components/src/UolExample/UolExample.vue
      at addExport (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26036:29)
      at getAvailableExportsFromAst (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26043:7)
      at extractTypesFromSource (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26130:59)
      at async /Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26228:22
      at async Promise.all (index 0)
      at async transform (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26223:26)
      at async TransformContext.transform (/Path/project-name/node_modules/vite-plugin-vue-type-imports/dist/index.js:26285:15)
      at async Object.transform (/Path/project-name/node_modules/vite/dist/node/chunks/dep-f5552faa.js:36985:30)
      at async doTransform (/Path/project-name/node_modules/vite/dist/node/chunks/dep-f5552faa.js:52060:29)

path: node.source!.value,

The property node.source will be null unless we use export { xx } from 'xx' syntax.
To solve this problem, we need to add a condition to filter.

export type MaybeNode = Node | null | undefined;

export type ExportNamedFromDeclaration = ExportNamedDeclaration & { source: StringLiteral };

/**
 * get reExported fields
 *
 * e.g. export { x } from './xxx'
 */
export function getAvailableExportsFromAst(ast: Program) {
    const exports: IImport[] = [];


    const addExport = (node: ExportNamedFromDeclaration) => {
        for (const specifier of node.specifiers) {
            if (specifier.type === 'ExportSpecifier' && specifier.exported.type === 'Identifier') {
                exports.push({
                    start: specifier.exported.start!,
                    end: specifier.local.end!,
                    imported: specifier.exported.name,
                    local: specifier.local.name,
                    path: node.source.value,
                });
            }
        }
    };


    for (const node of ast.body) {
        // TODO: support export * from
        if (isExportNamedFromDeclaration(node)) addExport(node);
    }


    return exports;
}

export function isExportNamedFromDeclaration(node: MaybeNode): node is ExportNamedFromDeclaration {
    return !!(node && node.type === 'ExportNamedDeclaration' && node.source);
}

The code above is from zolyn/vite-plugin-vue-type-imports , which is one of forks of this project and supports extended interfaces.

For a temporary solution, you can use this fork until @wheatjs fixes it.

@Zolyn your fix looks good! Would you mind making a PR so you can be listed as a contributor to the project?

Zolyn commented

@Zolyn your fix looks good! Would you mind making a PR so you can be listed as a contributor to the project?

I'd love to! I will make a PR later. (But now I have to go to sleep. :P)

Sorry, I came late.

I don't know the implementation details and also not sure if there are bugs. Share my .storybook/main.js here

const path = require("path");
const VueJsx = require("@vitejs/plugin-vue-jsx");
const VueTypeImports = require("vite-plugin-vue-type-imports");

module.exports = {
  stories: ["../stories/**/*.stories.*", "../src/**/*.stories.*"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-storysource",
  ],
  framework: "@storybook/vue3",
  core: {
    builder: "@storybook/builder-vite",
  },
  viteFinal: async (config) => {
    config.plugins.push(VueJsx(), VueTypeImports["default"]());
    config.resolve.alias = {
      ...config.resolve.alias,
      "~": path.resolve(__dirname, "../"),
      "@": path.resolve(__dirname, "../src"),
    };
    return config;
  },
};

And I use "yarn" to install these dependencies

//package.json

"dependencies": {
    ...
    "vue": "^3.2.31"
},
"devDependencies": {
    ...
    "@storybook/addon-actions": "^6.4.21",
    "@storybook/addon-essentials": "^6.4.21",
    "@storybook/addon-interactions": "^6.4.21",
    "@storybook/addon-links": "^6.4.21",
    "@storybook/addon-storysource": "^6.4.21",
    "@storybook/addons": "^6.4.21",
    "@storybook/builder-vite": "^0.1.28",
    "@storybook/testing-library": "^0.0.9",
    "@storybook/theming": "^6.4.21",
    "@storybook/vue3": "^6.4.21",
    "@vitejs/plugin-vue": "^2.2.2",
    "@vitejs/plugin-vue-jsx": "^1.3.7",
    "vite": "^2.8.4",
    "vite-plugin-vue-type-imports": "^0.1.3",
    "vue-loader": "^16.8.3",
    "vue-tsc": "^0
}
Zolyn commented

Fixed in v0.2.0