首页 > web前端 > js教程 > 使用node.js,git和markdown构建微博

使用node.js,git和markdown构建微博

Christopher Nolan
发布: 2025-02-17 10:48:14
原创
502 人浏览过

构建基于Node.js、Git和Markdown的微型博客

本文探讨了如何使用Node.js、Git和少量依赖项构建一个微型博客。此应用旨在从提交到存储库的文件中提供静态内容。您将学习如何构建和测试应用程序,并深入了解交付解决方案的过程。最终,您将拥有一个极简的、可运行的博客应用程序,您可以在此基础上进行构建。

Building a Microblog Using Node.js, Git and Markdown

关键要点:

  • Node.js 提供了一套平衡的 API,非常适合构建无需不必要复杂性的微型博客平台。
  • Git 用于将博客文章存储为版本控制的文本文档,无需使用传统的数据库。
  • Markdown 用于博客文章格式化,允许使用轻量级内容,并可以逐步增强。
  • Roast.it 用于单元测试,因为它简单且没有依赖项,从而可以快速获得反馈并增强开发人员的信心。
  • 微型博客架构的设计围绕简洁性,具有用于提供博客内容的路由和最少的依赖项,从而确保快速性能。
  • 应用程序使用自定义 Markdown 解析器和简单的模板函数将 Markdown 转换为 HTML,确保博客轻量且响应迅速。

微型博客的主要组成部分

要构建一个很棒的博客,首先,您需要一些组件:

  • 用于发送 HTTP 消息的库
  • 用于存储博客文章的存储库
  • 单元测试运行器或库
  • Markdown 解析器

为了发送 HTTP 消息,我选择 Node.js,因为它提供了从服务器发送超文本消息所需的一切。特别感兴趣的两个模块是 httpfshttp 模块将创建一个 Node HTTP 服务器。fs 模块将读取文件。Node 拥有使用 HTTP 构建微型博客的库。

为了存储博客文章存储库,我将选择 Git 而不是功能齐全的数据库。原因是,Git 本身就是一个具有版本控制的文本文档存储库。这正是我存储博客文章数据所需的一切。摆脱添加数据库作为依赖项,使我不必为大量问题编写代码。

我选择使用 Markdown 格式存储博客文章,并使用 marked 解析它们。如果我以后决定这样做,这将使我能够自由地逐步增强原始内容。Markdown 是普通 HTML 的一种不错的轻量级替代方案。

对于单元测试,我选择优秀的测试运行器 roast.it。我选择这个替代方案是因为它没有依赖项,并且满足了我的单元测试需求。您可以选择其他测试运行器,如 taper,但它大约有八个依赖项。我喜欢 roast.it 的原因是它没有依赖项。

有了这个组件列表,我就拥有了构建微型博客所需的所有依赖项。

选择依赖项并非易事。我认为关键是任何超出当前问题范围的东西都可能成为依赖项。例如,我没有构建测试运行器或数据存储库,因此将其添加到列表中。任何给定的依赖项都不能吞噬解决方案并劫持代码。因此,只选择轻量级组件是有意义的。

本文假设您已经熟悉 Node、npm 和 Git,以及各种测试方法。我不会逐步介绍构建微型博客的每个步骤,而是重点讨论代码的特定区域。如果您想在家中跟随操作,代码已上传到 GitHub,您可以尝试每个代码片段。

测试

测试使您对代码充满信心并加强反馈循环。编程中的反馈循环是指编写任何新代码和运行它之间所需的时间。在任何 Web 解决方案中,这意味着要跳过许多层才能获得任何反馈。例如,浏览器、Web 服务器甚至数据库。随着复杂性的增加,这可能意味着需要几分钟甚至一小时才能获得反馈。使用单元测试,我们可以减少这些层并获得快速反馈。这使重点放在当前问题上。

我喜欢从编写快速的单元测试开始任何解决方案。这让我开始为任何新代码编写测试。这就是您如何使用 roast.it 开始运行的方式。

package.json 文件中添加:

"scripts": {
  "test": "node test/test.js"
},
"devDependencies": {
  "roast.it": "1.0.4"
}
登录后复制
登录后复制
登录后复制

test.js 文件是您引入所有单元测试并运行它们的地方。例如,您可以执行以下操作:

var roast = require('roast.it');

roast.it('Is array empty', function isArrayEmpty() {
  var mock = [];

  return mock.length === 0;
});

roast.run();
roast.exit();
登录后复制
登录后复制

要运行测试,请执行 npm install && npm test。让我高兴的是,我不再需要费尽心思来测试新代码了。这就是测试的意义所在:快乐的程序员获得信心并专注于解决方案。

骨架

微型博客将使用 Node 来响应客户端请求。一种有效的方法是通过 http.CreateServer() Node API。这可以在 app.js 中的以下摘录中看到:

/* app.js */
var http = require('http');
var port = process.env.port || 1337;

