Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible with vue 3.0 #111

Closed
adambullmer opened this issue Sep 30, 2020 · 10 comments · Fixed by #119
Closed

Incompatible with vue 3.0 #111

adambullmer opened this issue Sep 30, 2020 · 10 comments · Fixed by #119

Comments

@adambullmer
Copy link

adambullmer commented Sep 30, 2020

Describe the bug

When using this plugin on a vue 3.0 based repo, the storybook build/serve commands fail due to the absence of the vue/dist/vue.esm.js file. I believe it has been renamed vue/dist/vue.esm-browser.js. Possibly, but not likely, this is because of yarn 2 (berry).

Steps to reproduce the behavior

  1. Scaffold new vue app vue create . and follow prompts selecting vue 3.0
  2. Add this plugin vue add storybook and use ^6.0.0 as the version
  3. yarn set version berry
  4. fix peer dependency outlined in Requiring unspecified peer dependency #110 (Manually add peer dependency to .yarnrc.yml)
  5. yarn install
  6. yarn storybook:build
  7. Observe error.

Expected behavior

I expect a default vue project, adding this plugin's generated code, and a build to succeed without failure.

Screenshots and/or logs

info 
info => Loading presets
info => Loading presets
info => Loading config/preview file in "config/storybook".
info => Adding stories defined in "config/storybook/main.js".
ERR! Error: Qualified path resolution failed - none of the candidates can be found on the disk.
ERR! 
ERR! Source path: /Users/adam/github/test-vue-3/.yarn/unplugged/vue-npm-3.0.0-6474504e0b/node_modules/vue/dist/vue.esm.js
ERR! Rejected candidate: /Users/adam/github/test-vue-3/.yarn/unplugged/vue-npm-3.0.0-6474504e0b/node_modules/vue/dist/vue.esm.js
ERR! Rejected candidate: /Users/adam/github/test-vue-3/.yarn/unplugged/vue-npm-3.0.0-6474504e0b/node_modules/vue/dist/vue.esm.js.js
ERR! Rejected candidate: /Users/adam/github/test-vue-3/.yarn/unplugged/vue-npm-3.0.0-6474504e0b/node_modules/vue/dist/vue.esm.js.json
ERR! Rejected candidate: /Users/adam/github/test-vue-3/.yarn/unplugged/vue-npm-3.0.0-6474504e0b/node_modules/vue/dist/vue.esm.js.node
ERR! 
ERR! Require stack:
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/vue-cli-plugin-storybook-virtual-dab0511f8d/0/cache/vue-cli-plugin-storybook-npm-1.3.0-5111490768-ff5ea2b87a.zip/node_modules/vue-cli-plugin-storybook/lib/preset.js
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/@storybook-core-virtual-239ad0cf3f/0/cache/@storybook-core-npm-6.0.22-db69c12efe-7f862c3c5f.zip/node_modules/@storybook/core/dist/server/presets.js
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/@storybook-core-virtual-239ad0cf3f/0/cache/@storybook-core-npm-6.0.22-db69c12efe-7f862c3c5f.zip/node_modules/@storybook/core/dist/server/config.js
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/@storybook-core-virtual-239ad0cf3f/0/cache/@storybook-core-npm-6.0.22-db69c12efe-7f862c3c5f.zip/node_modules/@storybook/core/dist/server/build-static.js
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/@storybook-core-virtual-239ad0cf3f/0/cache/@storybook-core-npm-6.0.22-db69c12efe-7f862c3c5f.zip/node_modules/@storybook/core/server.js
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/vue-cli-plugin-storybook-virtual-dab0511f8d/0/cache/vue-cli-plugin-storybook-npm-1.3.0-5111490768-ff5ea2b87a.zip/node_modules/vue-cli-plugin-storybook/lib/index.js
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/@vue-cli-service-virtual-81f54a6811/0/cache/@vue-cli-service-npm-4.5.6-7e8eb1fcab-c621385ec3.zip/node_modules/@vue/cli-service/lib/Service.js
ERR! - /Users/adam/github/test-vue-3/.yarn/$$virtual/@vue-cli-service-virtual-81f54a6811/0/cache/@vue-cli-service-npm-4.5.6-7e8eb1fcab-c621385ec3.zip/node_modules/@vue/cli-service/bin/vue-cli-service.js
ERR!     at internalTools_makeError (/Users/adam/github/test-vue-3/.pnp.js:26975:34)
ERR!     at resolveUnqualified (/Users/adam/github/test-vue-3/.pnp.js:28007:13)
ERR!     at resolveRequest (/Users/adam/github/test-vue-3/.pnp.js:28031:14)
ERR!     at Object.resolveRequest (/Users/adam/github/test-vue-3/.pnp.js:28091:26)
ERR!     at Function.external_module_.Module._resolveFilename (/Users/adam/github/test-vue-3/.pnp.js:27208:34)
ERR!     at Function.resolve (internal/modules/cjs/helpers.js:94:19)
ERR!     at Object.webpack (/Users/adam/github/test-vue-3/.yarn/$$virtual/vue-cli-plugin-storybook-virtual-dab0511f8d/0/cache/vue-cli-plugin-storybook-npm-1.3.0-5111490768-ff5ea2b87a.zip/node_modules/vue-cli-plugin-storybook/lib/preset.js:39:25)
ERR!     at /Users/adam/github/test-vue-3/.yarn/$$virtual/@storybook-core-virtual-239ad0cf3f/0/cache/@storybook-core-npm-6.0.22-db69c12efe-7f862c3c5f.zip/node_modules/@storybook/core/dist/server/presets.js:258:36
ERR!     at processTicksAndRejections (internal/process/task_queues.js:93:5)
ERR!     at async Promise.all (index 1)
ERR!     at async buildDevStandalone (/Users/adam/github/test-vue-3/.yarn/$$virtual/@storybook-core-virtual-239ad0cf3f/0/cache/@storybook-core-npm-6.0.22-db69c12efe-7f862c3c5f.zip/node_modules/@storybook/core/dist/server/build-dev.js:438:28)
ERR!     at async Object.buildDev (/Users/adam/github/test-vue-3/.yarn/$$virtual/@storybook-core-virtual-239ad0cf3f/0/cache/@storybook-core-npm-6.0.22-db69c12efe-7f862c3c5f.zip/node_modules/@storybook/core/dist/server/build-dev.js:520:3)

Environment

  • OS: OSX 10.15.7
  • Node.js version: v14.12.0
  • NPM version: yarn 2.2.2
  • Browser (if applicable): n/a
  • Browser version (if applicable): n/a
  • Device (if applicable): n/a

Additional context

#110 must be fixed if using yarn2

Example .yarnrc.yml

yarnPath: .yarn/releases/yarn-berry.js
packageExtensions:
  vue-cli-plugin-storybook@*:
    peerDependencies:
      "@storybook/core": "*"
@adambullmer adambullmer added the bug Something isn't working label Sep 30, 2020
@adambullmer
Copy link
Author

adambullmer commented Sep 30, 2020

In the interim, I've utilized yarn's patch capabilities to solve this for me:

First, Create file ./patches/vue-cli-plugin-storybook.patch

diff --git a/lib/preset.js b/lib/preset.js
index e5c85e120ce743d879044dfed9a77451eeabdaf1..ba340af5f10747ba4cf56bc4610942e9d69367f3 100644
--- a/lib/preset.js
+++ b/lib/preset.js
@@ -36,7 +36,7 @@ module.exports = {
         ...webpackConfig.resolve,
         alias: {
           ...webpackConfig.resolve && webpackConfig.resolve.alias,
-          vue$: require.resolve('vue/dist/vue.esm.js'),
+          vue$: require.resolve('vue/dist/vue.esm-browser.js'),
         },
       },
       resolveLoader: webpackConfig.resolveLoader,

Then tell yarn to use the patched version in your package.json

  "devDependencies": {
    // ...
    "vue-cli-plugin-storybook": "patch:vue-cli-plugin-storybook@~1.3.0#./patches/vue-cli-plugin-storybook.patch",
    // ...
  }

and lastly yarn install to apply the patch

@pksunkara
Copy link
Member

Is the patch working for you? I can't build storybook for my vue3 project even with npm. And vue3 is not exactly supported in storybook.

@adambullmer
Copy link
Author

adambullmer commented Sep 30, 2020

Yeah, I think I called my patch a solution too soon. It builds successfully and I assumed the lack of output was because the boilerplate component was broken for TS projects. After fixing that, there appears to be console errors because @storybook/vue/dist/client/preview/render.js tries to create vue components with new Vue() which was removed in vue 3.

    at Object../.yarn/$$virtual/@storybook-vue-virtual-af7ac388fa/0/cache/@storybook-vue-npm-6.0.22-10d30dd9e8-4f2987ec61.zip/node_modules/@storybook/vue/dist/client/preview/render.js (render.js:47)
    at __webpack_require__ (bootstrap:848)
    at fn (bootstrap:150)
    at Object../.yarn/$$virtual/@storybook-vue-virtual-af7ac388fa/0/cache/@storybook-vue-npm-6.0.22-10d30dd9e8-4f2987ec61.zip/node_modules/@storybook/vue/dist/client/preview/index.js (index.js:30)
    at __webpack_require__ (bootstrap:848)
    at fn (bootstrap:150)
    at Object.<anonymous> (index.js:55)
    at Object../.yarn/$$virtual/@storybook-vue-virtual-af7ac388fa/0/cache/@storybook-vue-npm-6.0.22-10d30dd9e8-4f2987ec61.zip/node_modules/@storybook/vue/dist/client/index.js (index.js:59)
    at __webpack_require__ (bootstrap:848)
    at fn (bootstrap:150)

