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