cyrilwanner / react-optimized-image

Easy to use React components for optimized-images-loader / next-optimized-images.
MIT License
62 stars 8 forks source link

Usage with storybook #8

Open piprees opened 4 years ago

piprees commented 4 years ago

Hey, I appreciate the work you've been doing on this package and can't wait to get a demo up and running with it! It works amazingly well in NextJS, so I'm trying to use the plugin with Storybook.js so we can use it with our component library.

I'm extending the storybook webpack config as recommended like this:

// .storybook/main.js

{
  webpackFinal: async (config) => {
    config.module.rules.push({
      test: /\.(png|jpe?g|gif|svg|webp|ico)$/i,
      use: [
        {
          loader: 'optimized-images-loader',
          options: {
            includeStrategy: 'react'
          },
        },
      ],
    });
    return config;
  }
}

And I have it configured in babel like so;

// babel.config.js

module.exports = {
  presets: ['next/babel'],
  plugins: ['react-optimized-image/plugin']
}

And I'm trying to use it like this in my components:

// components/Header/Header.tsx

import { Svg } from 'react-optimized-image'
import Logo from './assets/logo.svg'

export function Header(): JSX.Element {
  return (<Svg src={Logo} />)
}

And like this in my story file:

// components/Header/Header.stories.tsx

import { Meta, Story } from '@storybook/react'
import React from 'react'
import { Header } from './Header'

const config: Meta = { title: 'Components/Header', component: Header }
const Template: Story = (args) => <Header {...args} />

export default config
export const Default = Template.bind({})

When i run start-storybook, i get the following error:

Error: No react component generated. Please set `includeStrategy` option of optimized-images-loader to 'react'
    at Svg (http://localhost:6006/vendors~main.2430c86930fd7a1bab86.bundle.js:71140:11)
    at renderWithHooks

I've tried adding options and changing the order of the loaders with no luck, any ideas?

piprees commented 4 years ago

For anyone else who might be having this issue, I've got a (totally hacky) workaround...

File loader seems to be taking precedence over optimized-images-loader. So, in the below example, we override the file matching regex for file-loader by first finding out it's position in the rules array, and then adjusting the regex so that it doesn't handle all of the usual images.

This is unlikely to work for everyone, but it has worked for me!

To figure out the index of file loader, run webpack with a command like so, and just dig through it by searching for rules:. Please note, there are two sets of rules:, one for the webpack UI, and one for your stories. We want the file-loader index of the stories config (the second one).

yarn start-storybook --debug-webpack > ./webpacklog.txt

Then update your .storybook/main.js with a custom webpack config like so:

// .storybook/main.js
module.exports = {
  webpackFinal: async (config) => {
    // Override the images handler of file-loader to stop it
    // stealing file types away from optimized-images-loader
    config.module.rules[7].test = /\.(eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/;

    // Add optimized-images-loader to handle those file
    config.module.rules.push({
      test: /\.(png|jpg|jpeg|gif|svg|webp|ico)$/i,
      use: [
        {
          loader: 'optimized-images-loader',
          options: {
            includeStrategy: 'react'
          },
        },
      ],
    });
    return config;
  },
}

Hope this helps someone!