Я обнаружил источник. При использовании 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 в модулях только браузера. В больших приложениях это может стать довольно громоздким, если не невозможным для обработки. Нежелательно делать это вручную.