storybookjs / storybook

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

[Feature Request]: Use Angular with esbuild and vite #22544

Open yangfan100 opened 1 year ago

yangfan100 commented 1 year ago

Describe the bug

Why I can not use vite with Storybook Angular, Angular v16 is surport with Vite

To Reproduce

No response

System

No response

Additional context

No response

usrrname commented 1 year ago

Please include a reproduction so folks can understand what you're stuck on!

valentinpalkovic commented 1 year ago

Using esbuild as builder and a vite dev server is currently not supported for Angular. But we will evaluate possible solutions soon.

nstuyvesant commented 1 year ago

That would be appreciated. For the monorepo I am working on, there are 5 packages and 5 Storybooks. Out of the 10 items that need to be bundled, only one uses webpack.

brandonroberts commented 1 year ago

I maintain Analog, which has integration for Angular using Vite's build pipeline. I have a working example of Angular with the Storybook Vite Builder.

https://github.com/brandonroberts/analog-angular-storybook-vite

Not sure why yet, but I have to use a different import for the @storybook/angular imports. If anyone has any insight there, that would help.

Noted in this commit

https://github.com/brandonroberts/analog-angular-storybook-vite/commit/194c380dc4a1c8fc342a812f460e9422307f3b8d

asifaminb commented 1 year ago

I maintain Analog, which has integration for Angular using Vite's build pipeline. I have a working example of Angular with the Storybook Vite Builder.

https://github.com/brandonroberts/analog-angular-storybook-vite

Not sure why yet, but I have to use a different import for the @storybook/angular imports. If anyone has any insight there, that would help.

Noted in this commit

brandonroberts/analog-angular-storybook-vite@194c380

I got an error when I tried to run this project locally, image

rvale01 commented 1 year ago

Any updates on this?

brandonroberts commented 1 year ago

@rvale01 I think the team is still working to integrate the new esbuild based Angular setup with Storybook. I pushed an updated repo with Analog and Angular v16

https://github.com/brandonroberts/analog-angular-storybook-v16

pumano commented 11 months ago

would love to use that when support provided

brandonroberts commented 11 months ago

would love to use that when support provided

Yep, they are working towards a solution and will show it at some point

byjokese commented 10 months ago

Any expected timeframe for this?

VaniaBlanar commented 7 months ago

any update on it?

bastiW commented 7 months ago

"We’re also working with the Angular core team to support new high-performance build options in a future version."

https://storybook.js.org/blog/storybook-8/

sod commented 5 months ago

Can we help? We use both, storybook8 (webpack) and angular18/esbuild/vite.

VaniaBlanar commented 5 months ago

Eventually, I made it work. Changing the property in angular.json helped. from "outputPath": { "base": "./dist"} to "outputPath": "./dist",

LeoLetourneur commented 2 months ago

For anyone interrested, esbuild/vite are working with Angular 18.2.3 & Storybook 8.3.0. I made it work thanks to this repo https://github.com/brandonroberts/angular-v17-vite-storybook

For serve

I also had some path alias (typescript & scss) working with webpack. So I needed to add this to the .storybook/main.ts

resolve: {
    alias: {
          '@env': path.resolve(__dirname, '../src/environments/environment'),
          '@features': path.resolve(__dirname, '../src/app/features/'),
          '@shared': path.resolve(__dirname, '../src/app/shared'),
          '@core': path.resolve(__dirname, '../src/app/core'),
          shared: path.resolve(__dirname, '../src/styles/shared.scss'), // <- scss alias @import 'shared'
    },
},

I also had some old internal libraries in CommonJS with errors at runtime like Module xxx doesn't not provide exported name { XXX } for file://xxx/xxx/xxx

Make sure to build libraries in ESM.

For the build (& hosting), I had two more issues :

Workers output format at build time I have web workers in my app. Build failed like :

[vite:worker-import-meta-url] Invalid value "iife" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.

You should add to your esbuild config

worker: {
    format: 'esm',
},

ngDevMode not defined at run time (in storybook frame)

ReferenceError: ngDevMode is not defined

You should add to your esbuild config

define: {
    ngDevMode: 'undefined',
},
brandonroberts commented 2 months ago

Thanks @LeoLetourneur. There's also a guide here also for anyone looking to migrate

https://analogjs.org/docs/integrations/storybook

sinaa commented 1 month ago

@brandonroberts / @LeoLetourneur did you guys figure out how to sort out CSS post processing? e.g., tailwind.

brandonroberts commented 1 month ago

@brandonroberts / @LeoLetourneur did you guys figure out how to sort out CSS post processing? e.g., tailwind.

What issue are you having?

Vite has PostCSS support built in https://vitejs.dev/guide/features.html#postcss

elirov commented 1 week ago

For anyone interrested, esbuild/vite are working with Angular 18.2.3 & Storybook 8.3.0. I made it work thanks to this repo https://github.com/brandonroberts/angular-v17-vite-storybook

For serve

I also had some path alias (typescript & scss) working with webpack. So I needed to add this to the .storybook/main.ts

resolve: {
    alias: {
          '@env': path.resolve(__dirname, '../src/environments/environment'),
          '@features': path.resolve(__dirname, '../src/app/features/'),
          '@shared': path.resolve(__dirname, '../src/app/shared'),
          '@core': path.resolve(__dirname, '../src/app/core'),
          shared: path.resolve(__dirname, '../src/styles/shared.scss'), // <- scss alias @import 'shared'
    },
},

I also had some old internal libraries in CommonJS with errors at runtime like Module xxx doesn't not provide exported name { XXX } for file://xxx/xxx/xxx

