kristerkari / react-native-svg-transformer

Import SVG files in your React Native project the same way that you would in a Web application.
MIT License
1.58k stars 116 forks source link

With Expo web: Failed to execute 'createElement' on 'Document' #119

Open divonelnc opened 3 years ago

divonelnc commented 3 years ago

Hello,

I am using Expo 39's managed workflow.

I followed the installation instruction, created the metro.config.js file, and copy-pasted the content from the instructions. I also added the packagerOpts field to my app.json.

For testing purpose, I renamed my SVG file to logo.svg and used the following code in my app:

import Logo from "../../assets/images/avatars/logo.svg"

function TestComp() {
    const size = 120;
    return <Logo width={size} height={size}/>
}

Unfortunately, I am now getting the error: InvalidCharacterError: Failed to execute 'createElement' on 'Document': The tag name provided ('/static/media/logo.6a5b59b1.svg') is not a valid name.

Any idea about what is causing the error?

I don't know if it is related, but I do have a babel.config.js file in my root folder.

kristerkari commented 3 years ago

@divonelnc I just merged a PR to update the instructions for Expo, can you check the README again if that matches the config that you have in use?

divonelnc commented 3 years ago

I tried to find what was changed. Is there something else than replacing const { getDefaultConfig } = require("metro-config"); with const { getDefaultConfig } = require("@expo/metro-config");

and await getDefaultConfig(); with await getDefaultConfig(__dirname); ?

