【问题标题】:node.js i18n: "ReferenceError: __ is not defined"node.js i18n:“ReferenceError:__未定义”
【发布时间】:2020-12-01 15:20:26
【问题描述】:

在我的整个应用程序中,我使用 i18n 没有问题。但是,对于通过 cron 作业发送的电子邮件,我收到错误消息:

ReferenceError: __ 未定义

app.js我配置i18n:

const i18n = require("i18n");
i18n.configure({
    locales: ["en"],
    register: global,
    directory: path.join(__dirname, "locales"),
    defaultLocale: "en",
    objectNotation: true,
    updateFiles: false,
});
app.use(i18n.init);

在我的整个应用程序中,我将其用作__('authentication.flashes.not-logged-in'),就像我说的没有问题。在由 cron 作业调用的邮件控制器中,我以相同的方式使用它:__('mailers.buttons.upgrade-now')。然而,只有在那里,它才会产生上述错误。

只是试一试,我已在邮件控制器中将其更改为 i18n.__('authentication.flashes.not-logged-in')。但后来我得到另一个错误:

(node:11058) UnhandledPromiseRejectionWarning: TypeError: logWarnFn is not a function
    at logWarn (/data/web/my_app/node_modules/i18n/i18n.js:1180:5)

知道如何使通过 cron 作业发送的电子邮件正常工作吗?

【问题讨论】:

  • 您的 cron 作业到底是如何设置的?它是向您的应用发出 HTTP 请求,还是尝试使用 node 直接运行控制器?
  • @DylanSp,我对 cron 了解不多,也没有自己设置,所以我希望我能正确回答你的问题。如果我运行crontab -l 我有30 14 * * * cd /data/web/portal/ && /usr/bin/timeout 120 /usr/bin/node cli.js sendemails 2>&1 | /usr/bin/logger -t portal-cron-live。我认为这意味着节点尝试直接运行控制器,不是吗?
  • 这取决于cli.js sendemails 的作用。该脚本是发出 HTTP 请求,还是直接调用控制器?
  • 啊,直接调用控制器:program.command("sendemails").action(async function () { mailController.executeCrons() ...
  • 你的问题; i18n 全局不是这样定义的。我会输入一个答案。

标签: node.js cron internationalization i18n-node


【解决方案1】:

在 cmets 中,提问者澄清说 cron 作业直接调用 mailController.executeCrons(),而不是向应用程序发出 HTTP 请求。因此,i18n 全局对象永远不会被定义,因为app.js 中的应用设置代码没有运行。

最好的解决方案是使用i18ninstance usage。您可以将 I18N 对象的实例化和配置分离到一个单独的函数中,然后在 app.js 中调用它以将其设置为 Express 中间件,并在 mailController.executeCrons() 函数中调用它以在通过定时任务。

代码大纲:

i18n.js(新文件)

const i18n = require("i18n");

// factory function for centralizing config;
// either register i18n for global use in handling HTTP requests,
// or register it as `i18nObj` for local CLI use
const configureI18n = (isGlobal) => {
  let i18nObj = {};

  i18n.configure({
    locales: ["en"],
    register: isGlobal ? global : i18nObj,
    directory: path.join(__dirname, "locales"),
    defaultLocale: "en",
    objectNotation: true,
    updateFiles: false,
  });

  return [i18n, i18nObj];
};


module.exports = configureI18n;

app.js

const configureI18n = require('./path/to/i18n.js');

const [i18n, _] = configureI18n(true);
app.use(i18n.init);

mailController.js

const configureI18n = require('./path/to/i18n.js');

const [_, i18nObj] = configureI18n(false);

executeCrons() {
  i18nObj.__('authentication.flashes.not-logged-in');
}

【讨论】:

  • 我现在正在尝试解决方案,但引用 app.js 会产生错误:const [i18n, _] = configureI18n(true);TypeError: configureI18n is not a function or its return value is not iterable
  • 抱歉,搞砸了导出语法。将i18n.js 编辑为使用exports = configureI18n;,试试吧。