Не удается разрешить child_process при использовании Nodemailer в Next. js - PullRequest
0 голосов
/ 03 марта 2020

Использование nodemailer на одном из маршрутов страниц / API выдает следующее сообщение об ошибке:

[ error ] ./node_modules/nodemailer/lib/sendmail-transport/index.js Module not found: Can't resolve 'child_process' in 'C:\ua-demo\node_modules\nodemailer\lib\sendmail-transport'

Насколько я понимаю, следующие. js pages/api маршруты выполняются в одной только серверной среде удивительно, что эта ошибка происходит. Как это можно исправить, чтобы я мог отправлять обновления по электронной почте своим пользователям?

Пример был добавлен здесь по адресу codesandbox.io . Я думаю, что нам нужно создать копию программы непосредственно на локальном компьютере для воспроизведения.

Далее js обсуждение проблемы

1 Ответ

0 голосов
/ 15 марта 2020

Я обнаружил источник. При использовании Next. js все модули, включая пакеты NPM, разрешающие ресурсы собственного сервера во время сборки, необходимо импортировать в модули только на стороне сервера. Это не так просто, как кажется в универсальном веб-приложении.

Выполнение чего-то вроде следующего надуманного примера в универсально используемом модуле приведет к ошибке, подобной этой: Can't resolve 'child_process' in 'C:\ua-demo\node_modules\nodemailer\lib\sendmail-transport', поскольку child_process является собственным сервером resource.

// send-mail/server.js
import nodeMailer from 'nodemailer';
import config from './some/nodemailer/config;

const transport = nodeMailer.createTransport( config );
const sendMail = message => transport.sendMail( message );

export default sendMail;

// send-mail/browser.js
import { post } from 'axios';

const sendMail = async ( axiosRequestConfig ) => {
    try {
        await post( axiosRequestConfig );
    } catch( e ) {
        console.error( e );
    }
};
export default sendMail;

// send-mail/index.js
import isBrowser from './some/browser/detection/logic';
import browserMailer from './browser';
import serverMailer from './server';

const mailer = isBrowser() ? browserMailer : serverMailer;

export default mailer;

Импортируйте этот модуль 'send-mail' в свой компонент, полагая, что проверка браузером обеспечивает соответствующую логику send-email c во время выполнения. Однако сборка завершается с ошибкой, аналогичной приведенной выше. Решение здесь состоит в том, чтобы изменить модуль send-mail, чтобы отложить его импорт до времени выполнения.

// send-mail/index.js
import dynamic from 'next/dynamic'; // Can also use other lazy-loading module mechanism here. Since we are building a next.js app here, why not use the one created specifically for next apps?
import isBrowser from './some/browser/detection/logic';

const mailer = isBrowser()
    ? dynamic(() => import( './server' ))
    : dynamic(() => import( './browser' ));

export default mailer;

Можно также выбрать удаление индекса. js ветвление и вручную импортировать логи сервера электронной почты c в модулях только на стороне сервера и логи браузера электронной почты c в модулях только браузера. В больших приложениях это может стать довольно громоздким, если не невозможным для обработки. Нежелательно делать это вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...