在没有 Express 模板引擎的情况下向 HTML 添加值?

Adding Values to HTML Without a Template Engine in Express?

我已经接管了一个站点的开发,该站点使用 Express 在 Node 上运行。我应该注意到,这是我第一次使用 Node 或 Express。出于某种原因,原始开发人员一定不喜欢模板引擎,因为他已经完全删除了它们。我们基本上在前端使用 Angular 和 Firebase 来处理所有事情,所以我理解为什么我们不会经常向服务器端的页面注入数据。不过,能够这样做仍然很好。

原来没装过模板引擎。相反,他指示 Node 将 views 文件夹视为静态目录。然后,他将这些文件呈现为纯静态文件。例如:

摘自 App.js 文件:

app.use(express.static(path.join(__dirname, 'views')));

路线文件摘录:

router.get("/", function(request, response) {
    response.render("index.html");
});

此时我真的不想添加模板引擎并弄乱路由。尽管我严重怀疑我是否需要经常从服务器端注入数据,但如果有的话,我想知道我将如何做到这一点。

我唯一能想到的就是这样...

router.get("/", function(request, response) {
    var data = request.query.someVariable;
    var fileContents = fs.readFileSync('../views/index.html', 'utf8')
    fileContents = fileContents.replace("$SomeDelim", data);
    response.send(fileContents);
});

这不是真的那么漂亮。有没有更好的方法不使用模板引擎来做到这一点?

我认为您的问题没有正确答案,但让我作为 Express/Node(和 Angular)的重度用户给您我的意见。

您似乎不想使用模板引擎,因为您的模板几乎是静态的,但又不是完全静态的。后者在 Angular 项目中极为常见,因为 99.9% 的视图逻辑发生在 front-end 中。我同意你有时有必要在你的主要 Angular 引导页面或 e-mail 模板中引入变量。

您对文件内容进行替换的建议不一定是坏事,但 fs.readFileSync 是。这将阻止您的功能并阻止脚本的执行,等待文件系统。我会改用 fs.readFile 和回调函数。这样,当文件系统打开文件时,Node 的事件循环可以继续做其他事情。

我还想指出,对整个文件进行替换会导致 Node 将整个文件加载到内存中(由于替换可能会加载两次),对于较大的文件应该避免这种情况。然后你会想要这样做 line-by-line。我认为这不是您现在真正关心的问题。

我的建议是添加一个简单的模板引擎。为什么?因为它运行良好,因为它有文档记录,因为程序员知道如何使用它,因为它易于实现,因为一些较小的模板引擎完全按照您的建议进行操作。

我个人推荐Hogan.js,这是一个简单的模板引擎,被各种语言的程序员所熟知,主要做一些简单的替换,就像你想要的那样。 Hogan 基本上是这样替换变量的:<div>{{variable}}</div>。它有一个非常简单的切换方式 "if/else" 和一些简单的循环。基本上就这些了。

您可以更改您的 Express 应用以包含以下内容(并且您将删除现有的静态 'views' 声明):

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hjs');

使用 Hogan,您的视图文件将获得 .hjs 文件扩展名。

views/index.hjs

<section>
    <div>{{variable}}</div>
</section>

routes/index.js

route.get(function (req, res) {
    res.render('index', {
        variable: 'example',
    });
});

与您自己的解决方案类型相比,添加此模板引擎没有任何问题,并且不会影响您的性能。

如果您关心性能,请在您的 Node 应用程序前面放一个 reverse-proxy/webserver 类似 nginx 的程序,让它为所有静态文件提供服务。此外,在主模板路由中设置正确的 http 缓存 headers 以避免在 Node 上受到过多的攻击。