Así que he estado usando la sintaxis de estilo ES6 con importación / exportación en Nodejs con el cargador de módulos ESM. Todo ha estado bien hasta que comencé a recibir un error relacionado con las importaciones.

Aquí están los mensajes de error:

joseph@InsaneMachine:~/placeholder2/main-server$ npm start

> main-server@1.0.0 start /home/joseph/placeholder2/main-server
> nodemon --experimental-modules src/index.mjs

[nodemon] 1.19.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node --experimental-modules src/index.mjs`
(node:16942) ExperimentalWarning: The ESM module loader is experimental.
file:///home/joseph/placeholder2/main-server/src/games/game-player.mjs:3
export default class GamePlayer extends Player
                                        ^

ReferenceError: Cannot access 'Player' before initialization
    at file:///home/joseph/placeholder2/main-server/src/games/game-player.mjs:3:41
    at ModuleJob.run (internal/modules/esm/module_job.js:109:37)
    at async Loader.import (internal/modules/esm/loader.js:132:24)
[nodemon] app crashed - waiting for file changes before starting...

Aquí están los archivos Player (Clase base):

import PasswordHash from 'password-hash';

import GamesService from '../games/games.service.mjs';

import PlayersService from './players.service.mjs';

import QueueingService from '../queueing/queueing.service.mjs';

export default class Player
{
    constructor(object)
    {
        Object.assign(this, JSON.parse(JSON.stringify(object)));
    }

    get id()
    {
        return this._id.toString();
    }

    equals(other)
    {
        if(other.id != null)
            return other.id == this.id;
        return false;
    }

    checkPassword(password)
    {
        return PasswordHash.verify(password, this.password);
    }

    online()
    {
        return PlayersService.consumer.isPlayerOnline(this);
    }

    inQueue()
    {
        return QueueingService.queued(this);
    }

    inGame()
    {
        return GamesService.getActiveGameByPlayer(this) != null;
    }

    reduce()
    {
        return {
            id: this.id,
            username: this.username,
            email: this.email,
            admin: this.admin,
            online: this.online(),
            in_queue: this.inQueue(),
            in_game: this.inGame(),
        };
    }

    static hashPassword(password)
    {
        return PasswordHash.generate(password);
    }

    static schema = {
        username: String,
        password: String,
        email: String,
        email_confirmed: Boolean,
        admin: Boolean,
    }
}

Y GamePlayer (clase infantil):

import Player from '../players/player.mjs';

export default class GamePlayer extends Player
{
    constructor(player, token)
    {
        super(player);
        this.token = token;
    }
}

Y la jerarquía del proyecto:

src/
 -- games/
 --  -- game-player.mjs
 --  -- ...
    players/
 --  -- player.mjs
 --  -- ...
 -- ...

¿Cómo puedo solucionar este problema de importación, a menos que sea otra cosa?

Editar: No estoy usando Babel por lo que sé, estoy usando módulos externos provistos por Node. No estoy seguro de cómo funciona eso.

2
Joseph Norman 8 feb. 2020 a las 03:08

2 respuestas

La mejor respuesta

Fui a los foros de Node.JS y pregunté cuál podría ser el problema. No es un problema de Babel, solo dependencias circulares. Por ejemplo:

// A.js
import B from './B.js'
export default class A{}
// B.js
import A from './A.js'
export default class B extends A{}

Lo siento, no había suficiente información para poder resolver esto. Obtuve mucha ayuda en el github de node.js y alguien revisó mi proyecto en github y terminó encontrando una instancia en la que dos módulos se apuntaban entre sí.

0
Joseph Norman 12 feb. 2020 a las 15:25

Elimine es2015 de su configuración de Babel. La clase extiende la clase ES6 nativa y Babel se transpila a ES, lo que probablemente está causando el problema.

0
varoons 8 feb. 2020 a las 00:38