storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.11k stars 9.26k forks source link

[Bug]: Web Components are not supported propperly #24401

Open itsmebasti opened 12 months ago

itsmebasti commented 12 months ago

Describe the bug

I just installed the latest storybook version inside my stencil project. To make the components available I register them to the window as Custom Elements (CustomElementRegistry) with stencils provided loader function. While creating stories now, I encounter the following problems:

  1. Loading content into slots is not supported at all, it's basic web component functionality, it should be supported in my opinion.
  2. Using the args inside my stories leads to attributeless "show code" results:

I guess I have to write my own generic renderer to solve these issues, but I feel like it should be supported by the @storybook/web-components framework. Also, I am a little confused about the existing storybook web component examples, they all seem not to work with web component technologies, but are just using some lit-html renderings to create some HTML instead of loading proper web components.

Additionally, I had to add "@babel/preset-typescript" to my .babelrc.json to make my stories compile, I guess it's rather framework-specific, but I wanted to mention it for future googlers.

To Reproduce

No response

System

System:
    OS: Windows 10 10.0.22621
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 20.3.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 9.7.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (117.0.2045.47)

Additional context

No response

rramsey commented 11 months ago

I'll add some additional details. I found older instructions at https://ionic.io/blog/how-to-use-storybook-with-stencil which made it sound like everything just worked, except it didn't. It may be down to a vite vs. webpack issue, but I've got the same error with a more complex project with both vite and webpack. The basic instructions are to do the following:

  1. npm init stencil # when asked, call the project st-sb-test
  2. cd st-sb-test
  3. npm install
  4. npm run build # build your stencil app
  5. npx sb init --type html
  6. npm run storybook-build
  7. npm run build-storybook
  8. start storybook-static
  9. Copy files to a web server

I deleted the directory and tried again, but instead of explicitly doing npx sb init --type html I did npx sb init and picked web components and took the defaults for everything else.

Preview.js:

import {defineCustomElements} from '../loader';
defineCustomElements();
/** @type { import('@storybook/web-components').Preview } */
const preview = {
  parameters: {
    actions: { argTypesRegex: '^on[A-Z].*' },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
};
export default preview;

my-component.stories.ts:

export default {
  // this creates a ‘Components’ folder and a ‘MyComponent’ subfolder
  title: 'Components/MyComponent',
};
const Template = (args) => `<my-component first="${args.first}" middle="${args.middle}" last="${args.last}"></my-component>`;
export const Example = Template.bind({});
Example.args = {
  first: 'Winnie',
  middle: 'The',
  last: 'Pooh'
};

partial package.json:

  "dependencies": {
    "@stencil/core": "^4.7.0"
  },
  "devDependencies": {
    "@storybook/addon-essentials": "^7.5.2",
    "@storybook/addon-links": "^7.5.2",
    "@storybook/blocks": "^7.5.2",
    "@storybook/web-components": "^7.5.2",
    "@storybook/web-components-vite": "^7.5.2",
    "@types/jest": "^29.5.6",
    "@types/node": "^16.18.11",
    "jest": "^29.7.0",
    "jest-cli": "^29.7.0",
    "lit": "^3.0.1",
    "puppeteer": "21.1.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "storybook": "^7.5.2"
  },

The error I'm getting is:

index-db936cd2.js:1304     GET https://my.webserver.com/sb/assets/my-component.entry.js net::ERR_ABORTED 404 (Not Found)
index-db936cd2.js:1288 TypeError: Failed to fetch dynamically imported module: https://my.webserver.com/sb/assets/my-component.entry.js undefined
index-db936cd2.js:1028 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'isProxied')

my-component.entry.js exists in the dist/esm folder created by stencil's build, but just copying it into assets folder doesn't work. I've tried using the index-HASH.js files that stencil creates in that folder, but no luck. Also tried using dist/cjs/my-component.cjs.entry.js and renaming that, but then I get index-db936cd2.js:1288 ReferenceError: exports is not defined. And I don't know enough to go through the files in dist to find the one I need to rename and copy up to the web server.

Hopefully that helps someone to at least reproduce the problem in storybook.

The frustrating thing is that everything works fine locally. It's only when I build the static files and upload them to the server that I have a problem.

shilman commented 11 months ago

@Integrayshaun any thoughts here?

rramsey commented 11 months ago

A few more details. I realized that I'd only been copying the my-component.entry.js file into assets. So I copied everything in dist/esm into assets. That got me a slightly different error:

index-db936cd2.js:1288 TypeError: Cannot read properties of undefined (reading '$instanceValues$')
    at ve (index-db936cd2.js:851:28)
    at MyComponent.set [as first] (index-db936cd2.js:900:25)
    at new MyComponent (my-component.tsx:9:25)
    at Se (index-db936cd2.js:1044:17) undefined
index-db936cd2.js:1288 TypeError: Cannot read properties of undefined (reading '$instanceValues$')
    at he (index-db936cd2.js:847:51)
    at MyComponent.get [as first] (index-db936cd2.js:896:32)
    at MyComponent.getText (my-component.tsx:26:24)
    at MyComponent.render (my-component.tsx:30:41)
    at ge (index-db936cd2.js:776:29)
    at pe (index-db936cd2.js:734:9)
    at index-db936cd2.js:682:40
    at fe (index-db936cd2.js:700:90)

