使用Fastify,Esbuild和NX构建节点API
#node #服务器 #esbuild #monorepo

在构建节点API方面,有许多决定要做出。有各种各样的框架可供选择(Express,Fastify,Koa等),以及一百万个构建和部署应用程序的方式。

在本文中,我将通过使用NX创建节点API项目来向您展示从零到生产的最简单方法。

我们将使用Fastify作为首选框架。快速化是一个快速(如名称所暗示的)和节点中的低离心服务器。它的受欢迎程度越来越高,最近在NPM上跨越了每周100万个下载标记。我是Fastify的插件体系结构的粉丝,并且生态系统令人印象深刻,在250 core and community plugins上。

创建项目

您可以使用一个命令创建新的API。

$ npx create-nx-workspace@latest \
--preset=node-server \ # create a server project
--framework=fastify \  # other options are express and koa
--docker               # we'll touch on this later on

要在Dev Mode中运行服务器,请使用npx nx serve(与npm start相称),您应该看到服务器从端口3000开始。

$ curl http://localhost:3000
{"message":"Hello API"}

几个值得注意的文件:

  • src/main.ts文件负责启动快速服务器和注册插件。
  • src/app/app.ts文件是一个应用程序插件,它在/上提供了一个初始端点,该插件用{"message": "Hello API"}回复。

编辑源代码时,服务器将重新加载。您可以通过--no-watch禁用此行为。

运行测试

在生成源代码外,NX还将创建两个测试套件:

  1. 通过npx nx test进行单位测试(与npm run test相反)。
  2. E2E通过npx nx e2e e2e进行测试(与npm run e2e相反)。

单元测试利用了快速的插件架构,并允许您隔离测试每个插件。它使用Jest(是节点中最受欢迎的测试跑者)运行。

// src/app/app.spec.ts
// This file is generated by Nx.
import Fastify, { FastifyInstance } from 'fastify';
import { app } from './app';

describe('GET /', () => {
  let server: FastifyInstance;

  beforeEach(() => {
    server = Fastify();
    server.register(app);
  });

  it('should respond with a message', async () => {
    const response = await server.inject({
      method: 'GET',
      url: '/',
    });

    expect(response.json()).toEqual({ message: 'Hello API' });
  });
});

E2E测试与实际服务器(所有插件已注册)进行,该测试可提供更好的现实保证。

$ npx nx serve & # run server in background
$ npx nx e2e e2e # run test suite
GET /
     should return a message (27 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.429 s
Ran all test suites.

Tearing down...

 ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target e2e for project e2e (3s)

$ lsof -i:3000 -t | xargs kill # stop server process

在单位与E2E测试方面,速度与信心之间存在权衡,这是本文不范围的主题。我认为您应该同时做,但这是与您的团队进行的讨论。 NX支持两种情况。

使用Esbuild建造生产

现在我们拥有了准备生产的应用程序,让我们检查NX如何使用[esbuild](https://esbuild.github.io/)处理构建过程。

esbuild是一个用GO编写的捆绑器,非常快 - 它比WebPack和Parcel等其他捆绑器快得多,但是随着其他工具的其他工具可以改善自己的速度,这可能会改变。

运行构建命令时,nx使用esbuild生成一个独立的应用程序捆绑包,它不需要node_modules

$ npx nx build # aliased to npm build
> nx run api:build

 ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target build for project api (2s)

NX的一个很酷的功能是,如果项目(或其依赖关系)没有更改,则将诸如buildtest之类的命令被缓存。如果我们第二次运行构建,您会看到它以几毫秒完成。

$ npx nx build
> nx run api:build  [existing outputs match the cache, left as is]

 ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target build for project api (16ms)

   Nx read the output from the cache instead of running the command for 1 out of 1 tasks.

当我们查看Docker支持时,我们会在缓存中触摸更多。

现在,服务器捆绑包已经准备就绪,我们可以运行它。

$ node dist/api
{"level":30,"time":1675880059720,"pid":70605,"hostname":"mbp.lan","msg":"Server listening at http://[::1]:3000"}
{"level":30,"time":1675880059721,"pid":70605,"hostname":"mbp.lan","msg":"Server listening at http://127.0.0.1:3000"}
[ ready ] http://localhost:3000

您甚至可以针对生产捆绑包运行E2E套件:npx nx e2e e2e

Docker支持

回想一下,在创建API项目时,我们通过了--docker选项。使用此选项,NX将生成默认的Dockerfiledocker-build目标。

# This file is generated by Nx.
#
# Build the docker image with `npx nx docker-build api`.
# Tip: Modify "docker-build" options in project.json to change docker build args.
#
# Run the container with `docker run -p 3000:3000 -t api`.
FROM docker.io/node:lts-alpine

ENV HOST=0.0.0.0
ENV PORT=3000

WORKDIR /app

RUN addgroup --system api && \
    adduser --system -G api api

COPY dist/api api
RUN chown -R api:api .

CMD [ "node", "api" ]

要构建图像,运行npx nx docker-build。图像仅复制独立捆绑包,因此根本没有npm install

nx足够聪明,可以在构建Docker Image之前将应用程序包装,因为project.json中的dependsOn配置。您可以使用npx nx graph可视化这种依赖。

Nx graph

现在构建了图像,我们可以运行它。

$ docker run -p 3000:3000 -t api
{"level":30,"time":1675880993256,"pid":1,"hostname":"248744de020a","msg":"Server listening at http://0.0.0.0:3000"}
[ ready ] http://0.0.0.0:3000

注意:服务器与0.0.0.0结合,以便可以从主机计算机访问。您可以运行卷发以验证它确实有效,或者更好地使用E2E测试套件(npx nx e2e e2e)!

部署服务器

我们可以将应用程序部署到许多平台上。我喜欢Fly.io,因为它很容易使用CLI在世界范围内部署,并且它具有良好的Docker support

如果您以前没有使用过飞行,请关注他们的short getting started guide(5-10分钟)。

准备好后,让我们配置我们的项目。

$ fly launch --generate-name --no-deploy

遵循提示,将生成一个fly.toml文件,其中包含飞行配置。我们需要使用图像使用的正确端口更新此文件。

[[services]]
  http_checks = []
  internal_port = 3000 # Make sure this matches what the app listens on

现在我们可以部署应用程序。

$ fly deploy

Fly将在成功部署该应用时记录监视链接。

Fly dashboard

您可以使用fly open打开部署的服务器。

App running in production

就是这样!现在,我们的服务器已部署供全世界使用。

概括

在这篇文章中,我们看到了使用NX从零代码到部署的服务器的容易。这是点的快速摘要。

  1. 使用create-nx-workspace --preset=node-server --framework=fastify --docker快速创建一个快速服务器项目。
  2. nx提供单位测试和E2E测试套件 - npx nx testnpx nx e2e e2e
  3. nx使用esbuild npx nx build构建服务器。
  4. Docker支持是通过--docker选项提供的,NX了解Docker构建取决于该应用程序要捆绑。通过npx nx docker-build
  5. 运行它
  6. 部署飞行(或其他平台)很容易,因为我们有一个docker映像。

要了解有关NX及其还能做什么的更多信息,请参阅文档中的intro page

了解更多

另外,如果您喜欢这个,请单击“”,并确保在Twitter上关注JackNx以获取更多信息!

nx <按钮名称=“ button” type =“ button” data-info ='{“ className”:“ tag”,“ style”:“ full”,“ id”,“ id”:18643,“ name”:“:” nx“}'class =” crayons-btn toluck-action-button whitespace-nowrap c-btn-中学fs base“ aria-label =” laster tag tag:nx“ aria-pressed =“ false”> laste