使用 TypeScript 和 Docker 构建生产就绪的 Node.js 应用程序

2025-06-08

使用 TypeScript 和 Docker 构建生产就绪的 Node.js 应用程序

在本文中,我们将了解如何构建 Node.js 和 TypeScript 应用程序,并使用 Docker 将其部署到服务器。使用 TypeScript 和 Docker 构建可投入生产的 Node.js 应用。

如果您是 TypeScript 新手,请观看本教程,其中介绍了 TypeScript 的基础知识。

应用程序设置

首先,你需要在你的机器上安装 TypeScript。运行以下命令,这将在你的机器上全局安装 TypeScript。

npm install -g typescript 

创建目录并使用命令初始化node.js应用程序。

npm init --yes

之后,您需要为 typescript 创建一个配置文件,将 typescript 编译为 javascript。

tsc --init

它将创建一个名为tsconfig.json的配置文件,其中包含应用程序的 TypeScript 配置。

配置 TypeScript

此外,配置文件包含可以配置的编译器选项。重要的选项是,

  • 目标- 它可以是 ES6 或 ES5,根据选项,TypeScript 将代码编译为 ES6 或 ES5。
  • outDir——它指定存储编译代码的目录。
  • rootDir - 它指定了 TypeScript 代码所在的目录。
  • moduleResolution - 指定模块解析策略

一旦配置完成,我们需要安装一些依赖项来在 express 应用程序上设置和运行 typescript。

使用命令安装以下依赖项

npm i -D typescript ts-node @types/node @types/express
  • ts-node - 它是一个使用 TypeScript 和 Node.js 的包。我们可以使用ts-node app.ts运行应用程序
  • @types/node - 它用 TypeScript 定义 Node.js 的自定义类型
  • @types/express - 它定义了 TypeScript 中 Express 应用程序的自定义类型

之后,在 package.json 中创建一个脚本来编译和运行应用程序。

"scripts": {
    "dev": "ts-node src/app.ts",
    "start": "ts-node dist/app.js",
    "build": "tsc -p ."
  }

使用 TypeScript 构建 Express 应用程序

一旦 TypeScript 配置完成,我们就可以使用 TypeScript 构建 Express 应用程序。

创建一个名为src的目录,其中包含 TypeScript 文件,并在其中添加app.ts文件。

import express,{ Application,Request,Response,NextFunction } from 'express';
import bodyParser from 'body-parser';

const app : Application = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));


app.get('/',(req:Request,res : Response ) => {

    res.send('TS App is Running')
})

const PORT = process.env.PORT;


app.listen(PORT,() => {
    console.log(`server is running on PORT ${PORT}`)
})

使用 TypeScript 的优点之一是定义变量的类型(静态检查)。

这里的 Express 实例将是Application类型,因此变量必须是 Application 类型。Request 、ResponseNext Function(中间件)也是如此。

之后,我们需要编写连接数据库的逻辑。创建一个名为connect.ts的文件并添加以下代码,

import mongoose from 'mongoose';

type DBInput = {
    db : string;
}

export default({db} : DBInput) => {
    
    const connect = () => {
        mongoose
            .connect(db,{ useNewUrlParser : true })
            .then(() => {
                return console.info(`Successfully connected to ${db}`);
            })
            .catch((err) => {
                console.error(`Error connecting to database :`,err);

                return process.exit(1);
            })
    };

    connect();

    mongoose.connection.on('disconnected',connect);
}

DBInput是一种将变量 db 作为字符串的类型。我们使用它来连接 mongodb。

之后,在根目录中创建目录ControllersModelsRoutestypes 。

  • 控制器——包含应用程序的所有业务逻辑
  • 模型- 包含 Mongoose 的所有数据库模式。
  • 路由- 将包含应用程序的所有 API 路由
  • 类型- 将包含应用程序中使用的自定义类型

Models目录中创建文件User.mode.ts并添加以下代码,

 import mongoose, { Schema,Document } from 'mongoose';

 export interface IUser extends Document {
     email : String;
     firstName : String;
     lastName : String;
 }

 const UserSchema : Schema = new Schema({
     email : {
         type : String,
         required : true,
         unique : true
     },
     firstName : {
         type : String,
         required : true
     },
     lastName : {
         type : String,
         required : true
     }
 });

 export default mongoose.model<IUser>('User',UserSchema);

首先,我们为用户模型和用户界面定义 Mongoose 模式

Controllers目录中,创建User.controller.ts文件并添加以下代码


import User,{ IUser } from '../Models/User.model';

interface ICreateUserInput {
    email: IUser['email'];
    firstName: IUser['firstName'];
    lastName: IUser['lastName'];
}

async function CreateUser({
    email,
    firstName,
    lastName
  }: ICreateUserInput): Promise<IUser> {
    return User.create({
      email,
      firstName,
      lastName
    })
      .then((data: IUser) => {
        return data;
      })
      .catch((error: Error) => {
        throw error;
      });
  }
  
  export default {
    CreateUser
  };

之后,在 Routes 目录中创建一个文件 index.ts 并添加以下代码,

import { RoutesInput } from '../types/route';
import UserController from '../Controllers/User.controller';

export default ({ app } : RoutesInput) => {

    app.post('api/user',async(req,res) => {
        const user = await UserController.CreateUser({
            firstName: req.body.firstName,
            lastName: req.body.lastName,
            email: req.body.email
          });
      
          return res.send({ user });
    })
}

RoutesInput是一种定义 Express 应用程序类型的自定义类型。

types目录中创建文件types.ts并添加代码,

import { Application } from 'express';
export type RoutesInput = {
  app: Application;
};

使用mongodb连接和应用程序的路由更新app.ts。

import express,{ Application,Request,Response,NextFunction } from 'express';
import "dotenv/config";
import bodyParser from 'body-parser';
import Routes from './Routes';
import Connect from './connect';

const app : Application = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));


app.get('/',(req:Request,res : Response ) => {

    res.send('TS App is Running')
})

const PORT = process.env.PORT;
const db = 'mongodb://localhost:27017/test';


Connect({ db });
Routes({ app })

app.listen(PORT,() => {
    console.log(`server is running on PORT ${PORT}`)
})

要测试应用程序,请运行脚本npm run dev并访问 URL http://localhost:4000

Docker 配置

如果您是 docker 新手,请阅读有关node.js 的 dockerdocker 配置 的信息。

在根目录下创建文件Dockerfile ,并添加以下代码。

FROM node:10

WORKDIR /usr/src/app

COPY package.json ./

RUN npm install

RUN npm install pm2 -g

RUN npm run build

COPY ./dist .

EXPOSE 4000

CMD ["pm2-runtime","app.js"]

基本上,我们采用节点基础映像并在 docker 映像容器中安装所有依赖项

之后,我们安装名为pm2的进程管理器,它主要用于所有生产应用程序。然后我们将编译后的代码从本地复制到 docker 镜像。

进一步在根目录下创建一个文件docker-compose.yml,并添加以下代码。

version: "3"

services:
  app:
    container_name: app
    restart: always
    build: .
    environment: 
      - PORT=4000 
    ports: 
      - "4000:4000" 
    links: 
      - mongo
  mongo:
    container_name: mongo
    image: mongo
    ports:
      - "27017:27017"      

Docker Compose可以将多个 Docker 服务组合起来,并在单个容器中运行。这里,我们将 MongoDB 和应用程序镜像组合起来,并在容器中运行。

Docker 部署和运行

一旦添加了 Dockerfile,请运行以下命令,

docker-compose up

它会将编译后的代码部署到docker镜像中并在容器中运行。

完整的源代码包含使用 TypeScript 和 Docker 构建生产就绪的 Node.js 应用程序。

鏂囩珷鏉ユ簮锛�https://dev.to/ganeshmani/building-a-production-ready-node-js-app-with-typescript-and-docker-107p
PREV
在 Node.js 应用程序中实现 Redis Pub/Sub
NEXT
面向 Node.js 开发人员的 Apache Kafka