neutrinojs / neutrino

Create and build modern JavaScript projects with zero initial configuration.
https://neutrinojs.org
Mozilla Public License 2.0
3.95k stars 213 forks source link

svgr for react preset? #1507

Closed timkelty closed 8 months ago

timkelty commented 4 years ago

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 commented 4 years ago

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).

edmorley commented 4 years ago

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 :-)

timkelty commented 4 years ago

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 commented 4 years ago

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.

davidje13 commented 3 years ago

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'],
  },
} })
neo87cs commented 2 years ago

@davidje13 nice one, work like a sharm