Storybook: Vue: Add Vue3 support

Created on 5 May 2020  ·  61Comments  ·  Source: storybookjs/storybook

I just tried to run storybook with a Vue3 (beta) app and got some errors… A few I was able to work-around merging our Webpack config and pushing the Vue3 loader plugin:

const wltConfig = require('../apps/webpack-dev');
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
    stories: ['../**/*.stories.[tj]s'],

    webpackFinal: (config, ...args) => {
        config.plugins.push(new VueLoaderPlugin());
        return { ...config, module: { ...config.module, rules: wltConfig().module.rules } };
    }
};

I still get a warning and an error in the shell:

WARN   Failed to load preset: "/home/tobi/Projects/modul/portal/client/node_modules/@storybook/vue/dist/server/framework-preset-vue.js"
ERR! Error: Cannot find module 'vue-loader/lib/plugin'

– nevertheless storybook builds and opens the browser. There I am stuck with this error message:

Uncaught TypeError: _vue.default is not a constructor
    at Object../node_modules/@storybook/vue/dist/client/preview/render.js (render.js:43)
    at __webpack_require__ (bootstrap:848)
    at fn (bootstrap:150)
    at Object../node_modules/@storybook/vue/dist/client/preview/index.js (index.js:24)
    at __webpack_require__ (bootstrap:848)
    at fn (bootstrap:150)
    at Object.<anonymous> (index.js:55)
    at Object../node_modules/@storybook/vue/dist/client/index.js (index.js:59)
    at __webpack_require__ (bootstrap:848)
    at fn (bootstrap:150)

Is there a better approach than this? I am a total n00b to storybook so would be glad about any pointer or assistance. (I searched the issues for vue3 without any meaningful results, at least as far as I can tell.)

P1 vue feature request help wanted todo

Most helpful comment

Yes, hopefully it will land in 6.2. still looking for somebody to make it happen!

All 61 comments

Automention: Hey @backbone87 @pocka, you've been tagged! Can you give a hand here?

Hmm.. We might need to do a vue3 preset

Hmm.. We might need to do a vue3 preset

can i help?

what i tried so far (only in dist files located in the node modules directory, though):

vue/dist/server/framework-preset.js

  • VueLoaderPlugin is now an export of vue-loader
  • replace vue-esm.js with vue.esm-browser.js
11c11
< var _plugin = _interopRequireDefault(require("vue-loader/lib/plugin"));
---
> var _plugin = _interopRequireDefault(require("vue-loader").VueLoaderPlugin);
34c34
<         vue$: require.resolve('vue/dist/vue.esm.js')
---
>         vue$: require.resolve('vue/dist/vue.esm-browser.js')

vue/dist/client/preview/render.js

app component is now instantiated with createApp(), all configuration etc. needs to be applied to the instance

```diff
21c21

< var _vue = _interopRequireDefault(require("vue"));

var _vue = _interopRequireDefault(require("vue").createApp);
43c43

< var root = new _vue["default"]({

var root = _vue["default"]({
67c67

< _vue["default"].config.errorHandler = showException;

root.config.errorHandler = showException;
88c88

< root.$mount('#root');

root.mount('#root');

```

i am now stuck with vue/dist/client/preview/index.js because the app instance is needed there, e.g. to define the extends property – and that seems only feasible to implement with a proper storybook build…

Screenshot-2020-05-11-10:41:14

hopefully these baby steps are of some use.

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

bump

@pksunkara @graup @Aaron-Pool does anybody have time to dig into this? if there are breaking changes we need and we can get those into 6.0, now would be the best time to do it!

We would still need to support Vue2 for quite a while after Vue3 is released. One thing we need to check is if we can somehow support both of them at the same time.

Also considering that Vue3 is not yet out of beta, and supposing that we want to get storybook v6 out, I would postpone the vue3 support to be after the v6 release

I'm planning to look into this soon, but can't give an ETA. Haven't had a chance to try Vue 3 yet.

