Search code examples
react-nativereact-native-fs

React-native packager configuration - How to include .zip file in bundle?


My problem:

  • I have a zip file that contains a firmware update for my company's device
  • I want to be able to access it using react-native-fs with the code below

.

export function readAssetFile(name) {
  if(Platform.OS === 'ios') {
    return RNFS.readFile(`${RNFS.MainBundlePath}/assets/data/${name}`);
  } else {
    return RNFS.readFileAssets(`raw/${name}`, 'base64');
  }
}

My project structure looks like:

ProjectDir
  android
  data
    image1.png
    image2.png
    firmwarefile.zip
  ios

The android branch works, because I added a build step in my .gradle to copy firmwarefile.zip into ProjectDir/android/app/src/main/assets/raw. So I can call readAssetFile('firmwarefile.zip'), and it returns the data.

On iOS, all the image files (Image1.png, Image2.png) are included in MyProject.app/assets/data/ without me having to do anything, but the zip file that sits beside them is not.

Looking into the actual packager code (from the metro project), it seems (based on metro/src/defaults.js) that zip files aren't included by default by the packager, but the packager can be configured to include other file types. But I can't find any documentation for how I'd go about doing that configuring.

Sorry for what feels like a really simple question, but I've been trying to get this zip included in my bundle for ~4 hours now. I'm resorting to manually putting in console.logs and error-throws to trace things inside metro to try and find where I should be sending in my config.

Versions: React-native: 0.55.3 Metro: 0.30.2


Solution

  • This is a hack, but it gets it done:

    • Convert your zip binary to a base64 string
    • Stick it in a .js file, a la module.exports = "<your base64 data goes here>"
    • In your file that needs the zip file, use import myZipFileAsBase64 from './hacky-base64-file.js';

    Here's a quick script to make your base64 files:

    var fs = require('fs');
    
    function prepareZip(file, outJs) {
      const b64 = fs.readFileSync(file, 'base64');
    
      fs.writeFileSync(outJs, `module.exports = ${JSON.stringify(b64)};`);
    }
    
    prepareZip('./data/myFirmware.zip', './hacky-base64-file.js');