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

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

Feb 17, 2025 am 10:48 AM

构建基于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

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

JavaScript难以学习吗? JavaScript难以学习吗? Apr 03, 2025 am 12:20 AM

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

如何实现视差滚动和元素动画效果,像资生堂官网那样?
或者:
怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? 如何实现视差滚动和元素动画效果,像资生堂官网那样? 或者: 怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? Apr 04, 2025 pm 05:36 PM

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的演变:当前的趋势和未来前景 JavaScript的演变:当前的趋势和未来前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

console.log输出结果差异:两次调用为何不同? console.log输出结果差异:两次调用为何不同? Apr 04, 2025 pm 05:12 PM

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...

See all articles