Система модулей в nodejs позволяет подключать не только .js и .json - файлы, но и любые другие, если вы зададите для них функцию трансляции.
Зачем это нужно? Можно напихать в эти файлы ваших собственных DSL, которые будут при включении с помощью require()
на лету транслироваться в JavaScript. Про то, зачем использовать DSL написано многабукав, и повторять все это тут я не буду.
Итак, допустим у нас есть вот такого содержания файлик (converter.rule):
USD 30
EUR 40
И мы хотим, чтобы при включении его в наш код, нам становились доступны функции для конвертации валют:
require('./converter-translator'); // Тут наш транслятор, см. далее
var converter = require('./converter.rule'),
roubles = 300;
console.log(converter.USD(roubles)); // Должно вернуть 10
console.log(converter.EUR(roubles)); // Должно вернуть 7.5
Как этого добиться? Механизм модулей в node может быть расширен, если объекту require.extensions['расширение файла']
присвоить функцию, трансляции, которая принимает в качестве параметра объект включаемого модуля, и в результате своей работы заполнит поле module.exports
(содержимое этого поля собственно и представляет модуль в том коде, который его включает).
Делаем транслятор (converter-translator.js):
var fs = require('fs');
require.extensions['.rule'] = function (module) {
// Трансляция должна быть синхронной
var moduleContent = fs.readFileSync(module.filename).toString(),
// Разбиваем файл на строки
rules = moduleContent.split('\n');
// Выкидываем пустые строки
rules = rules.filter(function (rule) { return !!rule; })
// Для каждой строки добавляем в module.exports функцию конвертации
rules.forEach(function (rule) {
var ruleParts = rule.split(' '),
currency = ruleParts[0],
value = ruleParts[1];
module.exports[currency] = function (roubles) { return roubles / value; };
});
}
Понятно, что здесь нет никаких проверок и работы с ошибками, но идея должна быть понятна.
Из минусов —
require()
кэширует подключаемые модули, поэтому повторные вызовыrequire()
для уже включенного модуля не будут приводить к его повторной трансляции. Ну и то, что по-хорошему, если без извращений, то трансляция должна быть синхронной.