I agree with @pksunkara that this isn't urgent for 6.0 as it's still beta anyway.

Thanks @graup. I also agree it isn't urgent -- we shouldn't be expected to support unreleased software in Storybook. My only concern is that, for example, we release 6.0 in July, Vue3 launches in August, we go to support it in September, and find that there's a breaking change required. And we can't get that breaking change in without a major version bump in October, which should be happening in June 2021 instead.

I was just trying to get some lights on the discord channel just now on how do I go to attempt to make it work with Vue 3, it would require a new preset as the logic to bootstrap the framework is a bit different.. I dont think the current code in the vue folder will work with vue 3..

I understand @shilman. Let me clarify a bit more since it looks I didn't get my point across correctly.

From what I understand with @p3k's attempts and @milewski's comment, we not only need a new preset but we also need to do breaking changes in the @storybook/vue package.

But we would still need to support Vue v2 for quite a while, not everyone would be moving to Vue v3. So, unless we want to say that Vue v2 is not supported anymore, it would be better if we create a new @storybook/vue3 package.

But if we do decide to cut off Vue v2 support, then yes, I agree that we should probably do breaking changes before Storybook v6.

@pksunkara Your proposed solution sounds great. 💯

I don't think we can cut off vue2 support anytime soon, so we would want to run those two packages in parallel, and maybe make a full cut-over in some future major release (7.0? 8.0? never?). After the two packages are released we can use npm download stats to determine when is the right time to remove Vue2 support. WDYT?

cc @ndelangen

I gave it a shoot: https://github.com/milewski/storybook/tree/vue3 this is essentially working for me with vue3 ..

however, there was a block of code that I'm unsure what it was supposed to do https://github.com/milewski/storybook/blob/vue3/app/vue/src/client/preview/index.ts#L41-L58 I haven't actually used storybook ever before.. I just wanted to start using it now with my vue3 project..

so as far as I can tell https://storybook.js.org/docs/guides/guide-vue/ following the instruction on this guide I got my component using vue 3 rendered successfully... without that piece of code I left off... Perhaps it is needed to work with some specific plugin? can someone tell me with which config/addon/plugin that code would be useful for? so I can find a way to fix that and someone can get some inspiration on my version and properly follow the code procedures to release a new preset in here?

Great work @milewski -- super exciting!!! 🚀

I figured out what that code did.. it was necessary to apply the options given from knobs .. i have fixed that .. can you try it out as it seems you have been using storybook for longer? @p3k

You can install it by running:

git clone --branch vue3 https://github.com/milewski/storybook.git
cd storybook
yarn bootstrap --core
yarn build (select vue)
cd app/vue
yarn link

then cd to your project and:

yarn link @storybook/vue

thanks a lot for your efforts @milewski – i am just trying out your branch and got an error when running yarn bootstrap --core:

…
$ node ../../scripts/prepare.js
TSFILE: /home/tobi/Projects/modul/storybook/app/mithril/dist/src/client/preview/globals.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/mithril/dist/src/client/preview/types.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/mithril/dist/src/client/preview/render.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/mithril/dist/src/client/preview/index.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/mithril/dist/src/client/index.d.ts
Built: @storybook/[email protected]
lerna ERR! yarn run prepare exited 1 in '@storybook/vue'
lerna ERR! yarn run prepare stdout:
$ node ../../scripts/prepare.js
src/server/framework-preset-vue.ts(5,17): error TS4058: Return type of exported function has or is using name 'VueLoaderPlugin' from external module "/home/tobi/Projects/modul/storybook/app/vue/node_modules/vue-loader/dist/plugin" but cannot be named.
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/client/preview/globals.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/client/preview/types.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/client/preview/render.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/client/preview/util.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/client/preview/index.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/client/index.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/server/options.d.ts
TSFILE: /home/tobi/Projects/modul/storybook/app/vue/dist/server/build.d.ts
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

lerna ERR! yarn run prepare stderr:
ERR! FAILED (ts) :  
ERR! FAILED to compile ts: @storybook/[email protected] 
error Command failed with exit code 1.

