What happens when using “Import Map” in react-app? How does it avoid build systems?

“Import maps are a new way for web pages to control the behavior of JavaScript imports, potentially enabling you to ditch your build system.”

I could not find any explanation of how it avoids the build system.

What happens exactly behind the scene?

Is it a complete different use of a build tool?

Related Question:

What is “npm run build” in create-react-app?

Resources:
https://www.honeybadger.io/blog/import-maps/

https://www.digitalocean.com/community/tutorials/how-to-dynamically-import-javascript-with-import-maps

How do I “return new Promise” 1 of 2 buttons?

I’m new to JS and working on a blackjack game as a project to develop my skills. I have random cards set up but it wouldn’t be blackjack if you couldn’t choose whether the Ace you just picked has a value of 1 or 11. So when the random card value is 1 I need the script to await the 1 button or 11 button being clicked but I’m struggling to grasp the concept of promise from my search online. Here is the relevant code below:

const aceOneEl=document.getElementById("aceOne-el").style.display="none"
const aceElevenEl=document.getElementById("aceEleven-el").style.display="none"
//RANDOM CARD
function getRandomCard() {
    let randomCard=Math.floor(Math.random()*12)+1
        if (randomCard===1&&hasBlackjack===false&&isAlive===true){
            document.getElementById("newCard-btn").style.display="none"
            document.getElementById("aceOne-el").style.display="unset"
            document.getElementById("aceEleven-el").style.display="unset"
            return new Promise(getAceCard)
        }else if (randomCard>10) {
            return 10
        }else {
            return (randomCard)
        }
}
//ACE CARD
function getAceCard(aceOne,aceEleven) {
    aceOne();{
        aceOneEl.addEventListener("click");{
            return 1}
        }
    aceElevenEl();{
        aceElevenEl.addEventListener("click");{
            return 11}
        }
}

Im trying to run an HTML+CSS+JS+PHP on net (netlify.com), but it has to fetch some data from my database

First, im not a native english speaker but i hope everyone could understand this s**t.

Lets start from the begining.

I have some web game built using HTML CSS and JS.

This game must gain an array of existing cities of xCountry to make the main gamerule work.

It would be a hell to populate this array manually (15000+ titles bruh :P).

So i launched the Open Server Panel DB and made a small PHP application to echo the array of titles
i needed from data base.

This PHP app i put into my local domain (Open Server Panel domain if ya know what im talking ’bout)
let’s say it called newdomain.ua, and PHP app called back.php.

