Skip to content

How to use browser-side JavaScript (document, window, etc.) when running a node.js server to change the HTML document?

here’s my situation. I just started learning about node.js server with express and I find it to be an amazing technology, based on JavaScript that I am already a bit familiar with.

Now, so far, whenever I want to change something on the page, I have to do it with JS on the server-side with node.js, and thus, I have to refresh the page with new information. But in several cases this seems to be not the best way to handle things, like changing simple text contents or click events. I would like to use browser-side JS for that reason, but I have not found out a way to do that yet.

I tried to call js-files and import them, but I couldn’t make it work.

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

I also put the index.js and functional.js in the public folder, which I have made available to node.js at all times, but the imported JS still cannot be found when the project is run on the server.

app.use(express.static('public'));
app.use(express.static(path.join(__dirname, '/public')));

The strange thing is, I have been looking all over the internet on trying to find an explanation to it for several days already, but I couldn’t find anything that made it clear to me on how to use browser-JS with a node.js server.

My folder structure is this:

My node.js project folder structure

functional.js

exports.functional = () => {
    alert("Do something...");
}

index.js

const { functional } = require('./functional');

document.addEventListener('DOMContentLoaded', () => {

    const init = (() => {
        functional();
    })();
});

So now I have the following questions:

  • Can browser-side JS even be used with a node.js server?
  • If it can be used, how do I implement those js-files, so they actually work?

Every help is greatly appreciated! Thanks 🙂

Answer

Static Folder

You’re defining a static folder in Express, here.

app.use(express.static('public'));

This tells Express that every static file (css, js, images, .etc) are found in the folder public. Now Express handles this smart and now knows that when you’re looking for a static file, it is in that folder you’ve specified.

<script src="js/index.js"></script>

This will look into the folder public for the folder js and the file index.js. public/js/index.js.

Modules

The script itself needs some modification. Node.js uses a module system called CommonJS. And the syntax works works like in your file exports.functional, require('./functional'). But that is a technology that only works on the Node.js environment. Not in the browser.

JavaScript does also have a native module system, which is also available in Node.js, which works with the import and export keywords.

export const functional = () => {
  alert("Do something...");
};
import { functional } from './functional' ;

document.addEventListener('DOMContentLoaded', () => {
  functional();
});

But wait

By using the native module system on the client side, you’ll need to load all the scripts that have exported and imported values in them, otherwise you’d be missing pieces.

<script type="module" src="js/functional.js"></script>
<script type="module" src="js/index.js"></script>

Bundler

The mainstream use of import and export modules is in combination with a module bundler like Webpack, which combines all the modules into a single file, which you can serve to the browser. This is very useful for development to keep the files you work in small.

It can transform the following files from this:

public
-- dist <-- bundled files ready for distribution
-- src <-- raw source files to work with
---- js
------ index.js
------ functional.js

to this:

public
-- dist <-- bundled files ready for distribution
---- js
------ bundle.js <-- Single file ready for the browser
-- src <-- raw source files to work with
---- js
------ index.js
------ functional.js

The bundler program also works on the Node.js environment, just like Express.js, so you can include it in your project.

Alternative

If the bundlers seem like a huge hassle, then you could always choose to classically use a single file to serve your JavaScript in.