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

Importing SVG as react component does not work as mentioned in the docs. #7587

Open
ghost opened this issue Jan 21, 2022 · 11 comments · May be fixed by #7711
Open

Importing SVG as react component does not work as mentioned in the docs. #7587

ghost opened this issue Jan 21, 2022 · 11 comments · May be fixed by #7711
Labels
Stale Ignore This issue is exempt from getting flagged as stale and autoremoved SVG

Comments

@ghost
Copy link

ghost commented Jan 21, 2022

🐛 bug report

I am trying to import SVG as react component based on the documentation from parcel site. Instead of the svg being rendered as a component in the page, the build actually fails. With an error - @parcel/core: No transformers found for src/assets/logo.jsx with pipeline: 'jsx'.

🎛 Configuration (.babelrc, package.json, cli command)

Using default babel configuration.

// package.json

{
  "name": "parcel-react-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "parcel src/index.html"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@parcel/transformer-svg-react": "^2.2.1",
    "parcel": "^2.2.1"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}
// .parcelrc

{
  "extends": "@parcel/config-default",
  "transformers": {
    "jsx:*.svg": ["...", "@parcel/transformer-svg-react"]
  }
}

🤔 Expected Behavior

The svg image should be loaded as a react component in the webpage.

😯 Current Behavior

An error is thrown saying @parcel/core: No transformers found for src/assets/logo.jsx with pipeline: 'jsx'.

💁 Possible Solution

🔦 Context

I am trying to import a svg image as a react component.

💻 Code Sample

Clone this repo and run yarn && yarn run dev

🌍 Your Environment

Software Version(s)
Parcel 2.2.0
Node 16.13.2
npm/Yarn 8.1.2 / 1.22.17
Operating System Windows 10

Attachments:

error shown in browser

@hamzamihaidanielx
Copy link

Im getting the very same, this is for quite a while. No one has got a workaround or a fix for it yet right?

@jeb5
Copy link

jeb5 commented Feb 1, 2022

One possible workaround is to add "jsx:*": ["..."] below your existing svg transformer.

@ghost
Copy link
Author

ghost commented Feb 1, 2022

One possible workaround is to add "jsx:*": ["..."] below your existing svg transformer.

This actually makes it work. Should i consider this issue to be resolved?

@hamzamihaidanielx
Copy link

No, its not resolved, this is a workaround not a fix.

@MLNW
Copy link

MLNW commented Feb 24, 2022

One possible workaround is to add "jsx:*": ["..."] below your existing svg transformer.

When we apply this workaround the error is gone but parcel gets stuck Optimizing index.html...

Our .parcelrc:

{
    "extends": "@parcel/config-default",
    "transformers": {
        "jsx:*.svg": ["...", "@parcel/transformer-svg-react"],
        "jsx:*": ["..."],
        "*.{js,mjs,jsx,cjs}": ["@parcel/transformer-js", "@parcel/transformer-react-refresh-wrap"]
    }
}

By removing the last line, starting with *.{js,mjs,jsx,cjs}" it suddenly works, though I am unsure if we still require this pipeline.

EDIT: Sadly there are still issues which I am unable to diagnose as the Website simply does not render. The only error I get is this:

grafik

@oe
Copy link

oe commented Apr 22, 2022

same issue with "@parcel/transformer-svg-react": "^2.5.0"

@astegmaier
Copy link
Contributor

@MLNW - I hit the same error that you did - I think it's related to #7389

I found two workarounds: (1) remove inline style props on any svgs you are importing through your jsx:*.svg named pipeline or (2) remove the @transformer/svg plugin from that pipeline (i.e. remove the "..." entry, which includes this by default). The final config that worked for me was:

{
  "extends": "@parcel/config-default",
  "transformers": {
    "jsx:*.svg": ["@parcel/transformer-svg-react"]
    "jsx:*": ["..."]
  }
}

@MLNW
Copy link

MLNW commented Nov 1, 2022

@astegmaier I somehow missed your comment. It looks promising. Sadly I have moved on from the project for now so I can't test your solution at the moment

@github-actions github-actions bot removed the Stale Inactive issues label Nov 1, 2022
@mischnic mischnic added the Stale Ignore This issue is exempt from getting flagged as stale and autoremoved label Dec 8, 2022
@jboler
Copy link

jboler commented Mar 1, 2023

My project uses SVG files in 2 ways:

  1. Inline React components
import Icon from "./icon.svg";

function Component() {
  return <Icon />;
}
  1. As img src
import icon from "./icon.svg";

function Component() {
  return <img src={icon} />;
}

To make parcel work with this I had to:

  1. Rename inlined SVG files to *.jsx.svg
  2. Update .parcelrc
  "transformers": {
    "*.jsx.svg": ["@parcel/transformer-svg-react"],
    "*.{js,mjs,jsx,cjs,ts,tsx}": [
      "@parcel/transformer-js",
      "@parcel/transformer-react-refresh-wrap"
    ]
  }
  1. Add a type definition:
declare module '*.jsx.svg' {
  import { FunctionComponent, SVGProps } from 'react';

