skip to Main Content

i’m trying to use nuxt 3 for create a web app and it’s work very fine on my desktop with the version 17.3.0 of node js but it’s not the case on the server …

it’s a server with cpanel and i use the tools "setup node.js app" but i got this error every time.

App 37252 output: node:internal/modules/cjs/loader:979
App 37252 output:     throw new ERR_REQUIRE_ESM(filename, true);
App 37252 output:     ^
App 37252 output: Error [ERR_REQUIRE_ESM]: require() of ES Module /home/private/admin/server/index.mjs not supported.
App 37252 output: Instead change the require of /home/private/admin/server/index.mjs to a dynamic import() which is available in all CommonJS modules.
App 37252 output:     at Module.require (/opt/cpanel/ea-ruby27/root/usr/share/passenger/helper-scripts/node-loader.js:80:25)
App 37252 output:     at loadApplication (/opt/cpanel/ea-ruby27/root/usr/share/passenger/helper-scripts/node-loader.js:243:2)
App 37252 output:     at setupEnvironment (/opt/cpanel/ea-ruby27/root/usr/share/passenger/helper-scripts/node-loader.js:214:2)
App 37252 output:     at Object.<anonymous> (/opt/cpanel/ea-ruby27/root/usr/share/passenger/helper-scripts/node-loader.js:133:1) {
App 37252 output:   code: 'ERR_REQUIRE_ESM'
App 37252 output: }

in the "setup node.js app" tools, the latest version of node available is the 16.13.0 so i think the problem is from that (it’s work fine on my computer with the version 17.3.0).

If it’s that, how i can hade the latest version of nodeJs to cpanel ?

EDIT :

My package.json :

My package.json

my nuxt.config.ts :

my nuxt.config.ts

My app.vue

<template>
    <Html lang="fr">
        <Head>
            <Title>title</Title>
            <Meta name="description" content="My page's description" />
        </Head>
        <Body>
            <header>
                <nav>
                    <ul>
                        <li class="nav-item active">
                            <a href="#">
                                <span class="icon">
                                    <ion-icon name="grid-outline"></ion-icon>
                                </span>
                                <span class="text">Hub</span>
                            </a>
                        </li>
                        <li class="nav-item">
                            <a href="#">
                                <span class="icon">
                                    <ion-icon name="checkmark-outline"></ion-icon>
                                </span>
                                <span class="text">Vérification</span>
                            </a>
                        </li>
                        <li class="nav-item">
                            <a href="#">
                                <span class="icon">
                                    <ion-icon name="build-outline"></ion-icon>
                                </span>
                                <span class="text">Modération</span>
                            </a>
                        </li>
                        <li class="nav-item">
                            <a href="#">
                                <span class="icon">
                                    <ion-icon name="chatbubble-ellipses-outline"></ion-icon>
                                </span>
                                <span class="text">Communication</span>
                            </a>
                        </li>
                        <li class="nav-item">
                            <a href="#">
                                <span class="icon">
                                    <ion-icon name="settings-outline"></ion-icon>
                                </span>
                                <span class="text">Paramètre</span>
                            </a>
                        </li>
                        <div class="indicator"></div>
                    </ul>
                </nav>
            </header>
            <NuxtPage />
        </Body>
    </Html>
</template>

<script setup>
import { onMounted } from 'vue';


onMounted(() => {
    const navItems = document.querySelectorAll('.nav-item');
    navItems.forEach(navItem =>
        navItem.addEventListener('click', () => {
            navItems.forEach(item => {
                item.classList.remove('active');
            });
            navItem.classList.add('active');
        })
    );
});
</script>

<style lang="scss">
@font-face {
    font-family: 'Roboto';
    src: local('Roboto'), url('./assets/fonts/Roboto-Black.ttf');
}

body {
    font-family: 'Roboto';
    margin: 0;
}

nav {
    position: fixed;
    bottom: 0px;
    width: calc(100% - 10rem);
    height: 5rem;
    padding: 0 5rem;
    background: #039ce7;
    border-radius: 10px 10px 0 0;
}

nav > ul {
    height: 100%;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: space-between;
    list-style: none;
}

nav > ul > li > a {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

nav > ul > li > a > .icon {
    line-height: 5rem;
    font-size: 2rem;
    color: white;
    transition: 0.5s;
}

nav > ul > li:hover > a > .icon {
    transform: translateY(-.5rem);
}

nav > ul > li.active > a > .icon {
    transform: translateY(-2.4rem);
    color: white;
}

nav > ul > li > a > .text {
    position: absolute;
    font-size: 1rem;
    opacity: 0;
    color: white;
    transition: 0.5s;
    transform: translateY(40px);
}

nav > ul > li:hover > a > .text {
    opacity: 1;
    transform: translateY(22px);
}

nav > ul > li.active > a > .text {
    opacity: 1;
    transform: translateY(22px);
}

nav .indicator {
    position: absolute;
    top: calc(-52% + -8px);
    width: 5rem;
    height: 5rem;
    transform: translateX(50%);
    border-radius: 50%;
    background: #039ce7;
    border: 8px solid white;
    transition: .5s;
}

nav .indicator::before {
    content: '';
    position: absolute;
    top: 52%;
    left: -20px;
    width: 15px;
    height: 15px;
    border-top-right-radius: 24px;
    box-shadow: 0 -5px 0 0 white;
}

nav .indicator::after {
    content: '';
    position: absolute;
    top: 52%;
    right: -20px;
    width: 15px;
    height: 15px;
    border-top-left-radius: 24px;
    box-shadow: 0 -5px 0 0 white;
}

nav ul li:nth-child(1).active ~ .indicator {
    left: 0;
}

nav ul li:nth-child(2).active ~ .indicator {
    transform: translateX(0);
    left: 25%;
}

nav ul li:nth-child(3).active ~ .indicator {
    transform: translateX(-50%);
    left: 50%;
}

nav ul li:nth-child(4).active ~ .indicator {
    transform: translateX(-100%);
    left: 75%;
}

nav ul li:nth-child(5).active ~ .indicator {
    transform: translateX(-150%);
    left: 100%;
}
</style>

My index.vue :

<template>
    <div>
        <h1>{{ data }}</h1>
    </div>
</template>

<script setup>
// eslint-disable-next-line no-undef
const { data } = await useFetch('/api/hello');
</script>

An my hello.ts file :

export default async () => 'Hello World';

I’m at the start of my projects so i have only App.vue, Index.vue, and hello.ts

For deploy my app, i run npm run deploy, then i move all content of ".output" folder (the folder where the app is build) in the admin folder on my server (with filezilla).

.output folder :

.output folder

(any require is in the index.mjs file)

On my server, i launch the app with the "setup node.js app" tools.

enter image description here

2

Answers


  1. Try adding type: "module" to your package.json file then delete your node_modules directory and do an npm install again.

    Login or Signup to reply.
  2. Try to use node preset while building Nuxt 3 App. You can use our Express.js wrapper to run the app using CloudLinux Passenger that is installed on your CPanel.

    Check this out: https://github.com/Kodefix/express-wrapper-for-nuxt-3

    CloudLinux Passenger can’t handle ES Module, so you have to use entry.js as helper file to run the app. This is the easiest way to handle Nuxt 3 App on shared hosting, etc.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search