1

I have a server application which uses this to display the home page

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "/index.html"));
});

and my js file in the index.html has these lines in the head

    <script src="/public/js/controller.js" type="module"></script>
    <script src="/public/js/main.js" type="module"></script>

the main.js is for the frontend js while the controller is for the backed and it imports model.js and model.js use fs using this line

const fs = require("fs");

but when I try to load the index.html using the node server http://localhost:3000 I get this error

model.js:2 Uncaught ReferenceError: require is not defined
    at model.js:2

so I added the require.js library and then used it like this

    <script src="/public/js/require.js" ></script>

And then I still get this error

require.js:108 Uncaught Error: Module name "fs" has not been loaded yet for context: _. Use require([])
https://requirejs.org/docs/errors.html#notloaded
    at makeError (require.js:108)
    at Object.s [as require] (require.js:947)
    at requirejs (require.js:134)
    at model.js:2

Can someone please advise, what should one do to make this work? I am stuck for more than 2 days on this and I am pretty new to node.js and this 'require' thing.. but I know it's a very important part of node.js.

So I would like to have some clarity and some advise/help on what an html page that's not using a bundler and running directly from a node server have to do to handle this..

and just so that I am clear about what I mean by 'this' all I am trying to do is get a list of folder names that I want use as navigation menu (li items) on the front-end.. I am using this command on node.js to do get the array..

fs.readdir('./data/')

I need to have this array in my index.html which is on the same server/folder/application that is running on node.js..

I assumed that if node.js is displaying an html file (with app.get) I would be able to use the fs command this way.. am I wrong? If so, what do I have to do to use readdir and get the array to display as menu on the front-end?

Alim Bolar
  • 479
  • 4
  • 17
  • `requirejs` allows you to use `require()` on the client side, but that doesn't mean it has access to any nodejs packages, such as the default `fs` or an npm package like `express`. It can only do files. – code May 30 '21 at 06:37
  • thanks for the reponse.. have added some more info at the end of my question based on your comment.. please check if it makes sense – Alim Bolar May 30 '21 at 07:29

2 Answers2

1

The "fs" module is a built-in module in NodeJS to allow you to work with the filesystem. It isn't available on the client-side (imagine people can access your webpage and manipulate your filesystem!!).

What you're trying to do is get a list of folder names that you want use as navigation menu (li items) on the front-end. For that, you can get the list of folder names on the server-side using "fs" module, then using template engine to render HTML file with the data.

For NodeJS, there are some popular template engines: EJS, pug, nunjucks....

Đăng Khoa Đinh
  • 5,038
  • 3
  • 15
  • 33
  • Thanks @Dang for your clarification.. that's exactly what I set out to do.. and then I assumed that showing the HTML with `app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "/index.html")); });` was the same as a template engine.. but I guess I was wrong as I realise now that it's still just an html webpage getting the scripts from the even if it's served by the server.. that's my mistake.. right? .. a confirmation about this would help me move ahead.. so please do respond and let me know.. – Alim Bolar May 30 '21 at 12:39
  • Yes, `sendFile` just sends the file to client. You need to use a template engine :) – Đăng Khoa Đinh May 30 '21 at 12:40
  • Or, send an AJAX request to the server for the list of files. – code May 31 '21 at 02:08
-1

You might have your server.js as a ES6 module, which is a good thing as it took me an hour to set it up like that myself.

You can do import * as fs from 'fs'; or import {fs} from 'fs'; but I did import { promises as fs } from "fs"; because I like my fs calls async.

Gives it a python feel.

  • thanks for the response..:-).. and no, I don't have the server.js as an ES6 module.. and so it doesn't allow the import option (and I assumed that for node.js it's better to use the 'require' option so that there's no dependencies.. anyways that's a different point altogether)..;-).. so no, this answer didn't work for me.. – Alim Bolar May 30 '21 at 06:34
  • If you're trying to do `fs` stuff in html5, you can use an `input type="file"` tag, or load files like [this](https://stackoverflow.com/questions/19706046/how-to-read-an-external-local-json-file-in-javascript/34579496#34579496), or don't. – Leif Messinger LOAF May 30 '21 at 06:45