Peter
Peter

Reputation: 4151

Run a script to parse YAML when React app compiles

My Problem

I have a ReactJS website that parses a JSON file (stored in the src folder) to render content. I recently attempted to use a YAML file instead because of YAML's richer abilities (supporting Markdown, for example).

Because React must load and parse YAML asynchronously, this change complicated my codebase and degraded my app's performance (e.g., content flickers).

My Plan

Instead of rewriting my components and slowing down my app, I've written a script to convert my YAML file into a JSON file. This way, I can have the best of both worlds: the richer abilities of YAML and the simple implementation of JSON.

My Question

What's the best way to make React run this script when the app is built? My web host rebuilds my app every time I push a change, so hopefully this can be activated via package.json or similar.

Upvotes: 0

Views: 5615

Answers (2)

Peter
Peter

Reputation: 4151

My Solution

I solved the problem using js-yaml. I even found a way to make it work with Fast Refresh.

./src/[PATH]/yaml-convert.js:

const yaml = require('js-yaml');
const fs = require('fs');

const args = process.argv.slice(2);

switch (args[0]) {
  case 'watch':
    watch();
    break;
  default:
    convert();
}

function watch() {
  fs.watch('./src/[PATH]/myData.yaml', function (event, filename) {
    require('child_process').fork('./src/[PATH]/yaml-convert.js');
  });
}

function convert() {
  try {
    const json = yaml.load(fs.readFileSync('./src/[PATH]/myData.yaml', 'utf8'));
    fs.writeFileSync('./src/[PATH]/myData.json', JSON.stringify(json));
  } catch (e) {
    console.log(e);
  }
}

package.json: (note the -- watch argument and the single & in the dev command)

...
"scripts": {
  "start": "serve -s build",
  "dev": "npm run yaml-convert -- watch & react-scripts start",
  "build": "npm run yaml-convert && react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject",
  "yaml-convert": "node ./src/[PATH]/yaml-convert.js"
}
...

And to keep git diff tidy...

.gitattributes:

/src/[PATH]/myData.json -diff

Upvotes: 3

user1898662
user1898662

Reputation: 75

Try creating an empty object that will store the converted data from the YAML, and use an if statement to check if the former object length is >0 then render what you want from the data (and if not, render a placeholder)

Upvotes: 0

Related Questions