使用 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 、Response和Next 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。
之后,在根目录中创建目录Controllers、Models、Routes和types 。
- 控制器——包含应用程序的所有业务逻辑
- 模型- 包含 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 的 docker和docker 配置 的信息。
在根目录下创建文件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