So i fetched needed array of titles using JS fetch(http://newdomain.ua/back.php) {etc.}

Of course i did a lot of mistakes before. And also had a tons of CORS error messages.

But after i did everything mentioned above, my game was finally fully done.

Now there’s one issue. It’s obviously working only on my PC locally.

I made a remote DB and ready to upload the game to netlify.com, but i dont having any ideas of how to deal with PHP app, that connects all the stuff together.

So i tried to follow a lot of ChatGPT’s advices to run my game on net so everyone could play it but it seems like me and this guy havin a diffirent vision on this world.

What im sure to tell, that i got a lot of info, installed a lots of soft such as Ngrok, Heroku, XAMPP and also met some services such as Bitbucket, elephantSQL, etc. but none of them could explain me how can i deal with this s**t.

I just want to finish this project, gain some useful knowledge and finally go touch the grass.

I tried everything on my opinion. I just don’t know how such things work. I need a smartass HUMAN being, not an AI to explain me all the stuff. (i really appreciate how chatGPT helped me a lot with other things but this exact problem rips my ass) And im not copypasting code that chatgpt provides.
Im using it to learn how things work, not to solve the entire problem, so dont call me a dummy :3

Trying to get the root folder in Google drive using file IDs

I have built an apps script add-on that looks at a column in Google sheets with Doc IDs in google drive and determines the folder path of the file using those doc IDs.

The only issue is it does not give me the root folder. So if a file is located in the following folder path:

“root folder / sub-folder / sub-folder / sub-folder”

I get the following path with my code:

“Drive / sub-folder / sub-folder / sub-folder”

It says “Drive” for every file located in a shared drive and skips on the actual root folder.

Here is the code i have currently:

function getFolderPath(id) {

  var sheet = SpreadsheetApp.getActiveSheet();
  var dataRange = sheet.getDataRange();
  var values = dataRange.getValues();
  var docIdCol = 3; // assuming doc_id is in column C
  var folderPathCol = docIdCol + 1; // insert new column beside column C
  var folderPath;
  
  // insert new column beside column C
  sheet.insertColumnBefore(folderPathCol);
  
  // set column header
  sheet.getRange(1, folderPathCol).setValue("Folder Path");
  
  // iterate through each row and get folder path for each file
  for (var i = 1; i < values.length; i++) {
    var docId = values[i][docIdCol - 1];
    try {
      var file = DriveApp.getFileById(docId);
      var folders = file.getParents();
      
      while (folders.hasNext()) {
        var folder = folders.next();
        folderPath = folder.getName() + "/" + folderPath;
        folders = folder.getParents();
        console.log(folders)
        
      }
      sheet.getRange(i + 1, folderPathCol).setValue(folderPath);
      folderPath = "";
    } catch (e) {
      sheet.getRange(i + 1, folderPathCol).setValue("My Drive");
    }
    
  }

}

Command failed with exit code 1: next build – Netlify

I’m trying to deploy my site to Netlify and I keep getting this error. My site was working and was able to build before this build. Any ideas on what I can do? Also, I’m using Next.JS for the site.

3:43:14 PM: - info Generating static pages (2/6)
3:43:14 PM: - info Generating static pages (4/6)
3:43:14 PM: - info Generating static pages (6/6)
3:43:14 PM: > Export encountered errors on following paths:
3:43:14 PM:     /account/page: /account
3:43:14 PM: ​
3:43:14 PM: build.command failed                                        
3:43:14 PM: ────────────────────────────────────────────────────────────────
3:43:14 PM: ​
3:43:14 PM:   Error message
3:43:14 PM:   Command failed with exit code 1: next build (https://ntl.fyi/exit-code-1)
3:43:14 PM: ​
3:43:14 PM:   Error location
3:43:14 PM:   In Build command from Netlify app:
3:43:14 PM:   next build
3:43:14 PM: ​
3:43:14 PM:   Resolved config
3:43:14 PM:   build:
3:43:14 PM:     command: next build
3:43:14 PM:     commandOrigin: ui
3:43:14 PM:     environment:
3:43:14 PM:       - NEXT_PRIVATE_TARGET
3:43:14 PM:     publish: /opt/build/repo/.next
3:43:14 PM:     publishOrigin: ui
3:43:14 PM:   plugins:
3:43:14 PM:     - inputs: {}
3:43:14 PM:       origin: ui
3:43:14 PM:       package: '@netlify/plugin-nextjs'
3:43:16 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
3:43:16 PM: Failing build: Failed to build site
3:43:17 PM: Finished processing build request in 43.454s

I’ve tried reuploading the site and adding “CI= npm run build” in my build and deploy settings.

How to best track information about user interaction on your website and retrieve this data in real time? [closed]

We would like to track several user interaction on our website such as:

  • user clicks on a search result after typing a query in our search bar

  • if user searched for a term but this resulted in no result

  • if user searched for a term but decided not to click any of the link

  • etc

GA was an option that we came across but based on what I found online, it might be impossible to retrieve the data collected in real time. We would like to use the data we have collected so far to make search result recommendation (ie. show the most popular searches based on what the user has entered so far in the search bar).

In my previous company, the ML team used to store all this data using aws data lake which could be an option and based on it, their service would then return recommended search results.

Please let me know if you are aware of other possible options that work wonderful.

I tried researching online but most results pointed to GA but I believe GA won’t work for our case as we won’t be able to retrieve the data we want programatically.

ZingGrid Modal record display function

I tried to archive modal of record banner as display on the home page, 3 dots button https://www.zinggrid.com/

Following the guide in https://www.zinggrid.com/docs/api/methods/reference#zg-dialog

// Customize delete record dialog
zgRef.customizeDialog(‘view-info’, {
cancel: “Don’t do it!!!”,
confirm: “Okay”,
label: “End this record”
});

I made this change in JS
const zgRef = document.querySelector(‘zing-grid’);

but the model record info still not display, what else should i change?

How to dynamically create Javascript objects [duplicate]

I’m looking to dynamically merge/insert objects to refactor a bunch of API request object types and I can’t seem to find a clear answer.

let isThingTrue = true;

let dynamicObjectItem1 = {"foo": "bar"};

let dynamicObject = {
"item1": "stuff here",
"item2": "stuff here",
isThingTrue ? dynamicObject : <add nothing>
"item3": "stuff here
};

If isThingTrue is true, then object looks like:

{
"item1": "stuff here",
"item2": "stuff here",
"foo": "bar",
"item3": "stuff here
}

If isThingTrue is false, then object looks like:

{
"item1": "stuff here",
"item2": "stuff here",
"item3": "stuff here
}

Is this possible? Adding a value like this doesn’t work.

let dynamicObjectItem1 = {"foo": "bar"};

let dynamicObjectStart = {
"item1": "stuff here",
"item2": "stuff here",
dynamicObjectItem1,
"item3": "stuff here"
};

Which produces:

{
"item1": "stuff here",
"item2": "stuff here",
"dynamicObjectItem1": {
   "foo": "bar"
   }
"item3": "stuff here"
};

Is there a clean way to make this work without a bunch of Object.assigns?

Vector Control for Visual Studio

Does any one had a knowledge or experience creating/writing an application similar to CorelDraw? I just want to know what control is used for the Vector workspace in visual studio. Or can this be done in Visual Studio?

Please advise.

None – still looking for ways to pull this off.

Google Tag Manager – Custom Variable To Grab Text Located Near A Click of Interest

I’m looking to return the innertext of “How are we doing?”, when a user clicks on the toggle-icon class. This is a FAQ table where the user can click a plus or minus icon to expand / collapse the menu. My goal is when the user interacts with the icon, I can grab the related text to use within Google Tag Manager as a variable.

I know you can climb up or down the DOM tree using css selectors but am not quite at the point where I understand it fully enough to get it working.

<div id="elementor-tab-title-2871" class="elementor-tab-title" data-tab="1" role="tab" aria-controls="elementor-tab-content-2871">
    <span class="elementor-toggle-icon elementor-toggle-icon-right" aria-hidden="true">
        <span class="elementor-toggle-icon-closed"><i class="fas fa-plus"></i></span>
            <span class="elementor-toggle-icon-opened"><i class="elementor-toggle-icon-opened fas fa-minus"></i></span>
            </span>
        <a href="" class="elementor-toggle-title">How are we doing?</a>
</div>

How can you find an item in a list by its index in the Visual Studio Code code editor?

I want to find an easy way to go to the definition of an item in a list with a certain index.
I want it done in the code editor of VSCode without having to run the program.

I basically have a list of function objects called l. It is written in the code in the following format:

const l = [function(e, t, i) {
    var n = i(5)
      , r = i(14)
    // ... (more code here)
}
, function(e, t) {
    // ...
}
, // ... (many more items in list)
]

Whenever one of these functions are called, they are mentioned by their index. (The i function calls the functions from the list. e.g. i(14) calls the 14th function) This makes it really hard to tell which function is being called. That is why I would like an easy way to find the 14th function in the list.

I know that you can use breadcrums to see a list of all the items in a list but they are completely unindexed.

Image Of Breadcrums

You would think that there would be some easy way of searching for a specific item by how far down it appears in the dropdown menu or some way of using “Go To Definition” to find a certain item of a list.

Why might the AWS JavaScript SDK StartAssetBundleExportJobCommand fail as not being a constructor?

I have the following Lambda code to start a QuickSight asset export but I am experiencing the following error error when it runs.

import_client_quicksight.StartAssetBundleExportJobCommand is not a constructor

I must have a bug is something that I am doing but I can’t figure out how I got this wrong. Any thoughts?

import { QuickSightClient, StartAssetBundleExportJobCommand, StartAssetBundleExportJobCommandInput } from "@aws-sdk/client-quicksight";
import { Guid } from "guid-typescript";

const ACCOUNT_ID = process.env['ACCOUNT_ID'];
const REGION_ID = process.env['REGION_ID'];

const quicksightClient = new QuickSightClient({ region: REGION_ID });

export const handler = async (event: any): Promise<any> => {
    console.log('event', event);

    if (!event.DashboardsArns) {
        throw new Error('No DashboardsArns provided');
    }

    const startExportCommandInput: StartAssetBundleExportJobCommandInput = {
        AwsAccountId: ACCOUNT_ID,
        AssetBundleExportJobId: Guid.create().toString(),
        ResourceArns: event.DashboardsArns as string[],
        IncludeAllDependencies: true,
        ExportFormat: 'CLOUDFORMATION_JSON',
    };

    const startExportCommand = new StartAssetBundleExportJobCommand(startExportCommandInput);

    const start_asset_export_job_result = await quicksightClient.send(startExportCommand);

    if (!start_asset_export_job_result) 
      throw new Error('Empty result from StartAssetBundleExportJobCommand');

    if (start_asset_export_job_result.Status !== 200)
      throw new Error(`StartAssetBundleExportJobCommand failed with status ${start_asset_export_job_result.Status}`);

    if (!start_asset_export_job_result.AssetBundleExportJobId) {
        throw new Error('No AssetBundleExportJobId returned');
    }

    return {
      AssetBundleExportJobId: start_asset_export_job_result.AssetBundleExportJobId
    };
};

Change Owl Carousel Slide on hover

I’m using Owl Carousel and I want to change the slide on hover of a custom set of owl dots. I’ve added code that adds click functionality to the dots on hover but all that does is disable the click functionality for those dots that I’ve added it to.

PHP

<?php if(have_rows('apt_section_4')):
while(have_rows('apt_section_4')) : the_row();
    $heading = get_sub_field('heading');
    $paragraph = get_sub_field('paragraph');
    $slide_image_bathroom = get_sub_field('slide_image_bathroom');
    $slide_image_heating = get_sub_field('slide_image_heating');
    $slide_image_kitchen = get_sub_field('slide_image_kitchen');
    $slide_image_utility = get_sub_field('slide_image_utility');
    $slide_image_ensuites = get_sub_field('slide_image_ensuites');
    $slide_image_balcony = get_sub_field('slide_image_balcony');





endwhile; ?>

<section class="hover-gallery-section">

    <div class="container">

        <div class="gallery-container">
            <div class=" gsap-fade-in-up">
                <ul id='hover-carousel-custom-dots-1' class='nav-owl owl-dots-1' data-slide="1">
                    <li class="hover-owl-dot-1"><h3>SLEEK BATHROOM</h3></li>
                    <li class="hover-owl-dot-1"><h3>INTELLIGENT HEATING SYSTEM</h3></li>
                    <li class="owl-dot-1"><h3>HOTPOINT APPLIANCES IN THE KITCHEN</h3></li>
                    <li class="owl-dot-1"><h3>UTILITY SPACES</h3></li>
                    <li class="owl-dot-1"><h3>ENSUITES</h3></li>
                    <li class="owl-dot-1"><h3>BALCONY</h3></li>
                </ul>
            </div> <!-- .top-navigation -->
            <div class="row gsap-fade-in-up">
                <div class="col col-1">
                    <div class="main-slide active opacity" data-slide="1">
                        <div id="slider-hover-gallery" class="slider-hover-gallery owl-carousel owl-theme chocolat-parent">
                            <div class="slide">
                                <?php /* <p class="tagline"></p> */ ?>


                                <img class="no-lazy" src="<?php echo $slide_image_bathroom['url']; ?>" alt="<?php echo $slide_image_bathroom['alt']; ?>" />

                                <?php /*
                            <a class="chocolat-image" href="<?php echo $one_bedroom_floorplan['url']; ?>" title="<?php echo $one_bedroom_floorplan['alt']; ?>">
                                <img class="no-lazy" src="<?php echo $one_bedroom_floorplan['url']; ?>" alt="<?php echo $one_bedroom_floorplan['alt']; ?>" />
                            </a> */ ?>
                            </div> <!-- .slide -->
                            <div class="slide">
                                <?php /* <p class="tagline"></p> */ ?>

                                <img class="no-lazy" src="<?php echo $slide_image_heating['url']; ?>" alt="<?php echo $slide_image_heating['alt']; ?>" />
                                <?php /*
                            <a class="chocolat-image" href="<?php echo $two_bedroom_floorplan['url']; ?>" title="<?php echo $two_bedroom_floorplan['alt']; ?>">
                                <img class="no-lazy" src="<?php echo $two_bedroom_floorplan['url']; ?>" alt="<?php echo $two_bedroom_floorplan['alt']; ?>" />
                            </a> */?>
                            </div> <!-- .slide -->
                            <div class="slide">
                                <?php /* <p class="tagline"></p> */ ?>

                                <img class="no-lazy" src="<?php echo $slide_image_kitchen['url']; ?>" alt="<?php echo $slide_image_kitchen['alt']; ?>" />
                                <?php /*
                            <a class="chocolat-image" href="<?php echo $two_bedroom_floorplan['url']; ?>" title="<?php echo $two_bedroom_floorplan['alt']; ?>">
                                <img class="no-lazy" src="<?php echo $two_bedroom_floorplan['url']; ?>" alt="<?php echo $two_bedroom_floorplan['alt']; ?>" />
                            </a> */?>
                            </div> <!-- .slide --> <div class="slide">
                                <?php /* <p class="tagline"></p> */ ?>

                                <img class="no-lazy" src="<?php echo $slide_image_utility['url']; ?>" alt="<?php echo $slide_image_utility['alt']; ?>" />
                                <?php /*
                            <a class="chocolat-image" href="<?php echo $two_bedroom_floorplan['url']; ?>" title="<?php echo $two_bedroom_floorplan['alt']; ?>">
                                <img class="no-lazy" src="<?php echo $two_bedroom_floorplan['url']; ?>" alt="<?php echo $two_bedroom_floorplan['alt']; ?>" />
                            </a> */?>
                            </div> <!-- .slide --> <div class="slide">
                                <?php /* <p class="tagline"></p> */ ?>

                                <img class="no-lazy" src="<?php echo $slide_image_ensuites['url']; ?>" alt="<?php echo $slide_image_ensuites['alt']; ?>" />
                                <?php /*
                            <a class="chocolat-image" href="<?php echo $two_bedroom_floorplan['url']; ?>" title="<?php echo $two_bedroom_floorplan['alt']; ?>">
                                <img class="no-lazy" src="<?php echo $two_bedroom_floorplan['url']; ?>" alt="<?php echo $two_bedroom_floorplan['alt']; ?>" />
                            </a> */?>
                            </div> <!-- .slide --> <div class="slide">
                                <?php /* <p class="tagline"></p> */ ?>

                                <img class="no-lazy" src="<?php echo $slide_image_balcony['url']; ?>" alt="<?php echo $slide_image_balcony['alt']; ?>" />
                                <?php /*
                            <a class="chocolat-image" href="<?php echo $two_bedroom_floorplan['url']; ?>" title="<?php echo $two_bedroom_floorplan['alt']; ?>">
                                <img class="no-lazy" src="<?php echo $two_bedroom_floorplan['url']; ?>" alt="<?php echo $two_bedroom_floorplan['alt']; ?>" />
                            </a> */?>
                            </div> <!-- .slide -->

                        </div> <!-- .floorplan-slider -->
                    </div> <!-- .main-slide -->


                </div> <!-- .col-1 -->

            </div> <!-- .row -->
        </div>


    </div> <!-- .container -->
</section> <!-- .explore-apartments-section -->

Here’s the JS with the slider and custom dot functionality.

 $(function(){
    owl = $('#slider-hover-gallery')
    owl.owlCarousel({
        items:1,
        loop:false,
        autoplay:false,
        margin:0,
        nav:false,
        dots:true,
        animateOut: 'fadeOut',
        animateIn: 'fadeIn',
        dotsContainer: '#hover-carousel-custom-dots-1',
    });
});

 $('.owl-dot-1').click(function () {
    $('#slider-floorplans').trigger('to.owl.carousel', [$(this).index(), 300]);
    $('#slider-gallery').trigger('to.owl.carousel', [$(this).index(), 300]);
    $('#slider-virtual').trigger('to.owl.carousel', [$(this).index(), 300]);
    $('#slider-hover-gallery').trigger('to.owl.carousel', [$(this).index(), 300]);


});

$('.hover-owl-dot-1').hover(function() {
    $(this).click();
}, function() {});

Issues with viewport size on mobile devices with address bar

I have a problem that I know is common but I still haven’t found any solution. In my html page I have a text at the bottom of the screen. On mobile devices the address bar of the browser makes my 100vh actually longer than the viewport and the writing is therefore hidden. I tried to implement the dvh and svh units but they don’t have much compatibility and they are also slow and jerky. I also know that it is not possible to hide the address bar. So I was wondering if it was possible to make this always remain visible, so as to have a defined size of the viewport to work with. In case you think this approach is wrong or that there is better I would be happy to hear what is done in these cases.

Empty req.body when using a multipart form-data request

Problem

For an application, I need to be able to update the description and the avatar picture of a user.

For the file upload, I use multer and it works without any problems, but I have a small problem with the description.

I created a middleware validUserDescription which checks if the number of characters in the description is between 2 and 199. But the problem is that if I don’t put first the multer middleware, then the req.body is empty and my validator gives the green light to everything.

Now, you should tell me why not put multer first then? The problem is that if I put it first, then before the code checks the user’s description, the file would be uploaded!

Let’s not talk about the security problems, let’s imagine the following case:

  • The file is first uploaded but the validator doesn’t give the green light.
  • It means that this file’s path won’t be recorded in the database.
  • It also led to my code being incapable of locating it and deleting it when the user correctly updates his avatar picture the next time.

Trials

I tried to use JSON.parse and JSON.stringify on the req.body in my validUserDescription middleware, but they resulted in errors.

I also tried using multiparty but without success too.

Code

Multer middleware: multer-config.js

const multer = require("multer");

const MIME_TYPES = {
  "image/jpg": "jpg",
  "image/jpeg": "jpg",
  "image/png": "png",
  "image/gif": "gif"
};

const fileFilter = (req, file, callback) => {
  if (file.mimetype == "image/jpg" || file.mimetype == "image/jpeg"                          
      || file.mimetype == "image/png" || file.mimetype == "image/gif") {
    callback(null, true);
  } else {
    return callback(new Error("Invalid file format! - From multerConfig"), false);
  }
};

const storage = multer.diskStorage({
  destination: (req, file, callback) => {
    callback(null, "images");
  },
  filename: (req, file, callback) => {
    const name = file.originalname.split(" ").join("_");
    const extension = MIME_TYPES[file.mimetype];
    callback(null, name + Date.now() + "." + extension);
  }
});

module.exports = multer({ storage, fileFilter }).single("image");

User routes: user.routes.js

const router = require("express").Router();
const userCtrl = require("../controllers/user.controller");
const { validUserDescription } = require("../middleware/validInputs");
const multer = require("../middleware/multer-config");
const { auth } = require("../middleware/auth");


router.put('/:id', auth, validUserDescription, multer, userCtrl.updateUser);


module.exports = router;

Validator middleware: validInputs.js

exports.validUserDescription = async (req, res, next) => {
    try {
        const contentRegex = new RegExp(/^.{2,199}$/);

        if (contentRegex.test(req.body.user_description)) {
            next();
        } else {
            return res.status(401).json({
                success: false,
                message: "The number of characters in the must be between 2 and 199! - From validInputs"
            });
        }

    } catch (error) {
        return res.status(500).send({
            success: false,
            error: error,
            message: 'From validInputs!'
        });
    }
};

Controller to update user’s description and avatar picture: user.controller.js

self.updateUser = async (req, res) => {
    try {
        const userID = req.params.id;
        const userExist = await user.findOne({ where: { user_id: userID } });

        if (userExist) {
            const fileName = userExist.user_pictureURL.split('/images/')[1];

            const userObject = req.file
                ? {
                    ...fs.unlink('images/' + fileName, () => { }),
                    user_pictureURL: `${req.protocol}://${req.get('host')}/images/${req.file.filename}`,
                    user_description: req.body.user_description,
                    updatedAt: Date.now()
                }
                : {
                    user_description: req.body.user_description,
                    updatedAt: Date.now()
                };

            const updatedUser = await user.update({ ...userObject }, { where: { user_id: userID } });

            if (updatedUser[0] === 1) {
                return res.status(200).json({
                    success: true,
                    message: `User with the id=${userID} has been updated! - From userCtlr`
                });
            } else {
                return res.status(400).json({
                    success: false,
                    message: `User with the id=${userID} has not been updated! - From userCtlr`
                });
            }

        } else {
            return res.status(404).json({
                success: false,
                message: `User with the id=${userID} does not exist! - From userCtlr`
            });
        }

    } catch (error) {
        return res.status(500).json({
            success: false,
            error: error,
            message: "From userCtlr"
        });
    }
};

My server which is divided into two parts:
app.js

const express = require('express');
const path = require('path');

const usersRoutes = require("./routes/user.routes");

const app = express();

app.use(express.json());

app.use(express.urlencoded({ extended: true }));

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', '*');
  res.setHeader('Access-Control-Allow-Methods', '*');
  next();
});

app.use('/images', express.static(path.join(__dirname, 'images')));
app.use('/api/users', usersRoutes);

module.exports = app;

server.js

const http = require('http');
const app = require('./app');

function normalizePort(val) {
    const port = parseInt(val, 10);
    if (isNaN(port)) {
        return val;
    }
    if (port >= 0) {
        return port;
    }
    return false;
};

const port = normalizePort('8080');
app.set('port', port);

function errorHandler(error) {
    if (error.syscall !== 'listen') {
        throw error;
    }
    const address = server.address();
    const bind = typeof address === 'string' ? 'pipe ' + address : 'port: ' + port;
    switch (error.code) {
        case 'EACCES':
            console.error(bind + ' requires elevated privileges.');
            process.exit(1);
            break;
        case 'EADDRINUSE':
            console.error(bind + ' is already in use.');
            process.exit(1);
            break;
        default:
            throw error;
    }
};

const server = http.createServer(app);

server.on('error', errorHandler);
server.on('listening', () => {
    const address = server.address();
    const bind = typeof address === 'string' ? 'pipe ' + address : 'port ' + port;
    console.log('Listening on ' + bind);
});
server.listen(port);