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

SVG import not working #2

Closed
kevinfaveri opened this issue Jan 13, 2021 · 5 comments · Fixed by #19
Closed

SVG import not working #2

kevinfaveri opened this issue Jan 13, 2021 · 5 comments · Fixed by #19
Labels
bug Something isn't working

Comments

@kevinfaveri
Copy link

Same as pradel/create-react-app-esbuild#6, but for this plugin

Maybe CRA 4 uses SVGR babel plugin and since these plugins remove the babel-loader, it breaks things?

@pradel pradel added the bug Something isn't working label Jan 13, 2021
@lpillonel
Copy link

Facing the same issue while trying this plugin

@kevinfaveri
Copy link
Author

I just took the SVGR babel plugin out of the question and created a NodeJS script to transform everything in a specified "/assets/svg" folder to a React Component.

If useful to anyone, the script works like that and is run on demand as I wish (the script ignores existing components):

const fs = require('fs');
const svgr = require('@svgr/core').default;
const template = require('./template');

async function transformSvgs() {
  const svgFiles = fs.readdirSync('./src/assets/svgs');
  for (let index = 0; index < svgFiles.length; index++) {
    const svgFile = svgFiles[index];
  
    const files = fs.readdirSync('./src/assets/svgs/components');
    if (!files.includes(svgFile.replace('.svg', '.js')) && svgFile !== 'components') {
      let svgCode = fs.readFileSync(`./src/assets/svgs/${svgFile}`).toString();
      const camelCasedComponentName = svgFile.replace('.svg', '').replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
      const capitalizedName = camelCasedComponentName.charAt(0).toUpperCase() + camelCasedComponentName.slice(1)
      const jsCode = await svgr(svgCode, {
        plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier'],
        template,
      },
      { componentName: capitalizedName });
      fs.writeFileSync(`./src/assets/svgs/components/${svgFile.replace('.svg', '.js')}`, jsCode);
    }
  }
}

transformSvgs();

@cktang88
Copy link
Contributor

Seems like this is a cleaner solution pradel/create-react-app-esbuild#6 (comment)

@phtrivier
Copy link

phtrivier commented Feb 3, 2022

What would be the clean way to fix this ? I understood the general strategy would be like this:

// craco.config.js
const CracoSwcPlugin = require('craco-swc');

module.exports = {
  plugins: [
      {
      plugin: CracoSwcPlugin
    },
  ],

  webpack: {
    configure: (webpackConfig) => {
      webpackConfig.module.rules.unshift({
        test: /\.svg$/,
        use: ['@svgr/webpack']
      });
      return webpackConfig;
    },
  }


};

As in :

  • use swc in general to compile things
  • except for those pesky svg files that need to go through the webpack plugin

(And ideally, this configuration would be done internally by the create-react-app-swc plugin, like it's done by the `create-react-app-esbuild" plugin, possibly hidden behind a flag)

However if I simply change the webpack config as done above, compiling any svg fails with:

TypeError: this.getOptions is not a function

I'm new to all this, so:

  • are there craco options to pass to get more info about the error (which part of the toolchain does it come from ?)
  • is this something fixable from craco.config.js or does the plugin need a change ?

@drefined
Copy link

drefined commented Mar 8, 2022

I hope this helps someone:

The this.getOptions is not a function error is related to the newer version of svgr, so pinning the version to 5.5.0 will fix that issue. For more information, refer to this issue: gregberge/svgr#631

npm install --save-dev @svgr/webpack@5.5.0

My craco.config.js configuration:

const CracoSwcPlugin = require('craco-swc');

module.exports = {
    plugins: [
        {
            plugin: CracoSwcPlugin,
            options: {
                swcLoaderOptions: {
                    jsc: {
                        transform: {
                            react: {
                                runtime: 'automatic',
                            },
                        },
                    },
                },
            },
        },
    ],
    webpack: {
        configure: (webpackConfig) => {
            webpackConfig.module.rules.unshift({
                test: /\.svg$/,
                issuer: /\.[jt]sx?$/,
                use: ['@svgr/webpack'],
            });
            return webpackConfig;
        },
    }
};

The automatic react runtime is required if you don't import React from 'react' in your components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants