wheatjs / vite-plugin-vue-type-imports

Import types in Vue SFC for defineProps
223 stars 17 forks source link

Error importing types with combining with Storybook Build #4

Closed TylerOliver closed 2 years ago

TylerOliver commented 2 years ago

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)
TylerOliver commented 2 years ago

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)
wheatjs commented 2 years ago

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

TylerOliver commented 2 years ago

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

wheatjs commented 2 years ago

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

chrisjfoss commented 2 years ago

@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!

wheatjs commented 2 years ago

Can you provide a minimal reproduction for this?

TylerOliver commented 2 years ago

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

TylerOliver commented 2 years ago

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.

spacedawwwg commented 2 years ago

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

TylerOliver commented 2 years ago

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

mockingjet commented 2 years ago

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

spacedawwwg commented 2 years ago

@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)
Nauxscript commented 2 years ago

@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...

wheatjs commented 2 years ago

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

Nauxscript commented 2 years ago

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 2 years ago

@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)

https://github.com/wheatjs/vite-plugin-vue-type-imports/blob/1ad8b4c5efb9d6eb7ba2155ee97ac802d3886c63/src/core/ast.ts#L78 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.

wheatjs commented 2 years ago

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

Zolyn commented 2 years ago

@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)

mockingjet commented 2 years ago

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 2 years ago

Fixed in v0.2.0