NodeJS 在 JSON 文件字符串中使用变量

NodeJS use variables in JSON file strings

我使用 JSON 常用短语文件,这样我就不必输入它们,也许将来可以翻译它们。因此,例如在我的主要代码中,我想说 You don't have the permission to use ${command_name}。这完美地硬编码到我的 .js 文件中,但最终我希望它位于 JSON 文件中,该文件不允许插入任何变量。

有人知道我的问题的解决方案吗?

编辑:感谢您的建议。我想 string.replace 是我最好的选择。希望有一些内置功能可以将 JSON 字符串中的变量转换为该 JS 文件中声明的变量。

您可以使用 config npm 模块并根据您的环境分隔 JSON 文件。

./name.json

{
    command: "this is the output of 'command'"
}

./Node.js

cost names = require('./name.json');

console.log('name === ', name.command);
// name === this is the output of 'command'

您不能像 Javascript "code" 那样处理 JSON 文件中的模板字符串文字。你自己说的。但是:您可以为此使用模板引擎 - 或者只是简单的 String.replace().

模板引擎示例:https://github.com/janl/mustache.js

使用 Mustache(作为示例),您的代码将如下所示

var trans = {
  command_name: "dump"
};

var output = Mustache.render("You don't have the permission to use {{command_name}}", trans);

简单String.replace():

var str = "You don't have the permission to use %command_name%";

console.log(str.replace('%command_name%', 'dump'));

您可以简单地使用占位符。以下函数用用户定义的值替换占位符:

const messages = {
  msgName: 'Foo is :foo: and bar is :bar:!'
}

function _(key, placeholders) {
  return messages[key].replace(/:(\w+):/g, function(__, item) {
    return placeholders[item] || item;
  });
}

用法:

_('msgName', { foo: 'one', bar: 'two' })
// "Foo is one and bar is two!"

这只是一个例子。您可以随心所欲地更改占位符样式和函数行为!

所以主要的挑战是在其中一些参数化时获取带有字符串常量的分离文件,对吗?

JSON 格式本身对字符串(数字、布尔值、列表和哈希图)进行操作,并且对替换和参数一无所知。

您也无法使用像 you don't have permission to do ${actionName} 这样的模板字符串,因为模板字符串是立即插入的。

那你能做什么?

  1. 编写您自己的解析器,从 JSON 文件获取配置数据,解析字符串,找到对变量的引用并将其替换为值。简单例子:

    const varPattern = /\${([^{}]+)}/g; 函数 replaceVarWithValue(templateStr, params) { return templateStr.replace(varPattern, (fullMatch, varName) => params[varName] || fullMatch); }

  2. 或者您可以使用任何针对本地化的 npm 包,例如 i18n,这样它会为您处理模板

基本上你可以实现一个函数parse,给定一个文本和一个字典,它可以替换每个字典键的任何出现:

const parse = (template, textMap) => {
  let output = template

  for (let [id, text] of Object.entries(textMap)) {
    output = output.replace(new RegExp(`\$\{${id}}`, 'mg'), text)
  }

  return output
}

const textMap = {
  commandName: 'grep',
  foo: 'hello',
  bar: 'world'
}

const parsed = parse('command "${commandName}" said "${foo} ${bar}"', textMap)

console.log(parsed)

顺便说一句,我建议您应该使用一些现有的字符串模板引擎,例如 string-template 以避免重新发明轮子。