使用typescript搭建express

使用typescript搭建express

开始

为这个项目创建一个新的目录,使用下面的命令初始化项目并创建一个包。

 NPM init -y

初始化后,让我们安装必要的包

npm i express dotenv cors helmet body-parser 

在express中配置typescript

npm i -D typescript @types/node @types/express @types/dotenv @types/cors @types/helmet

现在我们要在我们的目录中生成 tsconfig.json 文件。使用下面的命令:

 npx tsc --init

打开 tsconfig.json 文件,注释掉 compilerOptions 中的所有字段,并配置 baseUrl 和 outDir

在这里插入图片描述

接下来,让我们创建一个 .env 文件,定义所有敏感变量的。

创建.env文件

port=5000

创建 index.ts 文件

然后创建一个 src 文件夹,在该文件夹下创建一个 index.ts 文件,此时目录结构如下所示:

在这里插入图片描述
之后我们就在 index.ts 文件中开始编写我们的代码。

import * as dotenv from 'dotenv'
import express from 'express'
import cors from 'cors' 
import helmet from 'helmet'

// 变量
dotenv.config()

const app = express(); 

// 使用中间件
app.use(helmet()); 
app.use(cors()); 
app.use(express.json())

module.exports = app

现在在 src 目录下创建一个 server.ts 文件。

server.ts

require("dotenv").config();
const app = require(".")

const PORT = process.env.PORT || 3000
app.listen(PORT, async () => {
   console.log(`listning on port ${PORT}`)
})

现在我们必须配置我们的开发脚本,我们正在使用的另一个与开发相关的工具是 nodemon,只要文件有变化,就重新启动我们的应用程序或服务器。

此时我们还得安装一个 ts-node 执行引擎。

npm i -D nodemon ts-node

然后在目录中配置一个 nodemon.json 文件。

nodemon.json

{
    "watch" : [
       "src", 
       ".env" 
    ], 
    "ext":"js,ts,json", 
    "ignore": [
        "src/logs/*", 
        "src/**/*.{spec,test}.ts"
    ], 
    "exec": "ts-node --transpile-only src/index.ts"
}

之后在package.json 文件的 scripts 字段中设置一个运行命令用于启动 nodemon。

 "scripts" : {
     "dev" : "nodemon"
 }

现在让我们使用该命令来运行应用程序。

在这里插入图片描述

最后,让我们添加一些脚本,比如构建和启动。

"scripts":{
    "dev": "nodemon", 
    "start": "npm run build && node dist/server.js"
    "build": "tsc"
}

如果我们想在生产环境中运行,可以把 NODE_ENV=production 放在命令行中设置成变量 。如果我们想使用条件语句来执行不同的环境,则需要安装 cross-env:

npm i -D cross-env 
"scripts":{
    "dev": "nodemon", 
    "start": "npm run build && cross-env NODE_ENV=production node dist/server.js"
    "build": "tsc"
}

现在我们已经完成了项目的基本配置。

typescript 配置

现在,我们将使用一些额外的工具来改进我们的开发工作流。

typescript有很多的配置,但是我们不能在这一篇文章中涵盖所有的配置,如果我们想学习的话,可以检查官方的配置文档说明。

首先,我们配置了 paths,并用下面的配置更改了 typescript.json 文件。

{
  "compilerOptions": {
    "target": "es2020",
    "lib": ["es2020"],
    "typeRoots": ["node_modules/@types"],
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "module": "commonjs",
    "pretty": true,
    "sourceMap": true,
    "declaration": true,
    "outDir": "dist",
    "allowJs": true,
    "noEmit": false,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "importHelpers": true,
    "baseUrl": "src",
    "paths": {
      "@/*": ["*"],
      "@config/*": ["config/*"],
      "@controllers/*": ["controllers/*"],
      "@databases/*": ["databases/*"],
      "@dtos/*": ["dtos/*"],
      "@exceptions/*": ["exceptions/*"],
      "@interfaces/*": ["interfaces/*"],
      "@middlewares/*": ["middlewares/*"],
      "@models/*": ["models/*"],
      "@routers/*": ["routers/*"],
      "@services/*": ["services/*"],
      "@utils/*": ["utils/*"]
    }
  },
  "include": ["src//*.ts", "src//*.json", ".env"],
  "exclude": ["node_modules", "src/http", "src/logs", "src/tests"]
}

正如我们在上面的代码片段中看到的,我们已经添加了许多不存在的路径,我们很快就建立了我们项目的结构。paths 项允许我们定义一系列条目,这些条目重新映射导入到相对于 baseURL 的查找位置。

路径别名:使用者定义的名称来替代较长的路径。