If yes, unfortunately, it does not fix the issue. I am still getting the same error :(

It seems that these fixes are for SDK 40, but I am using SDK 39.

One info that I forgot to mention is that I am trying to make it work for Expo web.

NisuSan commented 3 years ago

It seems that these fixes are for SDK 40, but I am using SDK 39.

Nope, it isn't. I have updated my project to SDK 40 and still getting this error too =(

sreenath-n commented 3 years ago

SVG import in create-react-app should be like this:

import { ReactComponent as Logo } from "../../assets/images/avatars/logo.svg"

In native it should be like this:

import Logo from "../../assets/images/avatars/logo.svg"

The import syntax for create-react-app is different from the syntax for native. @kristerkari any way we can fix this ?

kristerkari commented 3 years ago

@sreenath-n create-react-app has it's own syntax for importing things. It's not compatible with this SVG transformer. If you want to hack around it, you could always use tools like patch-package to modify the export in this library.

richardwu commented 3 years ago

I am getting the same issue with SDK 40 with an expo managed app:

Error

Unhandled Rejection (InvalidCharacterError): Failed to execute 'createElement' on 'Document': The tag name provided ('/static/media/swiped-all.eb95b811.svg') is not a valid name

Steps taken

I have placed my SVGs under ./src/assets/.... An example import I'm doing is:

import SwipedAll from "../assets/swiped-all.svg";

Notably, if I use babel-plugin-inline-react-svg as a plugin, it works like a charm on web: however it is not compatible with mobile.

Config files

# ./metro.config.js
const { getDefaultConfig } = require("@expo/metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig(__dirname);
  console.log(sourceExts);
  console.log(assetExts);
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer"),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"],
    },
  };
})();
# app.json
{
  "expo": {
    "scheme": "topspin",  
    "name": "topspin",
    "slug": "topspin",
    "platforms": [
      "ios",
      "android"
    ],
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./src/assets/icon.png",
    "splash": {
      "image": "./src/assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true,
      "bundleIdentifier": "com.topspin.topspin",
      "googleServicesFile": "./GoogleService-Info.plist"
    },
    "android": {
      "package": "com.topspin.topspin",
      "googleServicesFile": "./google-services.json",
      "useNextNotificationsApi": true
    },
    "web": {
      "favicon": "./src/assets/favicon.png",
      "build": {
        "babel": {
          "include": ["react-router-native"]
        }
      }
    }
  }
}
# ./babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ["babel-preset-expo", "@babel/preset-typescript"],
  };
};
# package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "test": "jest --config jest.config.js"
  },
  "dependencies": {
    "@apollo/client": "^3.2.5",
    "@expo-google-fonts/inter": "^0.1.0",
    "@ptomasroos/react-native-multi-slider": "^2.2.2",
    "@react-native-community/masked-view": "0.1.10",
    "@types/jest": "^26.0.19",
    "@types/react-router-native": "^5.1.0",
    "cloudinary-core": "^2.11.3",
    "expo": "^40.0.0",
    "expo-app-loading": "^1.0.1",
    "expo-auth-session": "~3.0.0",
    "expo-cli": "^4.0.17",
    "expo-constants": "~9.3.3",
    "expo-facebook": "~9.1.0",
    "expo-file-system": "~9.3.0",
    "expo-font": "~8.4.0",
    "expo-image-picker": "~9.2.0",
    "expo-notifications": "~0.8.2",
    "expo-random": "~10.0.0",
    "expo-status-bar": "~1.0.3",
    "firebase": "7.9.0",
    "graphql": "^15.4.0",
    "native-base": "^2.13.14",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-hook-form": "^6.11.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-deck-swiper": "^2.0.5",
    "react-native-elements": "^3.0.0-alpha.1",
    "react-native-expo-viewport-units": "^0.0.8",
    "react-native-fbsdk": "^2.0.0",
    "react-native-gesture-handler": "~1.8.0",
    "react-native-reanimated": "~1.13.0",
    "react-native-safe-area-context": "3.1.9",
    "react-native-screens": "~2.15.0",
    "react-native-svg": "12.1.0",
    "react-native-web": "~0.13.12",
    "react-router-native": "^5.2.0"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "@babel/preset-env": "^7.12.11",
    "@babel/preset-typescript": "^7.12.7",
    "@expo/webpack-config": "~0.12.45",
    "@testing-library/jest-dom": "^5.11.5",
    "@testing-library/react-native": "^7.1.0",
    "@types/react": "~16.9.35",
    "@types/react-dom": "~16.9.8",
    "@types/react-native": "~0.63.2",
    "@types/react-test-renderer": "^17.0.0",
    "babel-jest": "^26.6.3",
    "babel-plugin-inline-react-svg": "^1.1.2",
    "eslint": "^7.13.0",
    "eslint-plugin-jest": "^24.1.3",
    "jest-expo": "^40.0.0",
    "node-fetch": "^2.6.1",
    "react-native-svg-transformer": "^0.14.3",
    "react-test-renderer": "^17.0.1",
    "ts-loader": "^8.0.13",
    "typescript": "~4.0.0"
  },
  "private": true
}
# ./webpack.config.js
const createExpoWebpackConfigAsync = require("@expo/webpack-config");

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(
    {
      ...env,
      babel: {
        dangerouslyAddModulePathsToTranspile: [
          "@ptomasroos/react-native-multi-slider",
        ],
      },
    },
    argv
  );
  return config;
};
andylacko commented 3 years ago

Hello, my error looks something like this, followed the instalation guide using expo40 and native 0.63.4

Uncaught DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('/static/media/list.5d2dab27.svg') is not a valid name.

this is the svg file code

<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<g>
    <path d="M90.4964,8.5662H9.3199c-2.2361,0-4.3807,0.8768-5.9619,2.4377s-2.4695,3.6777-2.4695,5.8851v66.3107
        c0,2.2074,0.8883,4.3243,2.4695,5.885c1.5812,1.5611,3.7258,2.4378,5.9619,2.4378h81.1765c2.236,0,4.3808-0.8767,5.9619-2.4378
        c1.5811-1.5607,2.4695-3.6776,2.4695-5.885V16.889c0-2.2074-0.8884-4.3242-2.4695-5.8851S92.7324,8.5662,90.4964,8.5662z
         M91.9278,83.1997c0,0.3748-0.1508,0.7342-0.4193,0.9992c-0.2685,0.2647-0.6323,0.4137-1.0121,0.4137H9.3199
        c-0.3796,0-0.7437-0.1489-1.0121-0.4137c-0.2684-0.2651-0.4192-0.6244-0.4192-0.9992V36.2246h84.0392V83.1997z M91.9278,29.2956
        H7.8885V16.889c0-0.3747,0.1508-0.7341,0.4192-0.9991c0.2684-0.265,0.6325-0.4138,1.0121-0.4138h81.1765
        c0.3797,0,0.7436,0.1489,1.0121,0.4138c0.2685,0.265,0.4193,0.6244,0.4193,0.9991V29.2956z"/>
