Я передаю функцию stringify
в шаблон EJS. Он действует как include
, который всасывает все в одну строку, поэтому легко создавать строки из сложных данных, таких как JSON и XML. Шаблон EJS может выглядеть примерно так
{
"body": "<%- stringify('users.xml') %>"
}
В этом примере я бы хотел, чтобы 'users.xml' рассматривался относительно файла, который выполняет вызов stringify
. Это согласованное поведение с EJS includes
.
Проблема в том, что я не могу найти способ получить контекст файла, который вызывает stringify (CALLING_FILE
в приведенном ниже коде):
function stringify (filename) {
const resolvedPath = path.join(path.dirname(CALLING_FILE), filename),
contents = fs.readFileSync(resolvedPath, 'utf8'),
rendered = ejs.render(contents, { stringify }),
jsonString = JSON.stringify(rendered.trim());
// get rid of the surrounding quotes
return jsonString.substring(1, jsonString.length - 1);
}
Эта проблема проявляется во вложенных включениях: a.ejs
включает subdir/b.ejs
, subdir/b.ejs
вызывает stringify
на c.ejs
. Файл c.ejs
должен автоматически принять значение subdir
, так как он вызывается с subdir/b.ejs
.
Я могу переопределить ejs.fileLoader
и, используя магию регулярных выражений, построить карту всех литеральных значений имени файла, переданных в stringify
, и файла, который его вызывает, но это разбивается как минимум в двух сценариях:
- Когда пользователь создает блок JavaScript и инициализирует переменную, передавая переменную
stringify
и
- Когда два разных файла в двух разных каталогах оба вызывают
stringify
с одинаковым именем файла. Например, включенный файл subdir1 / b.ejs вызывает stringify для c.ejs, а включенный файл subdir2 / d.ejs вызывает stringify для c.ejs. В этом случае должно быть два отдельных файла c.ejs, один в subdir1 и один в subdir2. Так как все, что я смогу отключить карту в контексте вызова stringify
, это c.ejs, я не смогу определить, какой путь использовать.
Есть ли другой способ получить путь к файлу вызывающего файла?