npm i -D tsconfig-paths tslib 

tsconfig-paths 用于加载在 tsconfig.json 或者 jsconfig.json 文件中定义的 paths 模块。支持在运行时加载和通过API加载。
tslib 用作包含所有tsconfig助手功能的tsconfig的运行库。

为了使用它们,我们必须修改 nodemon.json 文件:

{
    "watch" : [
       "src", 
       ".env" 
    ], 
    "ext":"js,ts,json", 
    "ignore": [
        "src/logs/*", 
        "src/**/*.{spec,test}.ts"
    ], 
    "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts"

}

tsconfig-paths/register 将读取来自 tsconfig.json 中配置的 paths。

验证环境变量

接下来,我们将添加环境变量验证,因为忘记添加环境或不添加环境变量值的正确类型会导致意外错误,导致我们的应用程序故障。

我们使用 envalid 这个库来验证环境变量。

npm i envalid 

我们在 src 文件夹下创建一个 utils 文件夹,并创建一个 validateEnv.ts 文件

在这里插入图片描述

让我们来写这个配置

import { cleanEnv, port, str } form "envalid";

const validateEnv = () =>{
  cleanEnv(process.env, {
    NODE_ENV: str(), 
    PORT: port(),
  })
}

export default validateEnv;

写完配置后在 index.ts 文件中引用:

import * as dotenv from 'dotenv'
import express from 'express'
import cors from 'cors' 
import helmet from 'helmet'
import validateEnv from '@utils/validateEnv'

dotenv.config()

validateEnv();
const app = express(); 

app.use(helmet()); 
app.use(cors()); 
app.use(express.json())

module.exports = app

我们可以将环境变量更改为无效,例如将端口更改为字符串 PORT= XYZ

执行命令 npm run dev

它将显示一个错误,例如:

Invalid enviroment variables:
  PORT: Invalid port input: : "xyz"

但是当我们运行 build/start 命令时,我们得到了一个不同的错误:

Error: Cannot find module '@/utils/validateEnv'
This is because we are using a path alias with '@/utils'.

这个是在打包后的 dist 目录里我们的 index.js 文件是 import validateEnv from ‘@/utils/validateEnv’.

当然,我们可以在没有别名的情况下 import。然而,当我们的项目变得更大时,一个路径别名就会变得非常有用。

为了确保 node 找到模块,我们可以使用 ts-alias ,它用 typescript 编译后的相对路径替换别名路径。

npm i -D tsc-alias

我们可以通过将 build 命令修改为以下方式来利用这个包:

"build": "tsc && tsc-alias",

现在让我们运行我们 start 命令来测试它。

此时不应该有任何错误,我们应该在控制台中看到以下内容:

Listening on port 3000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/217309.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

filter过滤器

