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 projects using Vue 3 #12632

Closed
adambullmer opened this issue Sep 30, 2020 · 1 comment
Closed

Incompatible with projects using Vue 3 #12632

adambullmer opened this issue Sep 30, 2020 · 1 comment

Comments

@adambullmer
Copy link

Describe the bug
Piggybacking off the issue in storybookjs/vue-cli-plugin-storybook#111, This package appears to be completely incompatible with vue 3.

To Reproduce

  1. Create a vue 3 app using the vue-cli scaffold.
  2. Add storybook via the vue-cli plugin vue add storybook
  3. Convert project to yarn 2 (berry) yarn version set berry
  4. yarn install
  5. Extend peer dependencies for vue-cli-plugin-storybook (Necessary until Requiring unspecified peer dependency vue-cli-plugin-storybook#110 is closed) and other repo dependencies (sample below)
  6. Patch vue-cli-plugin-storybook to fix module import resolution (for vue 3) (sample below)
  7. Serve storybook, and observe console errors stemming from storybook/vue's client render package.

Expected behavior
I expect that using a vue-3 based project, storybook can still render stories without error.

Screenshots
If applicable, add screenshots to help explain your problem.

Code snippets
.yarnrc.yml

yarnPath: ".yarn/releases/yarn-berry.cjs"

packageExtensions:
  "@storybook/core@*":
    peerDependencies:
      react: "*"
      react-dom: "*"
  "@vue/cli-plugin-typescript@*":
    peerDependencies:
      babel-loader: "*"
  vue-cli-plugin-storybook@*:
    peerDependencies:
      "@storybook/core": "*"
  vue-loader@*:
    peerDependencies:
      webpack: "*"

./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,

package.json

{
  "name": "test-vue-3",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "lint": "vue-cli-service lint",
    "storybook:build": "vue-cli-service storybook:build -c config/storybook",
    "storybook:serve": "vue-cli-service storybook:serve -p 6006 -c config/storybook"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0-0",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@storybook/addon-actions": "^6.0.0",
    "@storybook/addon-knobs": "^6.0.0",
    "@storybook/addon-links": "^6.0.0",
    "@storybook/core": "^6.0.22",
    "@storybook/vue": "^6.0.0",
    "@types/jest": "^24.0.19",
    "@types/node": "^14.11.2",
    "@typescript-eslint/eslint-plugin": "^2.33.0",
    "@typescript-eslint/parser": "^2.33.0",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-e2e-cypress": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-plugin-unit-jest": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0-0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/eslint-config-typescript": "^5.0.2",
    "@vue/test-utils": "^2.0.0-0",
    "@yarnpkg/pnpify": "^2.2.1",
    "babel-loader": "^8.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-vue": "^7.0.0-0",
    "prettier": "^1.19.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "typescript": "~3.9.3",
    "vue-cli-plugin-pnp": "~1.0.0",
    "vue-cli-plugin-storybook": "patch:vue-cli-plugin-storybook@~1.3.0#./patches/vue-cli-plugin-storybook.patch",
    "vue-jest": "^5.0.0-0"
  }
}

System

Environment Info:

  System:
    OS: macOS 10.15.7
    CPU: (4) x64 Intel(R) Core(TM) i5-6267U CPU @ 2.90GHz
  Binaries:
    Node: 14.12.0 - /usr/local/bin/node
    Yarn: 2.2.2 - /usr/local/bin/yarn
    npm: 6.14.8 - /usr/local/bin/npm
  Browsers:
    Chrome: 85.0.4183.121
    Firefox: 67.0.4
    Safari: 14.0

Additional context

I've dug deep enough to create a patch to be able to successfully render a story for those who can't wait and need something in the interim. It's definitely not perfect, but it is better than no storybook at all.

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];
@pksunkara
Copy link
Member

pksunkara commented Sep 30, 2020

We are tracking the Vue 3 related work at #10654 as I already mentioned in the CLI plugin issue.

Please contribute to the discussion there instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants