How to execute node modules inside a React project?

As in the title, this is a general wondering. I have a React project which I scaffolded with create-react-app, and I am doing fine, more or less.
Now I need to fetch a xlsx file and convert it into a json file. For this task, I used this npm module.

So I put a separate folder in my project, called routines, and inside it I put a file called fetchInventary.js which looks like this:

var xlsxj = require("xlsx-to-json");

xlsxj(
  {
    input: "inventary.xlsx",
    output: "inventary.json",
  },
  (err, result) => {
    if (err) {
      console.error(err);
    } else {
      console.log(result);
    }
  }
);

Now I am wondering: how can I execute this in a React component?

You can’t, not like that.

  • The browser is an execution environment for JS. It means scripts written in JS and referenced in HTML pages can be executed. So for example, a React application – the browser JS engine can run that JS code that makes up the app (which relies on APIs available to it in the browser).
  • Node is an execution environment for JS. It means code written in JS can be executed. On your computer, the most common usage is for tools used to build frontend projects (Webpack etc). Otherwise, most common usage is running an application written in JS on a server somewhere using Node.

These are not the same thing, they are completely separate things. The browser knows absolutely nothing about Node, Node knows absolutely nothing about the browser. They have completely different purposes and APIs. For example, this line:

var xlsxj = require("xlsx-to-json");

require is a function from the Node standard library which resolves the location on the filesystem of (and thence includes the code for) a JavaScript module. That uses a format called CommonJS which is specific to Node. The browser has no idea what that is, it can’t execute it.

Then the xlsxj function there will use Node’s filesystem API to deal with those input & output files.

A browser can’t do these things, it knows absolutely nothing about the APIs of a completely different system (Node). Even if you use a tool to turn that into something that the browser understands (ie Webpack), the browser APIs have no access to the filesystem, so even if it could execute those functions, they rely on functionality that cannot exist in a browser.

To use what you have there, you would need to write a separate Node server application that allows you to run that conversion: it would need to allow uploading files and downloading files via HTTP. Alternatively, you could use a serverless platform (eg AWS Lambda, Cloudflare Workers), and write a function to do it (basically exactly what you have there, accept file as input, return file as output) rather than writing an entire Node application.

Then whatever is done, the React app talks to that – make POST request to upload a file, response would be the conversion.

This is not trivial, but this is how things generally work, it’s much easier to parse and convert files outside of the browser.

To do it client-side, there are a few solutions here:

Note that there’s a high chance of larger files crashing the browser if you aren’t careful about how it’s coded (ideally this would all be done in another thread using Web Workers). Plus there are likely to be issues with specific versions of Excel, the available libraries are normally written against a specific version of the application, as the XML output of Excel normally changes significantly between versions of the program.

I’m slightly confused.
So basically, say I build a front-end with React, and manage its state with Redux. Maybe even put a Redux form to make it more interesting. How does this relate to a Node server?

Because you’re asking how to run server-side (NodeJS) programs that in this case require filesystem access in a browser. The answer to that is that you run them in an environment that has access to a computer’s filesystem (ie a server running NodeJS), not in a browser (that being impossible).

I also included links to an alternative method using client-side browser APIs that does not depend on the filesystem, but you can’t use what you’re currently trying to use if you do that.