Noticed the reference to the tsx file in the error, so what the heck, copied that into assets as well, but it made no difference. I checked, and the index-db936cd2.js file does exist in my assets folder.

The localhost version can load the files just fine from the stencil dist/esm folder, so it shouldn't be too hard to get this to work. I just don't know enough.

rramsey commented 11 months ago

I wonder if it is something with the base href in the frame?? When I hover my mouse over the filename index-db936cd2.js in the devtools, it says it is https://server/rramsey/dist/esm/index-db936cd2.js. Except that path and file don't exist. Both firefox and chrome show a path that doesn't exist, which should be a 404. I created the dist/esm/index-db936cd2.js fileand put some console.logs in, but they never showed up and the source in devtools didn't show them.

If you put a breakpoint in, it's impossible to debug because instead of true functions, everything is const x = () => { } construction.

Spent more time on this than I should have because it is soo frustrating when everything works locally but not when built. My thought is that I'm just going to say that storybook isn't ready for prime time when it comes to html and web components.

omarkawach commented 10 months ago

Additionally, I had to add "@babel/preset-typescript" to my .babelrc.json to make my stories compile, I guess it's rather framework-specific, but I wanted to mention it for future googlers.

This wasn't necessary for us when using @storybook/web-components-vite. Only seems to be a thing with webpack

ShaunEvening commented 10 months ago

@omarkawach Yeah, vite supports TypeScript out of the box 😁

ShaunEvening commented 10 months ago

Hey @itsmebasti @rramsey 👋

This is unfortunately a known issue for stencil in particular right now. Currently @storybook/web-components is mostly geared towards lit so the name is a little misleading. This is something I want to work on in the coming months.

The other kicker is that stencil support is hard to get right and i'm trying to get in contact with the stencil team to see what we can do to remedy the situation. Here's a link to my comment in another issue that should give you the context on that situation. https://github.com/storybookjs/storybook/issues/22124#issuecomment-1769194296

rramsey commented 8 months ago

FYI, this is still broken when the stencil components are built with vue wrappers. It's fine when running locally, but as soon as you build it you get the 404 erros and the vueOutputTarget. Again, works fine locally, but as soon as you build it and put it on a server it breaks. I even tried 8-alpha-15 with no improvement.

rramsey commented 8 months ago

Oh, and I tried making a very basic lit component and got the same $instanceValues$ error. That was with both web components and html.

Tragio commented 5 months ago

On the project I was working on, if I have on tsconfig the target >= ES2022 it does not work and I have instanceValues error but if I put ES2021 or below it works.

marksy commented 3 months ago

Getting Stencil to work with Storybook is an absolute PIA.

I'm using Stencil to generate Web Components and React wrapped components, because our developers use both technologies in our stack.

To get them to show in Storybook, I'm following mi6's example that uses a monorepo, as well as the Storybook Composition technique to get multiple Storybook's to show in one interface.

I keep finding so many issues that I struggle to find answers for on the internet, which makes me wonder if all my config is wrong.

My latest issue is the Show Code button doesn't show any code for Web Components. I'm using MDX for WC stories.

Getting back to the main point, WC (specifically with Stencil) is not giving us a fun time with Storybook.

omarkawach commented 3 months ago

In our Stencil + @storybook/web-components / @storybook/web-components-vite project, the way we got it to work was by adding the following to previewHead in main.ts

<script type="module" src="./www/build/simplifiedPackageName.esm.js"></script>
<link rel="stylesheet" href="./www/build/simplifiedPackageName.css" />

Instead of the following in preview.ts as seen in https://github.com/mi6/ic-ui-kit

import { defineCustomElements } from '../dist/esm/loader';
defineCustomElements();
rjborba commented 2 months ago

In our Stencil + @storybook/web-components / @storybook/web-components-vite project, the way we got it to work was by adding the following to previewHead in main.ts

<script type="module" src="./www/build/simplifiedPackageName.esm.js"></script>
<link rel="stylesheet" href="./www/build/simplifiedPackageName.css" />

Instead of the following in preview.ts as seen in https://github.com/mi6/ic-ui-kit

import { defineCustomElements } from '../dist/esm/loader';
defineCustomElements();

Thank you so much. This was exactly what was missing from my settings.

In my case I'm using storybook + stencil in a monorepo. Storybook and Stencil are distinct projects.

I've removed the defineCustomElements on preview and imported it on previewHead in main.ts

previewHead: (head) => `
   ${head}
  <script type="module" src="assets/MY-PROJECT.esm.js"></script>
  <link rel="stylesheet" href="assets/MY_PROJECT.css" />
  `,

Also in preview, I added staticDirs prop to Storybook config mapping content of my dist folder to /assets:

staticDirs: [{ from: '../../../packages/MY_PROJECT/dist/MY_PROJECT_NAMESPACE', to: '/assets' }],

Loic57 commented 1 month ago

Hello @rjborba Is there any specific reason to put your esm.js and .css files into assets folder instead of keeping them in the dist ?