GithubHelp home page GithubHelp logo

vite-plugin-svgr's Introduction

vite-plugin-svgr

npm

Vite plugin to transform SVGs into React components. Uses svgr under the hood.

Installation

# npm
npm install --save-dev vite-plugin-svgr

# yarn
yarn add -D vite-plugin-svgr

# pnpm
pnpm add -D vite-plugin-svgr

Usage

// vite.config.js
import svgr from "vite-plugin-svgr";

export default {
  // ...
  plugins: [svgr()],
};

Then SVG files can be imported as React components:

import Logo from "./logo.svg?react";

If you are using TypeScript, there is also a declaration helper for better type inference:

/// <reference types="vite-plugin-svgr/client" />

Options

svgr({
  // svgr options: https://react-svgr.com/docs/options/
  svgrOptions: {
    // ...
  },

  // esbuild options, to transform jsx to js
  esbuildOptions: {
    // ...
  },

  // A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should include.
  include: "**/*.svg?react",

  //  A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should ignore. By default no files are ignored.
  exclude: "",
});

If you want to enable SVGO you can install @svgr/plugin-svgo and use following options to enable and configure it:

svgr({
  svgrOptions: {
    plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx"],
    svgoConfig: {
      floatPrecision: 2,
    },
  },
  // ...
});

License

MIT

vite-plugin-svgr's People

Contributors

andresgutgon avatar bosselijah avatar endlesshollow avatar gunters63 avatar helianthuswhite avatar ianvs avatar inshiku-han avatar kamahl19 avatar meeshh avatar mehimanshupatil avatar nhardy avatar oflisback avatar ofzo avatar oumarbarry avatar pd4d10 avatar peteruithoven avatar pulkownikfgs avatar twhitbeck avatar wtchnm avatar xantredev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vite-plugin-svgr's Issues

SVG files are still included in output

vite still outputs the SVG files that svgr converted into React components in the final output. Because the SVGs are already stored within the JavaScript, it would be nice to suppress the additional file outputs.

importing types with "vite-plugin-svgr/client" does not work for "moduleResolution": "node16"

Typescript requires package exports with condition "types" for subpath imports like "vite-plugin-svgr/client" when moduleResolution node16 is enabled.

Reproduction is easy:

Create a minimal React Typescript App with Vite and add like:

npm create vite@latest node16-bug -- --template react-ts
cd node16-bug
npm install vite-plugin-svgr

Add "types": ["vite-plugin-svgr/client"] to compilerOptions in tsconfig.node.json

Change to "moduleResolution": "node16" in tsconfig.json.

Change all existing relative imports to include the extension to make them compatible to node16 resolution.

Add the svgr plugin to vite.config.ts.

Add a SVG import.

Run type check with tsc --noemit. There will be an error:

error TS2688: Cannot find type definition file for 'vite-plugin-svgr/client'.
  The file is in the program because:
    Entry point of type library 'vite-plugin-svgr/client' specified in compilerOptions

  tsconfig.json:9:30
    9     "types": ["vite/client", "vite-plugin-svgr/client"]
                                   ~~~~~~~~~~~~~~~~~~~~~~~~~
    File is entry point of type library specified here.

For an easy fix add the following to the exports in vite-plugin-svgr package.json:

    "./client": {
      "types": "./client.d.ts"
    }

Support include and exclude options.

The plugin will always change every svg file to jsx. It's not flexible, and i hope there is some options like include or exclude to specify the certain files.

SVG components should be included in the main bundle

When creating a production build, this plugin will emit SVG components as separate files instead of having them be included in the main bundle.

Example: I have an icon foo.svg in my project. When I create a production build, the output bundle will contain the file foo.hash.js

However, I would prefer that the contents of foo.hash.js file were to be included in the index.hash.js file, so that not all SVG components need to be loaded separately.

Also: SVG files are still included in the bundle as well.

Config:

svgr({
  exportAsDefault: true
}),

Default export not working after updating to 2.0.0

import {defineConfig, searchForWorkspaceRoot, UserConfig} from 'vite'
import react from '@vitejs/plugin-react'
import * as path from "path";
import svgr from 'vite-plugin-svgr';

export default defineConfig(({command, mode}) => {
  const config = {
    ....
    plugins: [react(), svgr()],
   ....
  } as UserConfig;

  return config;
})
failed to load config from /Users/ettore/Workspace/conagrivet/api/vite.config.ts
error when starting dev server:
TypeError: svgr is not a function
    at file:///Users/ettore/Workspace/conagrivet/api/vite.config.ts.js?t=1651562275412:12:24

Doing a console.debug(svgr) it shows an object with a default property. Does this have something to do with CommonJS transpilation? I see lib/index.js uses exports.default instead of ESM.

Import SVG as React component stops working after update to v3.0

After update I faced with error during the build:

"ReactComponent" is not exported by "src/components/logo/logo.svg", imported by "src/components/logo/logo.tsx".
file: /app/src/components/logo/logo.tsx:4:9

import clsx from "clsx";
import { ReactComponent as LogoImg } from "./logo.svg";

#13 63.48 RollupError: "ReactComponent" is not exported by "src/components/logo/logo.svg", imported by "src/components/logo/logo.tsx".