</g>
</svg>
willtpwise commented 3 years ago

I'm getting the same issue as well. Here's a reproduction using Expo 40: https://github.com/willtpwise/react-native-svg-transformer__not-working

I've also noticed on Expo 39

DrimZ commented 3 years ago

encountered the same issue,

i solve this by adding babel-plugin-inline-react-svg as dev dependencies

then add this to your babel.config.js

{ "plugins": [ "inline-react-svg" ] }

thanks to this guy https://github.com/boopathi/react-svg-loader/issues/197#issuecomment-377562447

lucassouza16 commented 3 years ago

encontrou o mesmo problema,

eu resolvo isso adicionando babel-plugin-inline-react-svgcomo dependências de desenvolvimento

então adicione isso ao seu babel.config.js

{ "plugins": [ "inline-react-svg" ] }

graças a esse cara boopathi / react-svg-loader # 197 (comentário)

I tried to implement this solution, the SVG loaded well, but I can't change the height, width, or fill through the properties.

tsanjoto commented 3 years ago

@DrimZ used that solution, although it makes the web expo works, it breaks the ios and android simulator.

The error: Invariant Violation: View config getter callback for componentpathmust be a function (received 'undefined'). Make sure to start component names with a capital letter.

lucassouza16 commented 3 years ago

@DrimZ usou essa solução, embora faça a web expo funcionar, ela quebra o simulador ios e android.

O erro: Invariant Violation: View config getter callback for componentcaminhomust be a function (received 'undefined'). Make sure to start component names with a capital letter.

I created a temporary solution focused on the problem related to Expo, if you want you can take a look:

https://github.com/lucassouza16/react-native-svg-transformer-fix-expo

raqso commented 2 years ago

@DrimZ usou essa solução, embora faça a web expo funcionar, ela quebra o simulador ios e android. O erro: Invariant Violation: View config getter callback for componentcaminhomust be a function (received 'undefined'). Make sure to start component names with a capital letter.

I created a temporary solution focused on the problem related to Expo, if you want you can take a look:

https://github.com/lucassouza16/react-native-svg-transformer-fix-expo

I saw that you removed the repository with the temp fix and just wondering if you've found a better, permanent solution for this, maybe?

lucassouza16 commented 2 years ago

@DrimZ usou essa solução, embora faça a web expo funcionar, ela quebra o simulador ios e android. O erro: Invariant Violation: View config getter callback for componentcaminhomust be a function (received 'undefined'). Make sure to start component names with a capital letter.

I created a temporary solution focused on the problem related to Expo, if you want you can take a look: https://github.com/lucassouza16/react-native-svg-transformer-fix-expo

I saw that you removed the repository with the temp fix and just wondering if you've found a better, permanent solution for this, maybe?

Yes, the author suggested a solution to me that solved the problem for me, you can remove the workaround and implement it:

https://github.com/kristerkari/react-native-svg-transformer/issues/135#issuecomment-1008310514

haveamission commented 2 years ago

@DrimZ usou essa solução, embora faça a web expo funcionar, ela quebra o simulador ios e android. O erro: Invariant Violation: View config getter callback for componentcaminhomust be a function (received 'undefined'). Make sure to start component names with a capital letter.

I created a temporary solution focused on the problem related to Expo, if you want you can take a look: https://github.com/lucassouza16/react-native-svg-transformer-fix-expo

I saw that you removed the repository with the temp fix and just wondering if you've found a better, permanent solution for this, maybe?

Yes, the author suggested a solution to me that solved the problem for me, you can remove the workaround and implement it:

#135 (comment)

Yep, this worked for me