render.mjs
1.31 KB
// lib/render.mjs — literal-safe template render (replaces scope-lock/render.sh)
//
// 用法(CLI):node lib/render.mjs <tplPath> <varsJsonPath> <outPath>
// 程序内:import { render } from './render.mjs'
//
// 核心要求:{{key}} 占位替换;值中含 $、{、}、}} 不被二次解释(字面插入);
// 先剥离 HTML 注释(模板引导文本);缺少变量则 throw(不静默留空)。
export function render(template, vars) {
const withoutComments = template.replace(/<!--[\s\S]*?-->/g, '')
return withoutComments.replace(/\{\{(\w+)\}\}/g, (_, key) => {
if (!(key in vars)) throw new Error(`render: missing var "${key}"`)
return String(vars[key]) // 字面插入,不二次解释 $ 或 {}
})
}
// 入口判定用 pathToFileURL 规范化 process.argv[1],使其与 import.meta.url 编码一致
// (路径含空格/非 ASCII/Windows 反斜杠时,字面 `file://${argv[1]}` 比较会失配)。
const { pathToFileURL } = await import('node:url')
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
const { readFileSync, writeFileSync } = await import('node:fs')
const [tplPath, jsonPath, outPath] = process.argv.slice(2)
const tpl = readFileSync(tplPath, 'utf8')
const vars = JSON.parse(readFileSync(jsonPath, 'utf8'))
writeFileSync(outPath, render(tpl, vars))
}