Почему команда nexus dev запускает приложение дважды и как это исправить?

Я создал супер простое приложение, используя платформу nexus graphql.

Первый шаг такой:

https://www.nexusjs.org/#/tutorial/chapter-1-setup-and-first-query

я api/app.ts я набрал код:

const uid = require('uid')

let i = 0;

const sleep = async (ms: number) => {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, ms)
    })
}

const recurrenceFunction = async (id:string): Promise<void> => {
    i++;
    console.log(id, i);
    await sleep(2000);
    return recurrenceFunction(id)
}

const startQueue = () => {
    const id:string = uid();
    return recurrenceFunction(id)
}

(async () => {
    return startQueue()
})()

Только зависимость uid который генерирует уникальные ключи.

Когда я запускаю его с помощью ts-node, я вижу:

Итак, мы видим:

  1. Как только очередь началась.
  2. Единая очередь.
  3. Работает так, как и должно работать.

Но когда я запускаю этот код с nexus по команде nexus dev Я видел:

Так:

  1. Начались две очереди.
  2. Они работают одновременно.
  3. Они независимо создали переменные i.

Вопросы:

  • Кто-нибудь встречался с этой проблемой?
  • Как мне изменить свой код, чтобы получить единую очередь, как в ts-node?
  • А может это ошибка nexus?

Обновить:

Я проверил, что эта проблема существует для версий>= 0.21.1-next.2

В 0.21.1-next.1 приложение запускается один раз.

Действия по воспроизведению:

nexus dev
npm i nexus@0.21.1-next.1
nexus dev
npm i nexus@0.21.1-next.2

есть фиксация, которая ввела это поведение:

https://github.com/graphql-nexus/nexus/commit/ce1d45359e33af81169b7ebdc7bee6718fe313a8

Есть такие переменные, как onMainThread а также REFLECTION_ENV_VARно без ссылок на документацию. Я не могу понять, что делает этот код?

Это, вероятно, будет задокументировано в будущем в этом месте:

https://www.nexusjs.org/

но сейчас есть:

Обновление 2

Я обнаружил, что вокруг:

const xid = uid();
let limit=10;
const onApplicationStart = async (cb: () => any):Promise<any> => {
    console.log("can i start?", xid, limit, app.private.state.running);
    if(app.private.state.running) {
        await cb()
        return;
    }
    limit--;
    if(limit <= 0) return ;
    await sleep(100);
    return onApplicationStart(cb);
}

(async () => {

    return onApplicationStart(async () => {
        return startQueue()
    })

})()

но это скорее временный взлом, чем решение. Полный пример:

https://github.com/graphql-nexus/nexus/discussions/983

1 ответ

Решение

Код нетерпеливого модуля, основанный на побочных эффектах, не поддерживается Nexus.

Видеть:

Для временного решения оберните ваш код следующим образом:

// app.ts
if (!process.env.NEXUS_REFLECTION) {
  yourHeavyAsyncCode()
}

Ссылка https://github.com/graphql-nexus/nexus/issues/732

Другие вопросы по тегам