gpt4 book ai didi

react-redux - 在 Next.js 中使用 Nodemailer 时无法解析 child_process

转载 作者:行者123 更新时间:2023-12-03 08:48:19 26 4
gpt4 key购买 nike

在页面/api 路由之一中使用 nodemailer 会产生以下错误消息:

[错误] ./node_modules/nodemailer/lib/sendmail-transport/index.js 找不到模块:无法解析“C:\ua-demo\node_modules\nodemailer\lib\”中的“child_process”发送邮件传输'

据我了解,next.js pages/api 路由仅在服务器环境中运行,因此发生此错误真是一个奇迹。如何解决这个问题,以便我可以向我的用户发送电子邮件更新?

已在此处添加示例 codesandbox.io 。我认为我们需要直接在本地机器上构建该程序的副本才能重现。

Nextjs issue discussion

最佳答案

我已经找到了来源。使用 Next.js 时,所有模块(包括在构建期间解析 native 服务器资源的 NPM 包)都需要导入到仅服务器端模块中。这并不像通用 Web 应用程序中听起来那么简单。

在通用模块中执行类似以下人为示例的操作将导致类似以下错误:Can't parse 'child_process' in ' C:\ua-demo\node_modules\nodemailer\lib\sendmail-transport' 因为 child_process 是 native 服务器资源。

// 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-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;

如果使用 webpack,我们可以为客户端build设置 RUN_TARGET=BROWSER 环境变量并使用 webpack-conditional-loader在构建时对代码进行分支,而不是动态运行时加载,如下所示:

// #if process.env.RUN_TARGET !== 'BROWSER'
import serverMailer from './server';
// #endif
// #if process.env.RUN_TARGET === 'BROWSER'
import browserMailer from './browser';
// #endif
let mailer;
// #if process.env.RUN_TARGET !== 'BROWSER'
mailer = serverMailer;
// #endif
// #if process.env.RUN_TARGET === 'BROWSER'
mailer = browserMailer;
// #endif

export default mailer;

// yeilds the following after server-side build
import serverMailer from './server';
let mailer;
mailer = serverMailer;
export default mailer;

// yeilds the following after client-side build
import browserMailer from './browser';
let mailer;
mailer = browserMailer;
export default mailer;

还可以选择删除index.js分支,并在仅服务器端模块中手动导入服务器电子邮件逻辑,并在仅浏览器模块中手动导入浏览器电子邮件逻辑。在大型应用程序中,这即使不是不可能处理,也会变得相当麻烦。不建议手动执行此操作。

关于react-redux - 在 Next.js 中使用 Nodemailer 时无法解析 child_process,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60496911/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com