`vite build` fails

Hello,

for some reason svgr plugin fails with trying to build production build but works on dev.

I'm getting

[vite-plugin-svgr] ENOENT: no such file or directory, open '/Users/jb/Documents/bulbshare-web-app-react/assets/svgs/bulbshare-logo.svg?extractStyles&lang.svg'

No default export found in imported module "vite-plugin-svgr"

Getting a strange eslint warning in my vite.config.js of the svgr plugin import. The actual functionality of the plugin is working just fine.

import path from "path";
import { defineConfig, loadEnv } from "vite";
import svgr from "vite-plugin-svgr";
import react from "@vitejs/plugin-react";
import { createHtmlPlugin } from "vite-plugin-html";

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd());
  return {
    resolve: {
      alias: [{ find: "@", replacement: path.resolve(__dirname, "src") }],
    },
    plugins: [react(), svgr(), createHtmlPlugin({ inject: { data: env } })],
  };
});

The package in node_modules clearly does have a default export, so not sure what's going on here.

My eslint config
{
  "env": {
    "browser": true,
    "node": true
  },
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "plugins": ["prettier"],
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react/jsx-runtime",
    "plugin:react-hooks/recommended",
    "plugin:import/recommended",
    "plugin:jsx-a11y/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "settings": {
    "react": {
      "version": "detect"
    },
    "import/resolver": {
      "alias": {
        "map": [["@", "./src"]],
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    }
  },
  "rules": {
    "prettier/prettier": "error"
  }
}
My package.json
{
  "name": "simplex",
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext .ts,.tsx"
  },
  "dependencies": {
    "@floating-ui/react-dom": "^1.2.0",
    "@floating-ui/react-dom-interactions": "^0.13.3",
    "@react-hook/resize-observer": "^1.2.6",
    "@stitches/react": "^1.2.8",
    "@tanstack/react-query": "^4.22.0",
    "@zxcvbn-ts/core": "^2.1.0",
    "@zxcvbn-ts/language-common": "^2.0.1",
    "@zxcvbn-ts/language-en": "^2.1.0",
    "html-react-parser": "^3.0.7",
    "javascript-time-ago": "^2.5.9",
    "lodash": "^4.17.21",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-icons": "^4.7.1",
    "react-router": "^6.6.2",
    "react-router-dom": "^6.6.2",
    "react-time-ago": "^7.2.1",
    "react-use": "^17.4.0",
    "react-wrap-balancer": "^0.3.0",
    "use-query-params": "^2.1.2"
  },
  "devDependencies": {
    "@simbathesailor/use-what-changed": "^2.0.0",
    "@tanstack/react-query-devtools": "^4.22.0",
    "@types/lodash": "^4.14.191",
    "@types/node": "^18.11.18",
    "@types/react": "^18.0.26",
    "@types/react-dom": "^18.0.10",
    "@types/react-router-dom": "^5.3.3",
    "@typescript-eslint/eslint-plugin": "^5.48.1",
    "@typescript-eslint/parser": "^5.48.1",
    "@vitejs/plugin-react": "^3.0.1",
    "eslint": "^8.31.0",
    "eslint-config-prettier": "^8.6.0",
    "eslint-import-resolver-alias": "^1.1.2",
    "eslint-import-resolver-typescript": "^3.5.3",
    "eslint-plugin-import": "^2.27.4",
    "eslint-plugin-jsx-a11y": "^6.7.1",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-react": "^7.32.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "msw": "^0.49.2",
    "prettier": "^2.8.2",
    "typescript": "^4.9.4",
    "vite": "^4.0.4",
    "vite-plugin-html": "^3.2.0",
    "vite-plugin-svgr": "^2.4.0"
  },
  "msw": {
    "workerDirectory": "public"
  }
}

Anyone know what could be wrong?

I've also tried clearing node_modules and yarn.lock, and restarting VS Code.

Failed to build - Module '"svgo"' has no exported member 'OptimizeOptions'

Failed to build React TS (pnpm) project with following error:

> tsc && vite build --mode dev

node_modules/.pnpm/@[email protected]/node_modules/@svgr/core/dist/index.d.ts:2:10 - error TS2305: 
Module '"svgo"' has no exported member 'OptimizeOptions'.

import { OptimizeOptions } from 'svgo';

Packages:

"vite-plugin-svgr": "^2.4.0"
"@types/svgo": "^3.0.0"

vite.config.ts

import svgr from 'vite-plugin-svgr'

plugins: [react(), svgr(), basicSsl()]

vite, react-ts --- Module '"*.svg"' has no exported member 'ReactComponent'. ---

Hello i just installed this module in a vite/react-ts project, i'm getting this error when i'm importing an SVG

import { ReactComponent as HomeIcon } from "images/icons/IconSvg/home.svg"

The import works and the icon is shown.

I managed to get rid of the error by declaring this module

declare module "*.svg" {
  import * as React from "react";

  export const ReactComponent: React.FunctionComponent<
    React.SVGProps<SVGSVGElement> & { title?: string }
  >;

  const src: string;
  export default src;
}

It doesn't really bother me, but i was wondering if there is a " cleaner " solution

Thanks for your responses :)

SVGR Options & TypeScript

@pd4d10 Thanks for creating the plugin. Works nicely and I like that I can use both the default export for the src/path of the svg and the named export for the React component.

I was wondering if you would accept a PR to enable the plugin users to pass SVGR options (e.g. { plugins: ['@svgr/plugin-svgo'] }).

Also, I think the plugin should provide the typings to support this change to svg file imports. A simple client.d.ts with the typings suggested in #3 which is then added by the users to the tsconfig.json like "types": ["vite/client", "vite-plugin-svgr/client"] would be a solution.

[Error] Using external stories

Hi there! So, I am using Lerna and fetching stories from different packages to my Storybook Vite package.

I import your extension on the vite.config.ts as described in the docs and I get the following error:

SyntaxError: The requested module '/@fs/C:/[...]/icon.svg?import' does not provide an export named 'ReactComponent'

I tried setting an included with the path of the file:

plugins: [react(), svgr({include: '../[...]/add-round.svg'})]

But still gives the same error.

I would really appreciate any help!

Using with `@svgr/plugin-svgo` fails

Using with @svgr/plugin-svgo fails with following error.

Using vite-plugin-svgr without @svgr/plugin-svgo works.

/Users/devunt/workspace/ccoli/frontend/src/assets/logo.svg:1:102: ERROR: Expected "}" but found ":"
    at failureErrorWithLog (/Users/devunt/workspace/ccoli/frontend/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:1624:15)
    at /Users/devunt/workspace/ccoli/frontend/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:1413:29
    at /Users/devunt/workspace/ccoli/frontend/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:678:9
    at handleIncomingPacket (/Users/devunt/workspace/ccoli/frontend/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:775:9)
    at Socket.readFromStdout (/Users/devunt/workspace/ccoli/frontend/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:644:7)
    at Socket.emit (/Users/devunt/workspace/ccoli/frontend/lib/events.js:513:28)
    at Socket.emit (/Users/devunt/workspace/ccoli/frontend/lib/domain.js:489:12)
    at addChunk (/Users/devunt/workspace/ccoli/frontend/lib/internal/streams/readable.js:324:12)
    at readableAddChunk (/Users/devunt/workspace/ccoli/frontend/lib/internal/streams/readable.js:297:9)
    at Socket.Readable.push (node:internal/streams/readable:234:10) {stack: 'Error: Transform failed with 1 error:
/Users/….push (node:internal/streams/readable:234:10)', errors: Array(1), warnings: Array(0), frame: '
Expected "}" but found ":"
1  |  <svg xmlns=…                                           ^
', loc: {…}, …}
// vite.config.ts

export default defineConfig(({ mode }) => ({
  plugins: [
    react(),
    svgr({ svgrOptions: { plugins: ['@svgr/plugin-svgo'] } }),,
}));
// logo.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156.62 156.96">
  <defs>
    <style>
      .cls-1 {
        fill: #fff;
      }

      .cls-2 {
        fill: currentColor;
      }
    </style>
  </defs>
  <g>
    <path class="cls-2"
      d="M156.62,78.65c0-12.01-8.81-22.1-20.27-24.12,6.68-9.55,5.74-22.49-2.84-31.08-8.27-8.57-21.41-9.52-31.02-2.88-1.89-11.62-12.05-20.58-24.17-20.58s-22.1,8.81-24.12,20.27c-9.55-6.68-22.49-5.74-31.08,2.84-8.71,8.71-9.56,22.19-2.31,31.33C9.08,56.24,0,66.45,0,78.65s8.83,21.91,20.32,24.05c-6.73,9.56-5.81,22.54,2.79,31.15,8.6,8.3,21.58,9.18,31.14,3.19,2.16,11.3,12.16,19.93,24.05,19.93s22.2-9.17,24.15-20.78c9.39,6.86,22.74,5.98,31.39-2.67,8.51-8.51,9.51-21.3,3.03-30.83,11.21-2.23,19.74-12.19,19.74-24.02Z" />
    <g>
      <path class="cls-1"
        d="M61.33,72.59c.2-2.08,2.06-3.61,4.15-3.61h3.12c1.67,0,2.7-1.88,1.75-3.25-2.01-2.91-5.38-4.8-9.2-4.74-6.07,.09-10.84,5.29-10.84,11.36,0,3.72,0,8.56,0,12.27,0,6.06,4.74,11.25,10.79,11.36s11.21-4.85,11.21-11v-3.96c0-2.23-1.81-4.04-4.04-4.04h-2.96c-2.34,0-4.21-2.01-3.98-4.39Z" />
      <path class="cls-1"
        d="M95.33,72.59c.2-2.08,2.06-3.61,4.15-3.61h3.12c1.67,0,2.7-1.88,1.75-3.25-2.01-2.91-5.38-4.8-9.2-4.74-6.07,.09-10.84,5.29-10.84,11.36,0,3.72,0,8.56,0,12.27,0,6.06,4.74,11.25,10.79,11.36s11.21-4.85,11.21-11v-3.96c0-2.23-1.81-4.04-4.04-4.04h-2.96c-2.34,0-4.21-2.01-3.98-4.39Z" />
    </g>
  </g>
</svg>

Plugins don't work

40/5000
I'm having a problem. Your plug-in doesn't work after using it. I don't know what's wrong with the configuration. The browser returned the following error:

Uncaught DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('/src/images/smcLogo.svg') is not a valid name.

my code is this:

import React, { Component } from 'react';
import cssObj from './Logo.css';
import Icon from '@ant-design/icons';
import {ReactComponent as SMCLogo } from '@/images/smcLogo.svg';
class Logo extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (

            <div style={{width: this.props.width, height: this.props.height, paddingTop:'10px' }} >
                <div className={cssObj.LogoLeft}>
                    <Icon component={()=><SMCLogo width="70px" height="22px"  fill="#B7C1CF"/>} />
                </div>
            </div>

        );
    }
}

export default Logo;

Looking forward to your reply. thank you

SVGR outDir not working

Is set out dir svgr for build output the component in a directory is not working. Is it support?

Dynamic SVG imports?

Is there a way to import svgs dynamically?

I would love to be able to do something like this:

dynamic import hook

import { FunctionComponent } from 'preact';
import { useEffect, useRef, useState } from 'preact/hooks';

type Props = {
  name: string;
};

export const useDynamicSVGImport = ({ name }: Props) => {
  const ImportedIconRef = useRef<
    FunctionComponent<SVGSVGElement> | undefined
  >();

  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<Error>();

  useEffect(() => {
    setLoading(true);

    const importIcon = async (): Promise<void> => {
      try {
        const imported = await import(`../../assets/icons/${name}.svg`).then(
          module => module.default,
        );

        // logs: /src/assets/icons/spinner.svg if I pass name = spinner
        console.log('imported', imported); 

        ImportedIconRef.current = imported;
        
      } catch (err) {
        console.log(err);

        setError(err);
      } finally {
        setLoading(false);
      }
    };

    importIcon();
  }, [name]);

  return {
    loading,
    error,
    SvgIcon: ImportedIconRef.current,
  };
};

Note: If I pass SvgIcon to the src of an img tag it renders the icon properly so it is being imported.

icon.tsx

import { FunctionComponent } from 'preact';

import { useDynamicSVGImport } from '~/hooks/icons/use-dynamic-import';

type Props = {
  name: string;
  className?: string;
  isOutlineIcon?: boolean;
};

export const Icon: FunctionComponent<Props> = ({
  name,
  className,
  isOutlineIcon = false,
  ...restProps
}) => {
  const { error, loading, SvgIcon } = useDynamicSVGImport({ name });

  if (error || !SvgIcon || loading) {
    return null;
  }

  return (
    <SvgIcon
      className={`
        fill-slate-400
        ${isOutlineIcon ? '' : 'fill-current'}
        ${className ? className : 'h-5 w-5 text-lightBlack'}`}
      {...restProps}
    />
  );
};

This is currently not working.

How can I convert the imported file into a component?

    const imported = await import(`../../assets/icons/${name}.svg`).then(
          module => module.default,
        );

export default react component

Yo, tried to submit a pr but I have no permissions so leaving this here since it's what worked for me:

replace client.d.ts with the followng:

// https://github.com/facebook/create-react-app/blob/0ee4765c39f820e5f4820abf4bf2e47b3324da7f/packages/react-scripts/lib/react-app.d.ts#L47-L56

declare module '*.svg' {
  import * as React from 'react'

  export const ReactComponent: React.FunctionComponent<
    React.SVGProps<SVGSVGElement> & { title?: string }
  >

  export default ReactComponent
}

not sure if there is a way to make this conditional based on the exportDefault config option I'm afraid, that would be nicer..

maybe include both? my typescript doesn't seem to mind:

declare module '*.svg' {
  import * as React from 'react'

  export const ReactComponent: React.FunctionComponent<
    React.SVGProps<SVGSVGElement> & { title?: string }
  >
  export default ReactComponent
}

declare module '*.svg' {
  import * as React from 'react'

  export const ReactComponent: React.FunctionComponent<
    React.SVGProps<SVGSVGElement> & { title?: string }
  >
  const src: string;
  export default src;
}

I understand now why the other plugins have the ?component and ?url options

Multiple default exports when using "ref: true"

Using ref: true in svgrOptions causes build failure with the following message:

[VITE]   Multiple exports with the same name "default"
[VITE]   6  |  const ForwardRef = forwardRef(ReactComponent);
[VITE]   7  |  export default ForwardRef;
[VITE]   8  |  export default "/images/no-invitations.svg"
[VITE]      |         ^

This is happening because svgr outputs export default ForwardRef rather than export default ReactComponent, and the referenced code fails to replace default export:

'export default ReactComponent',

Pass svgr config options

Hey @pd4d10 great work on the plugin. I was wondering there's a way to pass svgr config options like
{ "ref": true }
to pass a ref to my component.

Or is there a way to pass refs without that?

Cannot build with default export and typescript

Hello 👋,

When using default export, and running vite build, I got this error :

error TS2322: Type '{ class: string; }' is not assignable to type 'IntrinsicAttributes'.
  Property 'class' does not exist on type 'IntrinsicAttributes'.

I do not have this error when running dev server / or using named imports.
I am running Preact.

// tsconfig.json
{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "jsxImportSource": "preact",
    "baseUrl": ".",
    "types": [
      "vite/client",
      "vite-plugin-svgr/client"
    ],
    "paths": {
      "@/*" : ["src/*"],
      "react": ["./node_modules/preact/compat/"],
      "react-dom": ["./node_modules/preact/compat/"]
    },
    "typeRoots": ["node_modules/@types", "src/@types"],
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
// vite.config.ts
  plugins: [
    preact(),
    svgr({
      exportAsDefault: true,
      svgrOptions: {
        svgoConfig: {
          prefixIds: false
        }
      }
    }),
  ],
// svg.d.ts
/// <reference types="vite-plugin-svgr/client" />

declare module "*.svg" {
  const content: any;
  export default content;
}

Sourcemaps (+possible implementation)

It would be great to add sourcemaps support to this project. I think it should be possible to do it using magic-string (npm link).

The implementation might look like this:

        // ... transform code
        const res = await transformWithEsbuild(componentCode, id, {
          loader: 'jsx',
          ...esbuildOptions,
        })

        return {
          code: res.code,
          map: new MagicString(res.code).generateMap({
            source: id,
          }),
        }

typescript vite config file error

when I try to put this command:

import svgrPlugin from 'vite-plugin-svgr'

in the vite.config.ts file, I get this error from the compiler:

Module '".../node_modules/vite-plugin-svgr/lib/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag
[index.d.ts(9, 1): ]()This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.

although the error is not preventing the plugin to run but would still like to know how to get this resolved, thanks.

[Help] Issue pulling in svgr types.

I recently updated to module version 2.2.1 and noticed that I now have a hard-to-figure-out error in my tsconfig.json in relation to this plugin.

Interestingly, this is fine in my vite.config.ts. Is it expected to include tsconfig.json in it's own includes?

tsconfig.json

Cannot find type definition file for 'vite-plugin-svgr/client'.
  The file is in the program because:
    Entry point of type library 'vite-plugin-svgr/client' specified in compilerOptions

at

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "types": ["vite/client", "@types/vite-plugin-svgr/client", "@types/react", "jest"],
    ...
    }
  "files": [ // is it expected to include tsconfig.json here?
    "vite.config.ts",
    "public/source-env.js",
  ],
  "include": [
    "src",
    "env/*.js",
    "src/**/*.test.ts",
  ]
}

package.json

"devDependencies": {
    "vite-plugin-svgr": "^2.2.1",
    ...
}

Custom configs for different paths?

Is there a way I can use this plugin so that it treats different paths differently? I would like to treat an icon package with some custom options and one way I would do that in webpack is like this, using two matchers:

const svgrOptionsForUnicons = {
  svgProps: {
    height: 24,
    width: 24,
  },
}

module.exports.webpackRules = [
  {
    test: uniconsRegExp,
    use: [
      {
        loader: '@svgr/webpack',
        options: svgrOptionsForUnicons,
      },
    ],
  },
  {
    test: function (path) {
      return /\.svg$/.test(path) && !uniconsRegExp.test(path)
    },
    use: ['@svgr/webpack'],
  },
]

This allows me to have most icons with a set height and width, while leaving all other svgs untouched.

I see the current approach is kind of crude, but maybe one could wrap the loader somehow? Everything is possible, of course, but I would like to stick to the most conventional way, if possible.

Build failure due to duplicate identifier

Hi, I am getting the following error when building:

❯ yarn build
yarn run v1.22.17
$ tsc && vite build
../node_modules/vite-plugin-svgr-component/client.d.ts:3:18 - error TS2300: Duplicate identifier 'src'.

3   export default component;
                   ~~~~~~~~~

  ../node_modules/vite/client.d.ts:88:18
    88   export default src
                        ~~~
    'src' was also declared here.

../node_modules/vite/client.d.ts:88:18 - error TS2300: Duplicate identifier 'src'.

88   export default src
                    ~~~

  ../node_modules/vite-plugin-svgr-component/client.d.ts:3:18
    3   export default component;
                       ~~~~~~~~~
    'src' was also declared here.


Found 2 errors in 2 files.

Errors  Files
     1  ../node_modules/vite-plugin-svgr-component/client.d.ts:3
     1  ../node_modules/vite/client.d.ts:88
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

It seems that both Vite and the plugin define the module *.svg.

I tried to add this line:

/// <reference types="vite-plugin-svgr-component/client" />

to vite-env.d.ts but no luck. I also tried to add another definition for *.svg?component and add this suffix to the imports. This solved the issue for Typescript but the imports now fail. What should I do?

Source Map

When I enable source-maps. I see the following in the terminal when I build:

Sourcemap is likely to be incorrect: a plugin (vite:svgr) was used to transform files, but didn't generate a sourcemap for the transformation.

Issue using with typescript

The @svgr/rollup package works well when used directly in a vite project.

When I switch to this plugin it says:

[plugin:vite:svgr] Transform failed with 1 error:
E:/GitHub/skyline-overlay/src/assets/jobs/thm.svg:4:29: error: Expected ")" but found ":"

E:/GitHub/skyline-overlay/src/assets/jobs/thm.svg:4:29

Expected ")" but found ":"
2  |  import { SVGProps } from "react";
3  |  
4  |  const ReactComponent = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" width="1em" height="1em" className="g-icon" {...props}><path d="M228 513q11 0 18 3 10 4 20 13.5t16 21.5q2 4 3 4l1-2q9-11 32-12 27-1 54 17 8 6 21 24 6 9 7 8.5t-1-8-6-15.5l-2-3q-4-8-7-13-7-9-17.5-16.5T343 523q-8-2-13-4-7-4-15-12-25-25-20-42 2-5 12-10-6-3-12-3-13 0-24-5-9-3-17.5-18.5T243 397q-1-6-.5-19t.5-19q-2-12-7-21-19-27-45-48-10-8-21-12 3 7 9 12.5t11 17.5q8 18 8 37 0 10-9 29.5t-9 29.5 7 21q4 6 14 16 8 9 10.5 13t2.5 10.5-2 8-9.5-1.5-18.5-10q-5-4-14.5-13.5T154 434q-9-7-21-9 1 4 4 6v1q22 20 28 37 2 6 2 18.5t3 16.5q4 6 15 16.5t14 10.5l1-2q8-16 28-16zm98-249q9 13 21 38t15.5 38.5T366 374q1 17-1 22-1 8-5 15 0-14-10-34-6-13-27-30l-6-5q-5-4-11-6l-5-1 11 15q10 13 14 24 8 19 8 44 0 11-9 29l-4 7q-1 5 1.5 16t7 17 14 11.5 20.5 8 26 11.5 28 22.5 26 29 17.5 23.5 6.5 16l3-4q2-7-1-15v-1q-15-52-40-85-15-19-24-40-8-18-9-33-2-20 11-40.5t12-32-4-21.5l3 2q4 4 6 10 2 7 2 17 0 4-4 17-7 25-4.5 38.5T444 463q7 9 9 11 6 10 8 23 2-5 2-10 0-3 2.5-14.5t6-18 12-15 12.5-9 8 3.5q3-18 1-36-2-24-39-59-20-18-32-46-13-30-14-65-2-43 41-85l3-3 13-15-13 7q-17 10-34 25-22 20-45 55-9 14-11 29-3 13 0 21 1 3 5.5 13.5T385 288q1 7 1 13l-5-10q-6-11-11-17-10-10-22-18-8-6-27-16-12-7-23-10l-8-3 12 12q15 13 24 25zm187 237q1 7-4.5 13.5T498 521t-9-5q-2-3-3-6-2 1-6 9t-4 19q0 18 14 37l18 25 1-4q1-4 0-6.5t-3-5.5q-4-6-4-13-1-15 8-27 3-5 7.5-8t8-1 1.5 10l-4 8q7-1 11-6 15-15 17-33t-8-28q-16-16-14-28 1-9 6-20 4-10 9-17l4-7q10-14 10-18-9 9-18 19-13 15-25 33-4 7-9.5 18.5T500 481l2 2q10 7 11 18zm89-74q4-5 14-15 19-18 26-26 12-15 16-29 2-7 2-24v-8q3 4 4 9 3 13 1 26-1 9-6 21.5T646 405t-21.5 24.5T606 446l-12 7 3 4q4 5 4 10-1 20-14 29-17 13-20 17.5t-2 10.5q3-4 8-6.5t10 1.5q2 2 1.5 6.5T582 533l-17 23q-8 10-11.5 22.5T553 603l3-9q5-11 10-19 18-26 39-37 15-8 34-13l2-11q3-13 10-21 7-10 18-16.5t19-6.5l5-1q14-1 18-2t11-6q9-6 15-13 9-10 13-22l2-9-5 6q-7 7-11 9-6 4-26 5l-8 1q-7 2-13 7l-9 6q0-4 2-8.5t8-10.5q8-10 17-14 22-10 32-22 7-7 10-17 1-6 2-17.5t2-16.5q4-23 27-43 20-16 44-24-8-1-16-1-18 3-35 10-24 9-40 29l-2 2q-6 8-10 11-7 5-14 3-13-4-14-24l1-13q0-17-.5-25t-8.5-24-17-29q-13-19-30-36-14-13-31-21 4 7 9 12 14 13 20 26 9 23 9 49 0 31-16 54-8 10-24.5 25.5T587 348q-2 13 4 24 4 10 2 21v1q-2 17-8 26l-23 34q0 1 16-9t24-18zm235 17q-6 6-13 15l-5 8q-6 7-12 10-4 1-12 2l-3 1q-8 1-17 0 6-7 11-16 3-6 4.5-19t0-27-6-26.5-9-19.5-11.5-12l4 9q2 3 2.5 17.5T769 417q-1 10-5 18-3 5-9 12.5t-9 12.5q-7 11-16.5 19T704 494q-31 14-49 32-7 7-14 20l-6 13q7-5 14-11 4-3 15.5-9t20.5-8.5 23-2 22 3.5q12 4 22 11 4-11 11-20 11-15 26-17l6-1q10 0 15-1 9-3 15-9 9-8 14-24l4-12q4-8 14-18l10-9q-17 0-30 12zm-96 226q-10 0-18 11-4 6-9 21-4 10-6.5 14t-8 7-10.5 0q-9-7-3-25 3-8 21-27l8-10q25-29 25-57 0-18-11-29.5T700 563q-31 0-46 21-1 1-2.5 1t-2.5-1q-4-7-9.5-12t-11.5-6-8 1l3 4q3 5 2 10-2 11-33 25-22 10-52 13-17 2-44 2h-2q-27 0-44-2-30-3-52-13-32-14-33-25h-1q-1-7 6-14-3-2-8.5-1t-11.5 6-9 12q-1 1-3 1t-2-1q-16-21-46-21-18 0-29.5 11.5T249 604q0 27 26 57l8 10q18 19 20 27 7 18-3 25-5 3-10.5 0t-7.5-7-6-14q-5-15-10-21-7-11-18-11-21 0-27 19-4 11 0 19t8 8v-6q1-6 4-9 5-6 12-6 5 0 8.5 4t5.5 10q6 19 14 27t14.5 11.5T302 751t14-3l3-3q1 13 6 25 7 18 23 29 6 4 16.5 9.5T381 818q12 8 22 19v8q0 5 8 11 10 7 27 12 24 7 57.5 7t56.5-7q17-5 27-12 8-6 8-11v-8q10-11 22-19 6-4 16.5-9.5T642 799q16-11 23-29 4-12 5-25l4 3q5 3 13 3t15-3.5 15-11.5 14-27q1-5 5-9t8-4q7-1 12 5 3 3 4 10l1 5q4 0 8-8t0-19q-7-19-28-19zm-399 33q-4 7-12 11v-5q0-6-2-12-4-10-13-20l-4-6q-19-22-22-34.5t1.5-23T302 600q14-6 32 9 9 8 14 18 3 7 3 13t-2 9-5 3q-6 0-8-3t-3-6q-6 0-5 12.5t13 16.5q5 1 10 0l1 4q0 5-2 11-2 8-8 16zm318 11q-8-4-13-11.5t-7-15.5q-2-6-2-11l1-5q5 2 10 1 12-4 12.5-16.5T657 643q-1 3-3 6t-8 3q-3 0-5-3t-2-9 3-13q5-10 14-18 18-15 32-9 7 3 11.5 13.5t1.5 23-22 34.5l-5 6q-8 10-12 20-2 7-2 12v5z" /></svg>;
   |                               ^