  const svg: FunctionComponent<SVGProps<SVGSVGElement> & { title?: string }>;
  export default svg;
}

declare module '*.svg' {
  const src: string;
  export default src;
}

It's not ideal because I cannot use the same image file both inline and as image but it works.

@mischnic mischnic added the SVG label Mar 1, 2023
@SrBrahma
Copy link

SrBrahma commented Jan 4, 2024

While #7587 (comment) works, this named pipeline conflicts with Storybook's webpack. Anyway to have it working without the named pipeline?

@SrBrahma
Copy link

SrBrahma commented Jan 4, 2024

I kept the named pipeline and created this webpack plugin so storybook can remove the jsx: from the import:

module.exports = function (source) {
    return source.replace(/import\('jsx:(.*\.svg)'\)/g, "import('$1')")
}

And have it in the storybook's webpack rules' array:

{
    test: /\.(ts|tsx)$/,
    use: [
        {
            loader: path.resolve(__dirname, 'renameJsxImport.js'),
        },
    ],
},

oyamauchi added a commit to rewiringamerica/embed.rewiringamerica.org that referenced this issue Jan 29, 2024
## Description

The SVG project icons can't be included via `<img>` because they
are colored using `currentColor`. They also can't be included via
Parcel's `bundle-text` named pipeline becase

The way we used `<sl-icon>`, it was fetching the svg file over the
network and dynamically inserting it into the DOM. This instead uses
another Parcel plugin to import an svg file as a React component at
build time. Getting it to work is kinda finicky. Ssee
parcel-bundler/parcel#7587, plus the workaround I ended up using in
the not-merged PR parcel-bundler/parcel#7711. The list of transformers
for `jsx:*.{js,jsx}` is copied from Parcel's default config for those
file types.

The icons are set to width `1em` to allow them to be sized by the
font-size at the usage site, like `<sl-icon>`.

## Test Plan

Look at the project icons in all contexts where they appear: project
multiselect, icon tab bar in pill mode, icon tab bar in dropdown mode.
oyamauchi added a commit to rewiringamerica/embed.rewiringamerica.org that referenced this issue Feb 5, 2024
## Description

The SVG project icons can't be included via `<img>` because they
are colored using `currentColor`. They also can't be included via
Parcel's `bundle-text` named pipeline becase

The way we used `<sl-icon>`, it was fetching the svg file over the
network and dynamically inserting it into the DOM. This instead uses
another Parcel plugin to import an svg file as a React component at
build time. Getting it to work is kinda finicky. Ssee
parcel-bundler/parcel#7587, plus the workaround I ended up using in
the not-merged PR parcel-bundler/parcel#7711. The list of transformers
for `jsx:*.{js,jsx}` is copied from Parcel's default config for those
file types.

The icons are set to width `1em` to allow them to be sized by the
font-size at the usage site, like `<sl-icon>`.

## Test Plan

Look at the project icons in all contexts where they appear: project
multiselect, icon tab bar in pill mode, icon tab bar in dropdown mode.
oyamauchi added a commit to rewiringamerica/embed.rewiringamerica.org that referenced this issue Feb 6, 2024
## Description

The SVG project icons can't be included via `<img>` because they
are colored using `currentColor`. They also can't be included via
Parcel's `bundle-text` named pipeline becase

The way we used `<sl-icon>`, it was fetching the svg file over the
network and dynamically inserting it into the DOM. This instead uses
another Parcel plugin to import an svg file as a React component at
build time. Getting it to work is kinda finicky. Ssee
parcel-bundler/parcel#7587, plus the workaround I ended up using in
the not-merged PR parcel-bundler/parcel#7711. The list of transformers
for `jsx:*.{js,jsx}` is copied from Parcel's default config for those
file types.

The icons are set to width `1em` to allow them to be sized by the
font-size at the usage site, like `<sl-icon>`.

## Test Plan

Look at the project icons in all contexts where they appear: project
multiselect, icon tab bar in pill mode, icon tab bar in dropdown mode.
oyamauchi added a commit to rewiringamerica/embed.rewiringamerica.org that referenced this issue Feb 9, 2024
## Description

The SVG project icons can't be included via `<img>` because they
are colored using `currentColor`. They also can't be included via
Parcel's `bundle-text` named pipeline becase

The way we used `<sl-icon>`, it was fetching the svg file over the
network and dynamically inserting it into the DOM. This instead uses
another Parcel plugin to import an svg file as a React component at
build time. Getting it to work is kinda finicky. Ssee
parcel-bundler/parcel#7587, plus the workaround I ended up using in
the not-merged PR parcel-bundler/parcel#7711. The list of transformers
for `jsx:*.{js,jsx}` is copied from Parcel's default config for those
file types.

The icons are set to width `1em` to allow them to be sized by the
font-size at the usage site, like `<sl-icon>`.

## Test Plan

Look at the project icons in all contexts where they appear: project
multiselect, icon tab bar in pill mode, icon tab bar in dropdown mode.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Stale Ignore This issue is exempt from getting flagged as stale and autoremoved SVG
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants