Если вы используете JSON для хранения / передачи конфигурации (или можете использовать JSON в процессе перед развертыванием для вывода в другой формат), вы можете аннотировать имена ключей / свойств для значений среды / контекста с произвольными значениями или средой -специфичные суффиксы, а затем динамически предпочитать / различать их во время сборки / развертывания / запуска / рендеринга, оставляя только аннотированные свойства в одиночку.
Мы использовали это, чтобы избежать дублирования целых файлов конфигурации (с хорошо известными связанными проблемами) И для уменьшения повторения. Техника также идеально подходит для интернационализации (i18n) - даже в том же файле, если это необходимо.
Пример, фрагмент предварительно обработанной конфигурации JSON:
var config = {
'ver': '1.0',
'help': {
'BLURB': 'This pre-production environment is not supported. Contact Development Team with questions.',
'PHONE': '808-867-5309',
'EMAIL': 'coder.jen@lostnumber.com'
},
'help@www.productionwebsite.com': {
'BLURB': 'Please contact Customer Service Center',
'BLURB@fr': 'S\'il vous plaît communiquer avec notre Centre de service à la clientèle',
'BLURB@de': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
'PHONE': '1-800-CUS-TOMR',
'EMAIL': 'customer.service@productionwebsite.com'
},
}
... и постобработка (в данном случае при рендеринг время) с учетом динамического, известного браузеру окружения location.hostname = ' www.productionwebsite.com ' и язык навигатора ' de '):
prefer(config,['www.productionwebsite.com','de']); // prefer(obj,string|Array<string>)
JSON.stringify(config); // {
'ver': '1.0',
'help': {
'BLURB': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
'PHONE': '1-800-CUS-TOMR',
'EMAIL': 'customer.service@productionwebsite.com'
}
}
Если неаннотированное («базовое») свойство не имеет конкурирующего аннотированного свойства, оно остается одним (предположительно глобальным для разных сред), в противном случае его значение заменяется аннотированным значением, если суффикс совпадает один из входов в функцию предпочтения / дискриминации. Аннотированные свойства, которые не совпадают, удаляются полностью.
Вы можете смешивать и сопоставлять это поведение для аннотирования конфигурации, чтобы добиться различий между глобальными, стандартными, специфичными, которые (если вы разумны) читаются с нулевым / минимальным дублированием.
Единственная, рекурсивная курсная () функция (как мы ее называем, без необходимости или желания сделать из нее целый проект / фреймворк), которую мы разработали до сих пор (см. jsFiddle , со встроенными документами) идет немного дальше, чем этот простой пример, и (более подробно объяснено здесь ) обрабатывает глубоко вложенные объекты конфигурации, а также преференциальный порядок и (если вы нужно остаться без изменений) комбинация суффиксов.
Функция полагается на способность JS ссылаться на свойства объекта как строки, динамически и допускать @ и & разделители в именах свойств, которые недопустимы в синтаксисе с точечной нотацией, но, следовательно, (помогают) не позволяют разработчикам нарушать эту технику, случайно ссылаясь на к предварительно обработанным / аннотированным атрибутам в коде (если они, как правило, не предпочитают использовать точечные обозначения.)
У нас еще не было этого разрыва для нас, и мы не были обучены каким-либо фундаментальным недостаткам этой техники, за исключением безответственного / непреднамеренного использования или инвестиций / привязанности к существующим основам / методам, которые уже существуют. Мы также не профилировали его для производительности (мы, как правило, запускаем его один раз за сборку / сессию и т. Д.), Поэтому для вашего собственного использования, YMMV.
Большинство конфигураций, передаваемых на стороне клиента, разумеется, не захотят содержать конфиденциальные значения перед началом производства, поэтому можно (следует!) Использовать эту же функцию для создания версии только для производства (без аннотаций) перед развертыванием, все еще наслаждаясь ОДИНОЧНЫМ файлом конфигурации перед вами в процессе.
Кроме того, если вы делаете это для i18n, вы можете не захотеть, чтобы весь пакет проходил по проводам, поэтому можете обработать его на стороне сервера (кэшированный или живой, и т. Д.) Или предварительно обработать его в build / deploy разделив на отдельные файлы, но ВСЕ ЕЩЕ наслаждайтесь единым источником правды как можно раньше в вашем рабочем процессе.
Мы не исследовали реализацию той же функции в Java (или C #, PERL и т. Д.), Предполагая, что это даже возможно (возможно, с каким-то экзотическим отражением?), Но среда сборки, включающая NodeJS, могла бы легко справиться с этой задачей.