5  |  
6  |  export { ReactComponent };

    at failureErrorWithLog (E:\GitHub\skyline-overlay\node_modules\.pnpm\[email protected]\node_modules\esbuild\lib\main.js:1493:15)
    at E:\GitHub\skyline-overlay\node_modules\.pnpm\[email protected]\node_modules\esbuild\lib\main.js:1282:29
    at E:\GitHub\skyline-overlay\node_modules\.pnpm\[email protected]\node_modules\esbuild\lib\main.js:629:9
    at handleIncomingPacket (E:\GitHub\skyline-overlay\node_modules\.pnpm\[email protected]\node_modules\esbuild\lib\main.js:726:9)
    at Socket.readFromStdout (E:\GitHub\skyline-overlay\node_modules\.pnpm\[email protected]\node_modules\esbuild\lib\main.js:596:7)
    at Socket.emit (node:events:390:28)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)
    at Socket.Readable.push (node:internal/streams/readable:228:10)
    at Pipe.onStreamRead (node:internal/stream_base_commons:199:23

It seems to indicate that Vite can't properly handle TS file output via SVGR.

How to reproduce:

https://github.com/dsrkafuu/skyline-overlay

My project above works well now when not using the typescript svtg option in vite.config.ts, when uncommenting the option and the issue occurs.

https://github.com/dsrkafuu/skyline-overlay/blob/7a4e49440f39aea1d7ef8338f7e9a3165c6e9cf7/vite.config.ts#L13-L17

Error with Yarn Berry

Current Behavior

[plugin:vite:svgr] vite-plugin-svgr tried to access esbuild, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.

Possible Solution

Add esbuild to the manifest's dependencies field.

Steps to reproduce the problem

  1. Use Yarn as package manager
    yarn create vite [PROJECT_NAME] --template react
  2. yarn set version berry
  3. Install and configure vite-plugin-svgr plugin (as per instructions)
  4. Start dev server

Possible Implementation

See PR #16

Specifications

  • vite-plugin-svgr 0.4.0
  • Yarn 3.0.1
  • Node 14.17.5

Storybook: TypeError: module.ReactComponent is not a function

The issue

Hi, we're trying to move vite-plugin-svgr to latest version but we're getting this error.

image

We load our SVGs components in async mode with a code like this:

  const [Svg, setSvg] = useState<JSX.Element>(null)
  const file = iconNames[name]
  const iconColor = colors.textColors[color]

  useEffect(() => {
    let unmounted = false

    const fetchIcon = async () => {
      const module = await import(`../../assets/icons/${file}.svg`)

      if (unmounted) return

      setSvg(
        module.ReactComponent({
          ref,
          className: cn('fill-current', className, iconColor, {
            'w-4 h-4': small,
          }),
        })
      )
    }

    fetchIcon()

    return () => {
      unmounted = true
    }
  }, [name, iconColor, className])

  if (!Svg) return <div className='w-4 h4' />

  return Svg
})

Versions

Storybook: 6.5.10
Vite 2.9.13
vite-plugin-svgr: 2.2.1

Any idea of what could be the issue. I see that you did a big change in the way the React component is created but I don't know how to relate to Vite version.

The latest version that is working for us is Vite 1.1.0

No filePath info provided to template file

Hi there, thanks for putting this together!

I'm working with a template that has some conditional logic depending on where the SVG is sourced.

// Example
if (context.options.state.filePath.includes("glyphs/")) {
// ...

This works totally fine when using @svgr/cli

npx @svgr/cli --template template.js -- src/glyphs/plus.svg

However, when using this plugin, the filePath attribute is no longer available.

console.log(context.options.state)
// { componentName: 'ReactComponent' }

How to build the svg to js?

If I want to build the SVG into js what should I do? I will get an error "'ReactComponent' is not exported by src/icon/logo.svg, imported by src/App.jsx" if I only set the exportAsDefault to be true. Thanks to everyone!

Internal server error: No "exports" main defined

I'm receiving the following error upon tuning my Vite+React app:

12:57:46 PM [vite] Internal server error: No "exports" main defined in ~/app/node_modules/vite-plugin-svgr/node_modules/@svgr/core/package.json imported from ~/app/node_modules/vite-plugin-svgr/dist/index.mjs
  Plugin: vite-plugin-svgr
  File: ~/app/src/components/icons/affiliates-manage-icon.svg
      at new NodeError (node:internal/errors:372:5)
      at throwExportsNotFound (node:internal/modules/esm/resolve:472:9)
      at packageExportsResolve (node:internal/modules/esm/resolve:693:7)
      at packageResolve (node:internal/modules/esm/resolve:935:14)
      at moduleResolve (node:internal/modules/esm/resolve:1003:20)
      at defaultResolve (node:internal/modules/esm/resolve:1218:11)
      at ESMLoader.resolve (node:internal/modules/esm/loader:580:30)
      at ESMLoader.getModuleJob (node:internal/modules/esm/loader:294:18)
      at ESMLoader.import (node:internal/modules/esm/loader:380:22)
      at importModuleDynamically (node:internal/modules/esm/translators:106:35)

This is my vite.config.ts

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import svgr from 'vite-plugin-svgr';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), svgr()],
  resolve: {
    alias: {
      src: path.resolve(__dirname, './src'),
    },
  },
});

We use the same usage logic according to https://www.npmjs.com/package/vite-plugin-svgr

These are the versions of the packages we use:

"react": "^18.2.0",
"vite": "^3.0.0"
"vite-plugin-svgr": "^2.2.0",
"@vitejs/plugin-react": "^2.0.0",

Preact `class` is ignored

First off, thanks for making this! Please let me know if this should go to the SVGR repo, because it's definitely possible.

I'm using Preact and my config in vite.config.ts (sorry, private repo) looks like this:

    svgr({
      exportAsDefault: true,
      svgrOptions: {
        // Types are out of sync with package & docs
        // https://react-svgr.com/docs/options/#jsx-runtime-import-source
        // @ts-ignore
        jsxRuntimeImport: {
          importSource: 'preact',
          specifiers: ['h'],
        },
      },
    }),

Note: I originally used jsxRuntime: 'classic-preact', but for one reason or another (it's been a bit) it didn't work, so that's how I ended up here. As you can see there seem to be some mismatches between docs and the types, at least—maybe the logic, too.

Passing class rather than className, as is the standard in Preact, means the value is effectively ignored. It's a small thing and I can just use className here, but I thought it was worth pointing out.

Expectation

Given foo.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="foo default-class" viewBox="0 0 16 16">
  <!---->
</svg>

The following code in Preact:

import Foo from './foo.svg';

<Foo class="bar" />;

Should render:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bar" viewBox="0 0 16 16">
  <!---->
</svg>

But it renders:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="foo default-class" viewBox="0 0 16 16">
  <!---->
</svg>

The below produces the expected result:

import Foo from './foo.svg';

<Foo className="bar" />;

Vite 4 Support

Attempting to upgrade Vite to version 4. Seems vite-plugin-svgr only supports up to version 3.

npm ERR! Could not resolve dependency:
npm ERR! peer vite@"^2.6.0 || 3" from [email protected]
npm ERR! node_modules/vite-plugin-svgr
npm ERR!   dev vite-plugin-svgr@"2.2.2" from the root project

Temporary workaround in package.json:

"overrides": { "vite-plugin-svgr": { "vite": "4" } },

Vite 3 compatibility

What?

Hi 👋 first of all thanks a lot for this plugin it's awesome. I had a question related with Vite 3 compatibility.
How difficult would be to make this plugin compatible with v3 of Vite?

It is not work when build.

When build my project. All svgs build in public. Could i build svg inline not in public?
Here is my config.

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import svgrPlugin from 'vite-plugin-svgr';

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [svgrPlugin(), react()],
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.