package com.it.filter;import javax.servlet.*; import javax.servlet.annotation.WebFilter;import java.io.IOException;WebFilter(urlPatterns"/*") public class DemoFilter implements Filter {Override // 初始化的方法 只要调用一次public void init(Filte…

【React 开发】增强你的React 技能:2024年要掌握的4种高级模式

React由于其简单和灵活,近年来已成为最受欢迎的前端库之一。然而,当应用程序的复杂性扩展时,管理状态、处理异步输入和维护可扩展的体系结构可能会变得困难。我们将在本文中介绍四种高级React模式,它们将帮助您克服这些困难以及如…

(C语言)判定一个字符串是否是另一个字符串的子串,若是则返回子串在主串中的位置。

要求: (1)在主函数中输入两个字符串,调用子函数cmpsubstr()判断,并在主函数输出结果。 (2)子函数的返回值为-1表示未找到,否则返回子串的位置(起始下标)。 …

人工智能-A*算法-八数码问题

一,A*算法设计思想 A*算法(A-star)是一种寻路算法,主要用于游戏、机器人等领域。 它的设计思想是将最短路径搜索问题转化为一个优化问题,通过计算每个节点的评分(f(n) g(n) h(n))来寻找最优…

YOLOv8-Seg改进:简单高效的模块-现代反向残差移动模块 (iRMB) | | ICCV2023 EMO

🚀🚀🚀本文改进:设计了一种面向移动端应用的简单而高效的现代反向残差移动模块 (Inverted Residual Mobile Block, iRMB),它吸收了类似 CNN 的效率来模拟短距离依赖和类似 Transformer 的动态建模能力来学习长距离交互,引入YOLOV8 🚀🚀🚀YOLOv8-seg创新专栏:h…

【华为OD题库-064】最小传输时延I-java

题目 某通信网络中有N个网络结点,用1到N进行标识。网络通过一个有向无环图.表示,其中图的边的值表示结点之间的消息传递时延。 现给定相连节点之间的时延列表times[]{u,v, w),其中u表示源结点,v表示目的结点&#xff0…

小程序长按识别二维码

小程序开发中要实现长按识别二维码的功能很简单,只需要在image标签里添加如下属性即可: 小程序版本: show-menu-by-longpress"{{true}}" uniapp版本: :show-menu-by-longpress"true" 举例: …

金融银行业更适合申请哪种SSL证书?

在当今数字化时代,金融行业的重要性日益增加。越来越多的金融交易和敏感信息在线进行,金融银行机构必须采取必要的措施来保护客户数据的安全。SSL证书作为一种重要的安全技术工具,可以帮助金融银行机构加密数据传输,验证网站身份&…

网页文章采集工具-人工智能AI功能

简数采集器是一款支持人工智能AI功能的网页文章采集工具,它可以调用百度的文心一言AI对采集的数据进行分析,处理,内容创作等等,根据你的需求进行更加灵活的数据采集和处理。 文心一言人工智能AI功能使用方法: 1. 填写…

什么是Overlay网络?Overlay网络与Underlay网络有什么区别?

你们好,我的网工朋友。 在传统历史阶段,数据中心的网络是以三层架构(核心、汇聚、接入)为基本标准。 但是随着技术的发展,不同的厂家有不同的组建方式,比如说在核心层、汇聚层和接入层增加虚拟化技术。 …

MySQL笔记-第05章_排序与分页

视频链接:【MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板】 文章目录 第05章_排序与分页1. 排序数据1.1 排序规则1.2 单列排序1.3 多列排序 2. 分页2.1 背景2.2 实现规则2.3 拓展 第05章_排序与分页 讲师&#…

Allegro无法模块复用的解决办法

Allegro无法模块复用的解决办法 在用Allegro做PCB设计的时候,模块复用是使用的比较频繁的功能,对于有相同模块的单板,可以节省大量的时间。 模块复用的功能不细说,具体参考以前的文章。 有时会遇到模块复用的时候出现如下报错 无法匹配,有时如果因为Device而无法复用,就…

学习pytorch16 现有网络模型的使用和修改

现有网络模型的使用和修改 官网 [https://pytorch.org/](https://pytorch.org/)torchvison 相关model1. 图像常用vgg16模型 【vgg19也常用】2. ImageNet数据集太大 无法代码下载 kaggle网址下载3. 代码4. 执行结果 官网 https://pytorch.org/ torchvison 相关model 1. 图像常用…

Android wifi 框架以及Enable流程

Android P相比于Android O的变化 多了WifiStateMachinePrime(状态机的前处理机制),wifiService的相关cmd 不再是直接send 给WifiStateMachine,而是被送到WifiStateMachinePrime先进行处理后,再送往WifiStateMachine也…

Linux Namespace技术

对应到容器技术,为了隔离不同类型的资源,Linux 内核里面实现了以下几种不同类型的 namespace。 UTS,对应的宏为 CLONE_NEWUTS,表示不同的 namespace 可以配置不同的 hostname。User,对应的宏为 CLONE_NEWUSER&#xf…

Redis Hash数据类型

Redis Hash数据类型 几乎所有的主流编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中,哈希类型是指值本身又是一个键值对结构,形如key “key”,value {ffield1, value1 }, … {fieldN…

HTTP 缓存机制

一、强制缓存 只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存而无需再请求服务器。 强制缓存是利用下面这两个 HTTP 响应头部(Response Header)字段实现的,它们都用来表示资源在客户端缓存的有效期: Cache…

对抗神经网络 CGAN实战详解 完整数据代码可直接运行

代码视频讲解: 中文核心项目:对抗神经网络 CGAN实战详解 完整代码数据可直接运行_哔哩哔哩_bilibili 运行图: 完整代码: from keras.layers import Input, Dense, Reshape, Flatten, Dropout, multiply from keras.layers import BatchNormalization, Activation, Embedd…

单片机系统

我们来看单片机 的例子,读者可能会担心单片机(又称MCU,或微控制器) 过于专业而无法理解。完全没必要!在这里我们仅借它谈论一下有关时间的话题,顺带提一下单片机系统的概念。 单片机顾名思义是集成到一个芯…

Java开发中一些重要软件安装配置

Java技术栈中重要过程 1、JavaWeb1、开发工具VsCode的安装和使用2、Tomcat服务器3、nodejs的简介和安装4、Vite创建Vue3工程化项目ViteVue3项目的创建、启动、停止ViteVue3项目的目录结构 5、Maven安装和配置 1、JavaWeb 1、开发工具VsCode的安装和使用 1 安装过程 安装过程比…