jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.26k stars 508 forks source link

HOWTO for importing images doesn't work for SVGs #662

Open stevesims opened 4 years ago

stevesims commented 4 years ago

Current Behavior

The HOWTO explaining how to support images, found here does not work for SVGs.

I have a tsdx.config.js file identical to the one in the HOWTO, but when I run a either yarn start or yarn build I see the following error:

✖ Failed to compile
(typescript) Error: /path/to/component/index.tsx(6,19): semantic error TS2307: Cannot find module '../icons/error.svg'.

I've also tried modified versions of that tsdx.config.js file that either just call images() or add in '**/*.svg' to the include list, to no avail.

This error relates to the following line in my component/index.tsx file:

import error from '../icons/error.svg';

Expected behavior

It should just work. :wink:

Suggested solution(s)

Additional context

The component in question is using styled-components - it's applying the image as a background, using: backgroundImage:url(${error}),

This component is part of a component library and I also have storybook set up in my repo - that is managing to successfully build and display this SVG file with this import.

Your environment

Software Version(s)
TSDX 0.12.3
TypeScript 3.7.5
Browser n/a
npm/Yarn yarn 1.22.4
Node 12.6.0
Operating System OS X 10.14.6
csabapalfi commented 4 years ago

I wonder if this comment is helpful for resolving this: https://github.com/jaredpalmer/tsdx/issues/278#issuecomment-563184800

stevesims commented 4 years ago

Unfortunately no, that comment doesn't help. Essentially the "working" solution in that comment just uses a different version of the image plugin, but I just get the same results. 😞

MrNovado commented 4 years ago

@stevesims @svgr/rollup (+ url) did the trick for me: https://react-svgr.com/docs/rollup/

const url = require('@rollup/plugin-url');
const svgr = require('@svgr/rollup').default;

module.exports = {
  rollup(config, options) {
    config.plugins = [
      url(),
      svgr({
        // configure however you like, this is just an example
        ref: true,
        memo: true,
        svgoConfig: {
          plugins: [
            { removeViewBox: false },
            { removeAttrs: { attrs: 'g:(stroke|fill):((?!^none$).)*' } }
          ],
        },
      }),
      ...config.plugins,
    ];

    return config;
  },
};
import SvgUrl, { ReactComponent as Svg } from './icon.svg'
technostyle commented 4 years ago

@MrNovado thanks a lot, it worked out great for me!

But now I wonder is it possible to load svg as ReactComponent from npm-module icon pack?

import SvgUrl, { ReactComponent as Svg } from 'icons-pack/my-icon.svg'

What I get now is a mysterious filename string import /static/media/my-icon.ba681e15.svg instead of SvgUrl from svg file. Are there any ideas how to fix it?

anthowen commented 3 years ago

@technostyle I'm getting the same issue. Were you able to fix it? Thanks in advance!

anthowen commented 3 years ago

This is the error I get. I have no idea why I get a such error image

agilgur5 commented 3 years ago

What I get now is a mysterious filename string import /static/media/my-icon.ba681e15.svg instead of SvgUrl from svg file. Are there any ideas how to fix it?

I haven't used these plugins and I haven't created an integration test for them, but hashes are pretty common for assets since that allows you to cache-bust easily.

I'm not sure why that's causing a bug, but if you want to configure it, I believe you can change @rollup/plugin-url's fileName config. It defaults to having a hash as [hash][extname]. Though the file here is a bit different, it's [name].[hash][extname]; I'm not sure how it got that. From a quick look at the @svgr/rollup internals it doesn't look like it changed the filename or even emits anything, it only implements a transform hook.

optimistiks commented 3 years ago

For Storybook users, if anyone stumbles on this, in addition to adding @svgr/rollup to tsdx.config.js as described above, I also had to install @svgr/webpack and add the following to .storybook/main.js to make it work with svgr.

  webpackFinal: async (config, { configType }) => {
    const assetRule = config.module.rules.find(({ test }) => test.test(".svg"));
    // exclude svg from the default storybook file-loader
    assetRule.exclude = /\.svg$/;

    // add svgr loader to handle svgs
    config.module.rules.push({
      test: /\.svg$/,
      use: ["@svgr/webpack"],
    });

    return config;
  },
PedroDias92 commented 3 years ago

@optimistiks i try to do what u mentioned above but didn't work. do you have a demo repository with your modifications?

MikePrus commented 2 years ago

Does anyone found a solution?