var app = http.createServer(function requestListener(req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8'});
  res.end('A simple micro blog website with no frills nor nonsense.');
});

app.listen(port);

console.log('Listening on http://localhost:' + port);
登录后复制
登录后复制

通过 package.json 中的 npm 脚本运行此脚本:

"scripts": {
  "start": "node app.js"
}
登录后复制
登录后复制

现在,http://localhost:1337/ 成为默认路由,并向客户端返回消息。其想法是添加更多路由以返回其他响应,例如使用博客文章内容进行响应。

文件夹结构

为了构建应用程序的结构,我决定使用以下主要部分:

使用node.js,git和markdown构建微博

我将使用这些文件夹来组织代码。以下是每个文件夹用途的概述:

  • blog:存储纯 Markdown 格式的原始博客文章
  • message:可重用的模块,用于构建对客户端的响应消息
  • route:除默认路由之外的路由
  • test:编写单元测试的地方
  • view:放置 HTML 模板的地方

更多路由和测试

对于第一个用例,我将介绍博客文章的另一条路由。我选择将其放在名为 BlogRoute 的可测试组件中。我喜欢的是您可以将依赖项注入其中。单元及其依赖项之间的这种关注点分离使得单元测试成为可能。每个依赖项在隔离的测试中都会获得一个模拟。这允许您编写不可变、可重复且快速的测试。

例如,构造函数如下所示:

"scripts": {
  "test": "node test/test.js"
},
"devDependencies": {
  "roast.it": "1.0.4"
}
登录后复制
登录后复制
登录后复制

有效的单元测试是:

var roast = require('roast.it');

roast.it('Is array empty', function isArrayEmpty() {
  var mock = [];

  return mock.length === 0;
});

roast.run();
roast.exit();
登录后复制
登录后复制

目前,BlogRoute 期望一个 req 对象,它来自 Node API。为了使测试通过,只需执行以下操作:

/* app.js */
var http = require('http');
var port = process.env.port || 1337;

var app = http.createServer(function requestListener(req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8'});
  res.end('A simple micro blog website with no frills nor nonsense.');
});

app.listen(port);

console.log('Listening on http://localhost:' + port);
登录后复制
登录后复制

有了这个,我们可以将其连接到请求管道。您可以在 app.js 中执行以下操作:

"scripts": {
  "start": "node app.js"
}
登录后复制
登录后复制

拥有测试的好处是我不必预先担心实现细节。我很快就会定义 messageresreq 对象来自 http.createServer() Node API。

存储库

下一个要解决的问题是在 BlogRoute.route() 中读取原始博客文章数据。Node 提供了一个 fs 模块,您可以使用它从文件系统读取。

例如:

/* route/blogRoute.js */
var BlogRoute = function BlogRoute(context) {
  this.req = context.req;
};
登录后复制

此代码片段位于 message/readTextFile.js 中。在解决方案的核心,您读取存储库中的文本文件。请注意,fs.readFile() 是一个异步操作。这就是它采用 fn 回调并使用文件数据调用它的原因。此异步解决方案使用简单的回调。

这提供了文件 IO 的需求。我喜欢它的地方在于它只解决一个问题。由于这是一个跨领域的问题,例如读取文件,因此无需进行单元测试。单元测试应该只测试您自己代码的隔离性,而不是其他人的代码。

理论上,您可以模拟内存中的文件系统并以此方式编写单元测试,但是解决方案随后将开始在各个地方泄漏关注点并变成混乱。

读取文件等跨领域问题超出了代码的范围。例如,读取文件取决于您无法直接控制的子系统。这使得测试变得脆弱,并增加了反馈循环的时间和复杂性。这是一个必须与您的解决方案分离的问题。

Markdown 解析器

下一个问题是将存储库中的原始 Markdown 数据转换为 HTML。此过程分为两个步骤:

  • view 文件夹获取 HTML 模板
  • 将 Markdown 解析为 HTML 并填充模板

在健全的编程中,其想法是将一个大问题分解成小的、易于处理的部分。让我们解决第一个问题:如何根据我在 BlogRoute 中的内容获取 HTML 模板?

一种方法可能是:

/* test/blogRouteTest.js */
roast.it('Is valid blog route', function isValidBlogRoute() {
  var req = {
    method: 'GET',
    url: 'http://localhost/blog/a-simple-test'
  };

  var route = new BlogRoute({ req: req });

  return route.isValidRoute();
});
登录后复制

请记住,这将替换上一节中使用的虚拟回调,称为 dummyTest

要替换回调 dummyTest,请执行以下操作:

"scripts": {
  "test": "node test/test.js"
},
"devDependencies": {
  "roast.it": "1.0.4"
}
登录后复制
登录后复制
登录后复制

(后续内容因篇幅限制而省略,请根据需要自行补充)

以上是使用node.js,git和markdown构建微博的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板