Nodejs模版实现原理

Nodejs模版实现原理

看到很多人用的是express 但是我不想用第三方模版 问一下自己写的话要怎么实现

原理是node 引入 .html 然后 replace 标记的地方(如 <%%>)么,然后再send回去么?

15 回复

当然可以!如果你想要自己实现一个简单的模板引擎,你可以使用 Node.js 的文件读取和字符串替换功能来实现。下面是一个简单的示例代码,展示如何从 HTML 文件中读取内容,并根据模板标记进行替换。

示例代码

假设我们有一个 HTML 模板文件 template.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><%% title %%></title>
</head>
<body>
    <h1>Hello, <%% name %%>!</h1>
    <p>Welcome to our website.</p>
</body>
</html>

接下来,我们编写一个简单的 Node.js 脚本来读取这个模板文件,并根据提供的数据进行替换:

const fs = require('fs');
const path = require('path');

// 定义模板文件路径
const templatePath = path.join(__dirname, 'template.html');

// 读取模板文件内容
fs.readFile(templatePath, 'utf8', (err, data) => {
    if (err) {
        console.error('Error reading file:', err);
        return;
    }

    // 定义需要替换的数据
    const replacements = {
        title: 'Welcome Page',
        name: 'John Doe'
    };

    // 替换模板中的占位符
    let result = data;
    for (const [key, value] of Object.entries(replacements)) {
        const regex = new RegExp(`<%% ${key} %%>`, 'g');
        result = result.replace(regex, value);
    }

    // 输出结果
    console.log(result);

    // 可以将结果发送给客户端
    // res.send(result);
});

解释

  1. 读取模板文件:使用 fs.readFile 方法读取模板文件的内容。
  2. 定义替换数据:创建一个对象 replacements,其中包含需要替换的键值对。
  3. 替换占位符:遍历 replacements 对象,使用正则表达式匹配并替换模板中的占位符(例如 <%% title %%><%% name %%>)。
  4. 输出结果:将替换后的结果输出到控制台。如果是在服务器端运行,你可以将结果发送给客户端(例如使用 Express 的 res.send 方法)。

这个示例展示了如何通过简单的字符串替换来实现一个基本的模板引擎。你可以根据需要扩展这个示例,添加更多的功能,比如支持条件语句、循环等复杂逻辑。


思路是对的。模板就是做变量替换。 好的模板支持 for in, if else。这些功能自己实现就不那么容易了。

我弄过一个 (后来半途而废了) 遇到了这些问题

  • 异步读模板文件还是同步读?
  • 模板里面某个变量能不能是异步获取的, 还是说所有内容都要等到数据准备完毕之后填入模板? (比如, 模板里一个分支, 如果满足条件就去查数据库里面的 x, 否则去查数据库里面的 y, 如果预先把 x 跟 y 都准备好就有点浪费了, 不过这个问题可能纯粹是我吃饱了撑的, 应该在 handler 里面解决?)

倒不是说这些解决不了, 只是解决方案很恶心, 回调套回调什么的… 所以最近在考虑弄个编译器先把回调给扭过来 (参考赵老师的 wind.js)

我也想知道, 那种挖空格一样的模板引擎是怎么写出来的?

高性能的模板是有“预编译”的,最终会创建一个函数,输入值,输出结果。 例如value is {value}可能会“编译”成 function(value) { return “value is”+value; }

这样的话第一次读取模板肯定是同步读取的, 而且如果运行时模板文件发生了变化, 页面不会立即更改, 必须重启服务器.

用fs 打开html文件 替换变量 然后再输出? 总觉得绕来绕去的,会不会效率上会有影响呢? 难道php 等也是这个原理么?

文件操作是慢一些。好的模板引擎会cache模板文件内容和对模板文件内容进行预处理。

我会选异步处理。小文件用同步还说得过去,文件多了就可能把主程序堵上了。

把ejs或者jade读懂不就知道该怎么写了?直接觉得不好,可以写,但是请你先学习基本的东西再来问“XXX怎么写”?

已经有些好的放在那里了,开源的,自己看代码很难么。

每个人都有自己的学习风格好么?! 正因为是初学者才想从基础搞起,不想去用模版什么的?! 正因为是初学者开源码才觉得吃力,才要去边问边学?OK?!

模板里还去查数据库。。。感觉不太好。

终于找你了,不知道你还在折腾不! 这里有个腾讯的讲了些原理 http://cdc.tencent.com/?p=5723 你可以参看下!

还在折腾 谢了~

要实现一个简单的模板引擎,可以使用 Node.js 的内置模块来读取和处理 HTML 文件。下面是一个基本的模板引擎实现示例,它会读取一个 HTML 文件,并替换其中的特定标记。

示例代码

  1. 创建一个简单的 HTML 模板文件 template.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><%% title %%></title>
</head>
<body>
    <h1>Hello, <%% name %%>!</h1>
</body>
</html>
  1. 编写 Node.js 脚本 server.js 来读取并渲染模板
const fs = require('fs');
const path = require('path');

// 定义模板路径
const templatePath = path.join(__dirname, 'template.html');

// 读取模板文件
fs.readFile(templatePath, 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }

    // 定义数据对象
    const dataObj = {
        title: 'My Custom Title',
        name: 'John Doe'
    };

    // 替换模板中的标记
    let renderedHtml = data;
    for (let key in dataObj) {
        const pattern = new RegExp(`<%% ${key} %%>`, 'g');
        renderedHtml = renderedHtml.replace(pattern, dataObj[key]);
    }

    // 输出结果
    console.log(renderedHtml);
});

原理解释

  1. 读取模板文件

    • 使用 fs.readFile 读取 HTML 文件的内容。
  2. 定义数据对象

    • 创建一个包含需要替换的数据的对象 dataObj
  3. 替换模板中的标记

    • 使用 for...in 循环遍历数据对象的键。
    • 使用正则表达式匹配模板中相应的标记,并使用 String.prototype.replace 方法进行替换。
  4. 输出结果

    • 将最终渲染后的 HTML 输出到控制台。

总结

上述代码实现了一个非常基础的模板引擎,它通过读取 HTML 文件,并使用正则表达式替换指定的标记。这种方法简单直观,适用于小规模的项目或学习目的。如果需要更强大的功能,可以考虑使用成熟的模板引擎库,如 EJS 或 Pug。

回到顶部