Make sure to build libraries in ESM.

For the build (& hosting), I had two more issues :

Workers output format at build time I have web workers in my app. Build failed like :

[vite:worker-import-meta-url] Invalid value "iife" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.

You should add to your esbuild config

worker: {
    format: 'esm',
},

ngDevMode not defined at run time (in storybook frame)

ReferenceError: ngDevMode is not defined

You should add to your esbuild config

define: {
    ngDevMode: 'undefined',
},

Getting that same ngDevMode undefined error. Where exactly can I add that define: {...} or worker: {...} clauses? what files?

brandonroberts commented 1 week ago

@elirov that issue has been resolved in Analog version 1.9.1.

elirov commented 1 week ago

Interesting. I was getting the same error on analog 1.9.1. I had to add the following to my .storybook/main.ts: async viteFinal(config: UserConfig) { // Merge custom configuration into the default config const { mergeConfig } = await import('vite'); const { default: angular } = await import('@analogjs/vite-plugin-angular'); const tailwindcss = await import('tailwindcss'); const autoprefixer = await import('autoprefixer');

return mergeConfig(config, {
  define: {
    ngDevMode: 'false',
  },
brandonroberts commented 1 week ago

Interesting. What version of Storybook/Angular/Analog plugin are you on?

elirov commented 1 week ago
"@analogjs/vite-plugin-angular": "^1.9.1",
"@chromatic-com/storybook": "3.2.2",
"@storybook/addon-designs": "8.0.4",
"@storybook/addon-docs": "8.4.1",
"@storybook/addon-essentials": "8.4.1",
"@storybook/addon-interactions": "8.4.1",
"@storybook/addon-links": "8.4.1",
"@storybook/angular": "8.4.1",
"@storybook/blocks": "8.4.1",
"@storybook/builder-vite": "^8.4.1",
"@storybook/test": "8.4.1",
"eslint-plugin-storybook": "0.10.2",
"storybook": "^8.4.1",
"storybook-addon-angular-router": "1.10.1",
"storybook-addon-mock": "5.0.0",
"storybook-addon-mock-date": "^0.6.0",
"vite": "^5.4.10",
"vite-tsconfig-paths": "^5.0.1",
elirov commented 1 week ago

and here's my storybook main.ts: import { StorybookConfig } from '@storybook/angular'; import { StorybookConfigVite } from '@storybook/builder-vite'; import { resolve } from 'path'; import { UserConfig } from 'vite'; import tsconfigPaths from 'vite-tsconfig-paths';

const config: StorybookConfig & StorybookConfigVite = { // other config, addons, etc. stories: ['../src/*/.stories.ts'], //staticDirs: ['../storybook-static'], addons: [ '@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions', 'storybook-addon-mock', 'storybook-addon-mock-date', ],

framework: { name: '@storybook/angular', options: {}, }, core: { builder: '@storybook/builder-vite', }, async viteFinal(config: UserConfig) { // Merge custom configuration into the default config const { mergeConfig } = await import('vite'); const { default: angular } = await import('@analogjs/vite-plugin-angular'); const tailwindcss = await import('tailwindcss'); const autoprefixer = await import('autoprefixer');

return mergeConfig(config, {
  define: {
    ngDevMode: 'false',
  },
  // Add dependencies to pre-optimization
  resolve: {
    alias: {
      app: resolve(__dirname, '../src/app'),
      features: resolve(__dirname, '../src/features'),
      shared: resolve(__dirname, '../src/shared'),
      theme: resolve(__dirname, '../src/theme'),
      environments: resolve(__dirname, '../src/environments'),
      licenses: resolve(__dirname, '../src/licenses'),
      '@syncfusion': resolve(__dirname, '../node_modules/@syncfusion'),
    },
  },
  optimizeDeps: {
    include: [
      '@storybook/angular',
      '@storybook/angular/dist/client',
      '@angular/compiler',
      '@storybook/blocks',
      'tslib',
    ],
    exclude: ['@analogjs/vite-plugin-angular'],
  },
  plugins: [
    tsconfigPaths(),
    angular({ jit: true, tsconfig: './.storybook/tsconfig.json' }),
  ],
  css: {
    postcss: {
      plugins: [tailwindcss.default(), autoprefixer.default()],
    },
    preprocessorOptions: {
      scss: {
        includePaths: [
          resolve(__dirname, '../src'),
          resolve(__dirname, '../node_modules'),
          resolve(__dirname, '../node_modules/@syncfusion'),
          resolve(__dirname, '../node_modules/@syncfusion/ej2-base/styles'),
          resolve(
            __dirname,
            '../node_modules/@syncfusion/ej2-icons/styles'
          ),
        ],
      },
    },
  },
});

}, }; export default config;

elirov commented 1 week ago

I did figure out how to add the ngDevMode: false option to the vite storybook config. But now, I'm getting an error in chromatic: ✖ Failed to extract stories from your Storybook This is usually a problem with your published Storybook, not with Chromatic.

Build and open your Storybook locally and check the browser console for errors. Visit your published Storybook at The following error was encountered while running your Storybook:

Error: Error: page.evaluate: TypeError: Cannot add property verbosity, object is not extensible

brandonroberts commented 1 week ago

Yea, ngDevMode should be false when doing a build. I'm seeing the issue here also https://github.com/brandonroberts/angular-v17-vite-storybook with the latest version of the plugin.

We changed the detection of production mode to be based on the vite config mode, but its not being set in the config. Will get a fix in shortly on the plugin side

brandonroberts commented 1 week ago

@elirov landed a fix in Analog 1.9.2-beta.2 you can test