I think the provided patch is all that is needed here, but more work will be necessary in the storybook side to fix vue rendering.

@adambullmer
Copy link
Author

@pksunkara I think I've got the yarn patchable (post transpile) changes figured out. There's some HMR issues with it for sure, and I'm seeing that click events (and probably other listeners) are firing twice. But this could at least serve as a starting place for using storybook with vue 3.

The changes below mostly follow the migration guides for render functions and creating components. But that alone didn't render the story, so it was necessary to begin using the composition api to make the reactive storybook properties added on the root app. While this is a bit of a hack, I suspect the storybook team will be able to leverage composition APIs to drastically simplify their vue integration.

./patches/@storybook/vue.patch

diff --git a/dist/client/preview/index.js b/dist/client/preview/index.js
index 38a6be377c58c2efab3fdd446a0272e30045ced9..3accfe7f72096cfce6d2bd63f37fd3005819a231 100644
--- a/dist/client/preview/index.js
+++ b/dist/client/preview/index.js
@@ -70,18 +70,19 @@ function prepare(rawStory, innerStory) {
       });
     }
 
-    story = _vue["default"].extend(story); // @ts-ignore // https://github.com/storybookjs/storybook/pull/7578#discussion_r307984824
-  } else if (story.options[WRAPS]) {
+    story = _vue["defineComponent"](story); // @ts-ignore // https://github.com/storybookjs/storybook/pull/7578#discussion_r307984824
+  } else if (story[WRAPS]) {
     return story;
   }
 