lerna ERR! yarn run prepare exited 1 in '@storybook/vue'
lerna WARN complete Waiting for 3 child processes to exit. CTRL-C to exit immediately.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Uhm. There was an issue with typescript. I just disabled the ts checking for now.. pull the latest code from my branch and try again

yes, now the command ran without errors.

re yarn build (select vue) i get the message _storybook WARN build Nothing to build!_ – is that correct?

No on the interactive menu that appears you need to press the space bar to select

image

ah! sorry, my bad, sure.

now it built fine and i can run storybook with my first vue3 component – splendid! thanks again, @milewski

@milewski Great work! Just tested and it seems to work.

As far as I can tell, the only big breaking changes are imports and the createApp stuff, right? Maybe it's possible to write backwards-compatible code that checks the installed vue version and does the right thing automatically? Then we could avoid having two versions of the preset.

I tried updating our vue examples but it seems that some of the stuff used there doesn't have vue3 versions yet. Generally there still seem to be a lot of beta and mismatched packages, so it might be better to wait a bit before trying to update the whole storybook codebase, including the addons etc etc. There'll be quite a lot of work to do.

As far as I can tell, the only big breaking changes are imports and the createApp stuff, right?

yes i would say so, too.

from the things i initially tried (see my initial comment) all i kept was the configuration merge – the push of the VueLoaderPlugin is not necessary, anymore, thanks to @milewski’s contribution, i assume :cat:

(re-)initializing storybook was straightforward as described in the docs: npm install @storybook/vue --save-dev; i did not even need to install any other peer dependencies (might be due to because we already install them for our project, anyway).

Then we could avoid having two versions of the preset.

i assume that would be very preferable, and maybe even make it possible to have the changes in the next storybook release…?

regarding the vue examples maybe i couldhelp creating vue3-compatible versions of (some of) them? (i am not a vue expert, yet, though.)

@graup

As far as I can tell, the only big breaking changes are imports and the createApp stuff, right? Maybe it's possible to write backwards-compatible code that checks the installed vue version and does the right thing automatically? Then we could avoid having two versions of the preset.

I faced issues with the reactivity too, I tried to follow the way the current version was setting/extending object but vue3 no longer tracks changes on that type of objects, specially the ones created inside the render function, I had to create references with ref() or reactive() for it to trigger updates..

I tried updating our vue examples but it seems that some of the stuff used there doesn't have vue3 versions yet. Generally there still seem to be a lot of beta and mismatched packages, so it might be better to wait a bit before trying to update the whole storybook codebase, including the addons etc etc. There'll be quite a lot of work to do.

I tried using that one as a starting point but it tried to install vue2 stuff even thou I had explicitly set the version on the packagejson ... vue 3 doesnt work at all if you have vue-template-compiler or the old vue loader installed .. there might have some dependencies on there that is importing thoses

@p3k

(re-)initializing storybook was straightforward as described in the docs: npm install @storybook/vue --save-dev; i did not even need to install any other peer dependencies (might be due to because we already install them for our project, anyway).

I think this happened because I included vue3 and vue-loader^16 as a dependency on the packages.json

I'd be fine with a @storybook/vue3 package if that's really needed.

FYI, I just fixed a core rendering bug in the Storybook Vue2 code: https://github.com/storybookjs/storybook/pull/11076

This causes the "force refresh behavior" used by addon-knobs and addon-controls to actually force a refresh. I'm not sure if it has any bearing on the Vue3 code, but just FYI if you're testing, please merge in that update.

Done also applied on the forked version!

Just to put in my two cents, it looks like vite will be the _defacto_ tooling used for vue 3, much like the vue-cli was used for vue 2. We had several users have issues with having to do all config setup twice when using vue-cli with storybook, a probalem @pksunkara did a great job of solving with his vue-cli storybook plugin. We should ensure whatever preset/package we setup works pretty seamlessly with vite, if possible.

Edit: I just realized that this could be tricky, because Vite uses rollup under the hood, rather than webpack 😬

I think I should really look into seeing if Storybook can just use the users webpack/build system and not need it's own config at all.

Thoughts aside, I think I haven't checked out vite, but maybe they will adapt the vue cli plugin system

We don't think or aim for Vite to become "the" tooling. A great number of projects will need the power and flexibility that webpack provides, and vite's goal is not to cater to all of these needs.

So I wouldn't worry too much about vite for now, and certainly not for the Vue3 support for storybook itself.

@LinusBorg the reason I specifically brought that up is that we often ran into a similar issue with Vue 2, where 90% of the community created their projects with vue-cli, and the fact that storybook couldn't detect and use a Vue-cli managed build system caused a substantial amount of confusion for Vue users.

Do you not see us running into a similar issue with vite as people try to integrate storybook into a vite based project?

not really, no. Vite itself is pretty bare-bones compared to a Vue CLI setup.

What Vite provides is covered by any simple Webpack config that has rules for handling .vue, ts(x) and .css files. And while it is extensible, that API is pretty close to the metal so we don't expect people adding custom transforms and stuff left and right.

It doesn't have an extensive plugin API by design. if people need fancy custom magic for their projects, chances are they will need Webpack anyway sooner than later, so go with Vue CLI.

Vite doesn't see "extensibility for any use case" as one of its goals.

So I would say that any Vite project should usually work with storybook/vue as long as its webpack config covers the basic rules that I laid out, which I think it does

@LinusBorg Ok, that makes sense. Thankful for the input 👍 Any guidance from the Core Vue team is always very appreciated!

Thanks for the work everyone is putting into storybook, can't wait to use it for my Vue 3 project :)

Since Vue3 is now in RC, it might be worthwhile reevaluating whether or not adding Vue3 support to v6 should be considered.

@hollandThomas we're already mid-RC so vue3 will have to come in 6.1. That said, we should be releasing the first 6.1 alphas in a few weeks so if anybody wants to start putting this together, I'm sure there is a large audience that's hungry for this!

Are there any active branches we can use or contribute to, to help with getting Vue 3 support ready?

In our org our Vue ui-component library touches all of our Vue projects, so it's one of the first things blocking from us trying out Vue 3, and we'd be eager to help test or migrate if needed. I would guess that others are in the same boat.

There's also now a v2 -> v3 migration guide in the docs https://v3.vuejs.org/guide/migration/introduction.html#overview

@milewski @graup @Aaron-Pool @elevatebart we're in 6.1-alpha now. anybody want to take a shot at a PR for this?

@p3k thanks. just created with your descriptions, for me looks like work, didn't test so much functionality
webpack config can be easily fixed in main.js like

webpackFinal: async (config, {configType}) => {

    config.resolve.alias['vue$'] = 'vue/dist/vue.esm-browser.js'

    return config
  }

and loader can be to

with render.js stuck a little bit how to configure in .storybook

@shilman is this version '6.1.0-alpha.1' is compatible with vue3 ?

not sure but looks like no. still second version supported..

Nope, not yet. I'm hoping somebody here will contribute it, per my comment above

@shilman I've still not had a chance to use Vue 3 yet 😞 My work has a deadline for a Vue 2 based product release this month, so I haven't had time to dabble.

So the tasks are basically

  • copy app/vue to app/vue3
  • make sure to modify all framework refs
  • apply changes done by @milewski in https://github.com/milewski/storybook/tree/vue3
  • modify or create new kitchensink examples
  • try different story / vue3 component definition method combinations and check if they work

?

@chartinger sounds like the most direct path to me. if we can figure out out how conditionally apply those changes based on the version of vue you're using and maintain a single package, that would be even better.

I did a view experiments in https://github.com/chartinger/storybook/tree/app-vue3 (needed some changes from the above fork) what i found so far:

Good:

  • Basic vue3 components will render
  • Changes from Controls are live updated

