unimonkiez / react-native-svg-loader

Build time parsing for svgs, use any svg in your React Native app in ease
12 stars 4 forks source link

Hi, how to integrate it with Metro bundler? #1

Open kruyvanna opened 6 years ago

kruyvanna commented 6 years ago

My project has no webpack config file. I assume it is replaced with Metro bundler. If so, how to integrate it with Metro bundler?

FYI, my project is based on Ignite React Native https://github.com/infinitered/ignite

unimonkiez commented 6 years ago

Well off their documentation to add a tranformer, you simply do this:

const transformSvgSync = require('react-native-svg-loader');
// For React Native version 0.52 or later
var upstreamTransformer = require("metro/src/transformer");

// For React Native version 0.47-0.51
// var upstreamTransformer = require("metro-bundler/src/transformer");

// For React Native version 0.46
// var upstreamTransformer = require("metro-bundler/build/transformer");

module.exports.transform = function({ src, filename, options }) {
  if (filename.endsWith('.svg') {
    return transformSvgSync(src);
  } else {
    return upstreamTransformer.transform({ src, filename, options });
  }
};

Hope it works, didn't test it, or even used metro before.

Also you should check out this boilerplate, it has this loader and so much more

kruyvanna commented 6 years ago

hi @unimonkiez, thanks for showing some lights. I tried it but can't make it work yet.

I created rn-cli.config.js so that Metro will pick it up.

module.exports = {  
  assetTransforms: true,
  getPlatforms: () => ["ios", "android"],
  getTransformModulePath() {            
        return require.resolve('./svg_transformer')    
  },
  getAssetExts() {
    return ["svg"];
  }
};

below is the content of svg_transformer.js

const path = require('path')

const transformSvgSync = require('react-native-svg-loader');
var upstreamTransformer = require("metro/src/transformer");

module.exports.transform = function({ src, filename, options }) {   
    const basename = path.basename(filename)
    console.log(basename)

  if (filename.endsWith('.svg')) {
    console.log('==============================================')
    console.log('SVG!', filename)
    return transformSvgSync(src);
  } else {
    return upstreamTransformer.transform({ src, filename, options });
  }
};

I can confirm the transform method is called but the file ending with .svg does not get called.

screen shot 2018-05-30 at 11 14 34

I created a clean project to test it. You may try it here https://github.com/kruyvanna/metro-asset-transformer-test

kruyvanna commented 6 years ago

@unimonkiez the boilerplate looks promising. Will check it out on next project

kristerkari commented 6 years ago

Because of how the file extensions are defined in React Native, it seems that is not currently possible to use the .svg file extension for a transformer as React Native defines that as a basic file type that does not run through the transformer.

As a workaround, I created a transformer that uses .svgx instead of .svg as the file extension: https://github.com/kristerkari/react-native-svg-transformer

I will move to use .svg when that gets supported in future React Native version.

kristerkari commented 6 years ago

I've updated my svg transformer to support .svg extension now that React Native 0.57 was released: https://github.com/kristerkari/react-native-svg-transformer