0

I am getting the error Uncaught TypeError: fs.writeFile is not a function in my program, in which I just want to write something to a JSON file. The fs.readFileSync function works properly, but fs.writeFile doesn't for some reason. Here is my code:

HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    <button id="button">Write Something</button>
    <script src="./app.js"></script>
  </body>
</html>

JavaScript:

const fs = require("fs");
const data = fs.readFileSync("db.json", "utf8");
const db = JSON.parse(data);

console.log(db);

document.getElementById("button").onclick = () => {
  fs.writeFile("db.json", "test", () => {
    console.log("Written file!");
  });
};

JSON:

["something1", "something2"]

Just to let you know, I am using Parcel as my bundler. Please help me on why this is not working.

DG27
  • 77
  • 3
  • 8
  • 1
    You shouldn't have write access from the browser. So, I'd expect `fs` running in the browser might just have all the writing methods removed. – VLAZ May 31 '21 at 10:17

3 Answers3

2

The Node.js fs module is not written in JavaScript. It is a core part of Node.js written in C/C++. It won't run in a web browser and can't be bundled into a JS file.

(Note that readFileSync can be inlined, it just reads the file when it is bundled instead of at runtime).

If you want to generate a JSON file then you can either:

  • Write a web service (which will write JSON to a file on the server) and then issue an HTTP request to it or
  • Convert the data into a downloadable URL (so it will be saved to the user's download folder).
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • I don't want to generate a JSON file, I want to modify an existing one which I have created, such as by adding or deleting elements in it. The first option you've suggested me could work, but my hosting type doesn't provide the facilities for it. Unless your second proposal means that I can access the file, modify and delete elements in it, I would require a bit more to work with. – DG27 May 31 '21 at 12:18
  • @DG27 — If you need to change data on the server then you need hosting which supports it. – Quentin May 31 '21 at 12:20
  • I want as less backend infrastructure as possible. If it helps, here's a link to a photo of my folder structure. You would hopefully be able to understand what I'm going for - https://photos.app.goo.gl/qv6qobpBDKd93Nvu5. Please tell me more about the second suggestion. – DG27 May 31 '21 at 12:28
  • Putting a modified copy of the file on the end user's computer won't meet your requirement of editing the file you have already. – Quentin May 31 '21 at 12:50
1

You won't be able to use writeFile in the browser, even if you use a bundler because this is Node.js and not a browser API. Bundlers won't embed native Node.js functions in a browser's build because these are two different execution environments.

In the browser, you can't trigger arbitrarily a file write on the disk without the user's consent, so you have to actually trigger a file download instead.

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • "*this is Node.js and not a browser API.*" yet the `readFile` call succeeds. So, whatever library this is, does exist in the browser environment. But I don't know which one it would be. Might just be doing a GET for a file to "read" it. – VLAZ May 31 '21 at 10:19
  • It would be best if you edited this and went into a more detail. – DG27 May 31 '21 at 12:21
0

I was facing the same issue.

Replace const fs = require("fs"); with const fs = require('fs-extra');

This worked for me.
fs-extra provides additional functionality on top of the core fs module, making it a more convenient option for many use cases.

If this works for anyone else, do let me know.

Anonymous
  • 835
  • 1
  • 5
  • 21