Bad:

  • Can't seem to get class-decorated vue components to load
  • No idea if knobs works, i wanted to learn storybook with vue3 so no demo code or past projects to test
  • No auto-detection of control-attributes from props

Other:

  • Importing the component in StoryMeta does nothing, has to be in the Story
  • Global components are now bound to the app instance, is it possible to provide it to the .storybook/preview.js or some other way? (is it needed?)

@elevatebart What's the status of vue-docgen-api for vue3? ☝️

It is overall compatible. But event emitting in the setup function is not dealt with yet.

For this, I still need a performant way to enter setup functions and detect those emits.

Since the functions can be in multiple files it might take a little time.

@chartinger want to update your branch with some of the experiments? i'd like to dig in on the "autodetection of control attributes" problem you found, and i can probably get somebody to look at the class-decorated issue.

@shilman I added a vue3 example, based on vue-cli and migrated the button example to composition and class api (i called it annotation in the code, which has to change but will do for now). Somehow the class api components loaded this time.

For testing don't forget to npm link and npm link @storybook/vue3 accordingly.

FYI: I just published @andoshin11/storybook-vue3 to npm, so feel free to try it out 👇

https://www.npmjs.com/package/@andoshin11/storybook-vue3

btw, Vue 3 is officially out of the beta.

PS. Thanks for your fork/version of storybook @andoshin11

//edit: just read the thread and great job guys.. I might take a shot at this :)

Awesome work everybody. I'd love to get this into the 6.1 release. Does anybody want to take this on? It will be a very high impact contribution. Ideally we support vue3 and vue2 in the same package, doing some autodetection or user configuration to figure out which version to use.

Scope of this work:

  • [ ] Making the necessary changes to support vue3
  • [ ] Adding e2e tests for vue3 a vue project (we already have a template for this, and it shouldn't be too hard)
  • [ ] Updating the documentation
  • [ ] Being available for bugfixes and support as we promote it in the prerelease

Please contact me on our discord if you'd like to work on this -- I've created a #vue3 temp channel to discuss! https://discord.com/invite/UUt2PJb

There is a little bit of work done at https://github.com/storybookjs/storybook/issues/12632. Noting it down here so that it doesn't get lost.

Since Vue 3 is out of beta and will be available in latest tag in couple of months, is there an ETA available for Vue 3 support in storybook?

Also, it would be helpful to add a CHANGELOG to @storybook/vue - https://github.com/storybookjs/storybook/tree/master/app/vue, so that we can get an idea on what changed with @storybook/vue versions.

@palerdot i'd love to get vue3 support shipped as part of storybook 6.1. looking for somebody to contribute this -- are you interested? https://github.com/storybookjs/storybook/issues/10654#issuecomment-698200547

as for the CHANGELOG, we have one for the entire monorepo and it's not realistic to maintain an additional one for each framework. however, i'll consider doing framework-specific summaries with each release announcement, which is probably what you actually want as a user.

@shilman

looking for somebody to contribute this -- are you interested?

Unfortunately, I will not be able to commit time on this currently (not to mention I'm not that familiar with storybook codebase).

i'll consider doing framework-specific summaries with each release announcement, which is probably what you actually want as a user.

Thank you. That would be better. You are correct. As a user I just want to know what framework is supported (like Vue 3 for instance) with every release. So, adding that info to the main CHANGELOG will be helpful.

Just dropping a data point that I would love to have Vue3 work with storybook as well. Maybe some of the Vue core/tooling developers could help here, like @Akryum ?

@shilman
I think i found the solution for working storybook with vue2 & vue3. I try to make a POC of it if i hopefully find the time for it ;-). No promise. ^^
But i thought i share my idea already.
I found Vue Demi that seems promising to solve the problem of using one package for vue2 & vue3.
Of course there is still the work to be done with compostion api. But i think with that package its one step forward to a promising package

13224 same problem. @shilman should we wait for Vue 3 support in the next Storybook version?

Yes, hopefully it will land in 6.2. still looking for somebody to make it happen!

Was this page helpful?
0 / 5 - 0 ratings