-  return _vue["default"].extend((_Vue$extend = {}, _defineProperty(_Vue$extend, WRAPS, story), _defineProperty(_Vue$extend, _render.VALUES, Object.assign(Object.assign({}, innerStory ? innerStory.options[_render.VALUES] : {}), (0, _util.extractProps)(story))), _defineProperty(_Vue$extend, "functional", true), _defineProperty(_Vue$extend, "render", function render(h, _ref) {
-    var data = _ref.data,
-        parent = _ref.parent,
-        children = _ref.children;
-    return h(story, Object.assign(Object.assign({}, data), {}, {
+  return _vue["defineComponent"]((_Vue$extend = {}, _defineProperty(_Vue$extend, WRAPS, story), _defineProperty(_Vue$extend, _render.VALUES, Object.assign(Object.assign({}, innerStory ? innerStory[_render.VALUES] : {}), (0, _util.extractProps)(story))), _defineProperty(_Vue$extend, "functional", true), _defineProperty(_Vue$extend, "render", function render(_ref) {
+    var data = _ref.$data,
+        props = _ref.$props,
+        parent = _ref.$parent,
+        children = _ref.$children;
+    return _vue['h'](story, Object.assign(Object.assign({}, data), {}, {
       // @ts-ignore // https://github.com/storybookjs/storybook/pull/7578#discussion_r307986196
-      props: Object.assign(Object.assign({}, data.props || {}), parent.$root[_render.VALUES])
+      props: Object.assign(Object.assign({}, props || {}), parent.$root[_render.VALUES])
     }), children);
   }), _Vue$extend));
 }
diff --git a/dist/client/preview/render.js b/dist/client/preview/render.js
index 510391bf8a72e0ae4246176901522654e425b4b0..6b914faad18f7f69af30456d30a08c77fd02eaea 100644
--- a/dist/client/preview/render.js
+++ b/dist/client/preview/render.js
@@ -44,20 +44,24 @@ var COMPONENT = 'STORYBOOK_COMPONENT';
 exports.COMPONENT = COMPONENT;
 var VALUES = 'STORYBOOK_VALUES';
 exports.VALUES = VALUES;
-var root = new _vue["default"]({
-  data: function data() {
-    var _ref;
-
-    return _ref = {}, _defineProperty(_ref, COMPONENT, undefined), _defineProperty(_ref, VALUES, {}), _ref;
+var _ref = _vue['markRaw']({
+  [COMPONENT]: undefined,
+  [VALUES]: {},
+});
+var root = _vue["createApp"]({
+  setup(props, { slots, attrs, emit }) {
+    var children = _ref[COMPONENT] ? [_vue['h'](_ref[COMPONENT])] : undefined;
+
+    return () => _vue['h'](
+      'div',
+      {
+        id: 'root',
+        [COMPONENT]: _ref[COMPONENT],
+        [VALUES]: _ref[VALUES],
+      },
+      children
+    );
   },
-  render: function render(h) {
-    var children = this[COMPONENT] ? [h(this[COMPONENT])] : undefined;
-    return h('div', {
-      attrs: {
-        id: 'root'
-      }
-    }, children);
-  }
 });
 
 function render(_ref2) {
@@ -69,7 +73,7 @@ function render(_ref2) {
       showError = _ref2.showError,
       showException = _ref2.showException,
       forceRender = _ref2.forceRender;
-  _vue["default"].config.errorHandler = showException; // FIXME: move this into root[COMPONENT] = element
+  root.config.errorHandler = showException; // FIXME: move this into root[COMPONENT] = element
   // once we get rid of knobs so we don't have to re-create
   // a new component each time
 
@@ -85,14 +89,14 @@ function render(_ref2) {
 
   showMain(); // at component creation || refresh by HMR or switching stories
 
-  if (!root[COMPONENT] || !forceRender) {
-    root[COMPONENT] = element;
+  if (!_ref[COMPONENT] || !forceRender) {
+    _ref[COMPONENT] = element;
   } // @ts-ignore https://github.com/storybookjs/storrybook/pull/7578#discussion_r307986139
 
 
-  root[VALUES] = Object.assign(Object.assign({}, element.options[VALUES]), args);
+  _ref[VALUES] = Object.assign(Object.assign({}, element[VALUES]), args);
 
   if (!root.$el) {
-    root.$mount('#root');
+    root.mount('#root');
   }
 }
\ No newline at end of file
diff --git a/dist/client/preview/util.js b/dist/client/preview/util.js
index ab8c1d3cdb5424fc782e3fb3bee8951ee2d6c7e0..90bbd09f5a6276ea6592c7c0d0a9ba63df83e140 100644
--- a/dist/client/preview/util.js
+++ b/dist/client/preview/util.js
@@ -79,7 +79,7 @@ function resolveDefault(_ref) {
 
 function extractProps(component) {
   // @ts-ignore this options business seems not good according to the types
-  return Object.entries(component.options.props || {}).map(function (_ref2) {
+  return Object.entries(component.props || {}).map(function (_ref2) {
     var _ref3 = _slicedToArray(_ref2, 2),
         name = _ref3[0],
         prop = _ref3[1];
 "devDependencies": {
    // ...
    "@storybook/vue": "patch:@storybook/vue@^6.0.0#./patches/@storybook/vue.patch",
    "vue-cli-plugin-storybook": "patch:vue-cli-plugin-storybook@~1.3.0#./patches/vue-cli-plugin-storybook.patch",
    // ...
  }

@pksunkara
Copy link
Member

You should probably help at storybookjs/storybook#10654 instead of here.

@bodograumann
Copy link
Contributor

bodograumann commented May 31, 2021

Given that vue3 support has landed in storybook 6.2, this should be doable now.

Here are some things, that I definitely had to change:

  • install @storybook/vue3
  • require @storybook/vue3/package.json in lib/index.js
  • framework: 'vue3' in lib/index.js
  • require vue/dist/vue.esm-browser.js in lib/preset.js
  • get the new app object in config/storybook/preview.js with import { app } from "@storybook/vue3";
    e.g. to register directives or global components

The only thing that doesn’t work for me is storybook-vue-router and the property tables in docs mode.
Cf. vue-styleguidist/vue-styleguidist#997

@bodograumann
Copy link
Contributor

What do you think, would it be better to have one version of vue-cli-plugin-storybook to support both vue2 and vue3 or separate versions?

@pksunkara
Copy link
Member

We can try. Would welcome a PR

@bodograumann
Copy link
Contributor

From a user perspective I would prefer to have only one plugin no matter my vue version.
For vue 2 we peer-depend on @storybook/vue and for vue 3 on @storybook/vue3 though.
How can we handle that?

@bodograumann
Copy link
Contributor

Ok, I solved it with optional peerDependencies. They work with npm 7. In npm 6 peerDependencies are not pulled in automatically anyways.

Please have a look at the PR @pksunkara .

@pksunkara pksunkara removed the bug Something isn't working label Jun 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants