代码创建向导是现代开发 IDE 提供的常规功能,也是程序员比较青睐的一种开发方式。毕竟不用自己敲代码,只需要点点鼠标,就会哗哗哗的生成一大段代码,何乐而不为呢?
比如下图就是 ABAP workbench 里生成 Webservice 的开发向导截图:
不过并不是所有的开发 IDE 都支持所有我们日常工作中需要创建的代码模版,当遇到现有的 IDE,无法支持某种开发任务对应的模版代码生成时,程序员有两个选择,要么去该 IDE 的 extension market place 上查找有无热心人开发的扩展,要么就自己动手。
下面我们通过一个实际的例子来介绍如何实现自定义的模版代码生成器。这个例子是通过一段模版代码,自动生成一个 Web 服务器,能够监听在用户指定的端口号上,监听用户指定 url 上发送的 HTTP get 请求,解析出请求传递的参数值,并发送给请求方。
首先准备好一个模版文件,命名为 template.js
:
const express = require('express');
// 引入 body-parser
const bodyParser = require('body-parser');
// 创建一个 express 应用
const app = express();
// 配置 body-parser 中间件,用于解析 JSON 格式的请求体
app.use(bodyParser.json());
// 设置路由和端口号
const PORT = <port>;
// 创建 get 路由处理函数
app.get('/<url>', (req, res) => {
// 获取请求体中的数据
const requestData = req.body;
// 将接收到的数据原样返回
res.json(requestData);
});
// 服务器开始监听指定端口
app.listen(PORT, () => {
console.log('服务器正在监听端口: ${PORT}');
});
这个模版文件的原理比较简单,监听在用占位符 <port>
代表的端口号上。当该端口号的 <url>
有 HTTP get 请求到来时,从 req 请求参数里,提取出 body 内容,然后直接将这个 body 内容返回给调用方。
有了模版文件之后,我们下一步就可以创建并实现模版代码生成器了。基本原理就是使用 Node.js 的 fs 模块,读取该模版文件,解析出 <port>
和 <url>
两个占位符,替换成用户指定的内容即可。
下面是生成器第一个版本的代码:
const fs = require('fs');
const path = require('path');
// 设置文件路径
const templatePath = path.join(__dirname, 'template.js');
const serverPath = path.join(__dirname, 'server.js');
// 读取模板文件
fs.readFile(templatePath, 'utf8', function(err, data) {
if (err) {
console.error('Error reading the template file:', err);
return;
}
// 替换占位符
let result = data.replace(/<port>/g, '8080').replace(/<url>/g, 'hello');
// 写入新文件
fs.writeFile(serverPath, result, 'utf8', function(err) {
if (err) {
console.error('Error writing the server file:', err);
return;
}
console.log('The file has been saved as server.js with placeholders replaced.');
});
});
我们可以看到,这个生成器的逻辑,就是读取当前目录下的 template.js
文件,解析占位符,将其用 JavaScript 字符串原生的 replace
方法,替换成硬编码的 8080 和 hello,然后将替换后的结果,另存成 server.js
文件。
生成器另存为 generator.js
, 然后我们用命令行 node .\generator.js
运行这个生成器。
生成一个 server.js 输出文件,内容如下。可以看到两个占位符都已经被替换成了我们硬编码的数据。
硬编码的做法始终不够灵活。让我们对模版代码生成器进行重构,提供两个命令行参数,允许用户输入。
改造后的代码:
const fs = require('fs');
const path = require('path');
// 从命令行参数中获取端口和 URL
const args = process.argv.slice(2);
if (args.length < 2) {
console.error('Usage: node script.js <port> <url>');
process.exit(1);
}
const port = args[0];
const url = args[1];
// 设置文件路径
const templatePath = path.join(__dirname, 'template.js');
const serverPath = path.join(__dirname, 'server.js');
// 读取模板文件
fs.readFile(templatePath, 'utf8', function(err, data) {
if (err) {
console.error('Error reading the template file:', err);
return;
}
// 替换占位符
let result = data.replace(/<port>/g, port).replace(/<url>/g, url);
// 写入新文件
fs.writeFile(serverPath, result, 'utf8', function(err) {
if (err) {
console.error('Error writing the server file:', err);
return;
}
console.log('The file has been saved as server.js with placeholders replaced.');
});
});
我们来测试一下改造过的代码生成器:使用命令行 node .\generator.js 8089 test
, 这里通过两个命令行参数,指定代码模版里占位符的实际值。
可以看到这次生成的 server.js 文件里,占位符已经正确地被我命令行里指定的两个参数所替换了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。