neutrino icon indicating copy to clipboard operation
neutrino copied to clipboard

svgr for react preset?

Open timkelty opened this issue 5 years ago • 6 comments

svgr allows you to import svgs as React components.

Not sure if we should consider this, but I used https://github.com/smooth-code/svgr recently, and noticed that CRA included it so I thought it was worth bringing up.

In general, I feel like since v8 we've been more judicious about including 3rd party libs like this, so maybe it would just be better as an example of how to include it yourself in the @neutrino/react docs?

timkelty avatar Dec 13 '19 19:12 timkelty

Aside from just having to deal with more 3rd party libs, I think the biggest argument against including this is there are decisions to be made about when we use the loader (all svgs, certain paths, etc).

timkelty avatar Dec 13 '19 19:12 timkelty

I think we should definitely compare @neutrinojs/react against CRA regularly, and use them both as a source of inspiration, and as a datapoint when making decisions.

Though I suppose one difference is that both technically and philosophically, CRA is very much a "one size fits many, we don't allow too much customisation" tool - which means they need to include things that not everyone will use, since end users aren't able to add them in themselves. However with Neutrino, customisation is easier, so I think the bar for inclusion can be set at a slightly different threshold.

That said, I don't have a strong opinion on this one either way - I haven't heard of the svgr project until now, but I'm not actively working on front-end projects any more so that's not a big surprise :-)

edmorley avatar Dec 13 '19 20:12 edmorley

I think the best thing to do here is have sections in the docs for "recipes" like this, rather than including it in the preset.

I think that would also get people more familiar with webpack-chain, and realize that most of the "how do I do x with Neutrino" questions are really just "how do I do x with Webpack" questions.

timkelty avatar Dec 13 '19 20:12 timkelty

But I agree we should frequently compare with CRA, (and vue-cli) to compare features. If we're missing something, we can start with including examples of how to add it yourself, and then consider adding it to presets if it is idiomatic enough.

timkelty avatar Dec 13 '19 20:12 timkelty

For anybody arriving here who just wants to know how to enable SVGR with neutrino, I believe this is the best way:

module.exports = {
  use: [
    /* ... */
    (neutrino) => neutrino.config.module
      .rule('svgr')
      .test(/\.svg$/) // you can pick whatever file extension you like here
      .issuer({ test: /\.[tj]sx?$/ }) // optional, but lets you continue importing SVGs from CSS files etc. without it breaking
      .use('@svgr/webpack')
      .loader(require.resolve('@svgr/webpack'))
      .options({ svgoConfig: { plugins: { removeViewBox: false } } }), // allow resizing SVGs (default options strip viewBox for some strange reason)
      .end()      // these next bits are not needed if your files are named '.svg' since the built-in rules do this for you
      .use('url') // but if you pick a different extension, this is needed
      .loader(require.resolve('url-loader'));

    // note that the svgr configuration MUST BE BEFORE the react preset
    react({ /* ... */ }),
    /* ... */
  ],
};

(don't forget to run npm install --save-dev @svgr/webpack too)

Usage:

import { ReactComponent as Star } from './star.svg';

const App = () => (<Star />);

If you want it to work with typescript, you need to provide a boilerplate definition for svg files, for example (definition sourced from here):

// This file lives in types/svgr.d.ts (the filename is arbitrary)

declare module '*.svg' {
  const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  const content: string;

  export { ReactComponent };
  export default content;
}

And make sure your tsconfig is configured to use that folder for types, e.g:

typescript({ tsconfig: {
  compilerOptions: {
    typeRoots: ['src/types', 'node_modules/@types'],
  },
} })

davidje13 avatar Nov 22 '20 01:11 davidje13

@davidje13 nice one, work like a sharm

neo87cs avatar Jan 08 '22 13:01 neo87cs