使用node.js,git和markdown构建微博
构建基于Node.js、Git和Markdown的微型博客
本文探讨了如何使用Node.js、Git和少量依赖项构建一个微型博客。此应用旨在从提交到存储库的文件中提供静态内容。您将学习如何构建和测试应用程序,并深入了解交付解决方案的过程。最终,您将拥有一个极简的、可运行的博客应用程序,您可以在此基础上进行构建。
关键要点:
- Node.js 提供了一套平衡的 API,非常适合构建无需不必要复杂性的微型博客平台。
- Git 用于将博客文章存储为版本控制的文本文档,无需使用传统的数据库。
- Markdown 用于博客文章格式化,允许使用轻量级内容,并可以逐步增强。
- Roast.it 用于单元测试,因为它简单且没有依赖项,从而可以快速获得反馈并增强开发人员的信心。
- 微型博客架构的设计围绕简洁性,具有用于提供博客内容的路由和最少的依赖项,从而确保快速性能。
- 应用程序使用自定义 Markdown 解析器和简单的模板函数将 Markdown 转换为 HTML,确保博客轻量且响应迅速。
微型博客的主要组成部分
要构建一个很棒的博客,首先,您需要一些组件:
- 用于发送 HTTP 消息的库
- 用于存储博客文章的存储库
- 单元测试运行器或库
- Markdown 解析器
为了发送 HTTP 消息,我选择 Node.js,因为它提供了从服务器发送超文本消息所需的一切。特别感兴趣的两个模块是 http
和 fs
。http
模块将创建一个 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/
成为默认路由,并向客户端返回消息。其想法是添加更多路由以返回其他响应,例如使用博客文章内容进行响应。
文件夹结构
为了构建应用程序的结构,我决定使用以下主要部分:
我将使用这些文件夹来组织代码。以下是每个文件夹用途的概述:
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" }
拥有测试的好处是我不必预先担心实现细节。我很快就会定义 message
。res
和 req
对象来自 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中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

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

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

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

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

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

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

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