当前位置: 首页 > news >正文

一个电信ip做网站卡不卡成都装修公司前十强

一个电信ip做网站卡不卡,成都装修公司前十强,山东泰安天气预报15天,洪泽网站建设Express是nodejs开发中普遍使用的一个框架#xff0c;下面要谈的是如何结合Typescript去使用。 目标 我们的目标是能够使用Typescript快速开发我们的应用程序#xff0c;而最终我们的应用程序却是编译为原始的JavaScript代码#xff0c;以由nodejs运行时来执行。 初始化设置… Express是nodejs开发中普遍使用的一个框架下面要谈的是如何结合Typescript去使用。 目标 我们的目标是能够使用Typescript快速开发我们的应用程序而最终我们的应用程序却是编译为原始的JavaScript代码以由nodejs运行时来执行。 初始化设置 首要的是我们要创建一个目录名为express-typescript-app来存放我们的项目代码 mkdir express-typescript-app cd express-typescript-app为了实现我们的目标首先我们需要区分哪些是线上程序依赖项哪些是开发依赖项这样可以确保最终编译的代码都是有用的。 在这个教程中将使用yarn命令作为程序包管理器当然npm也是一样可以的。 生产环境依赖 express作为程序的主体框架在生产环境中是必不可少的需要安装 yarn add express这样当前目录下就生成了一个package.json 文件里面暂时只有一个依赖 开发环境依赖项 在开发环境中我们将要使用Typescript编写代码。所以我们需要安装typescript。另外也需要安装node和express的类型声明。安装的时候带上- D参数来确保它是开发依赖。 yarn add -D typescript types/express types/node安装好之后还有一点值得注意我们并不想每次代码更改之后还需要手动去执行编译才生效。这样体验太不好了所以我们需要额外添加几个依赖 ts-node: 这个安装包是为了不用编译直接运行typescript代码这个对本地开发太有必要了 nodemon这个安装包在程序代码变更之后自动监听然后重启开发服务。搭配ts-node模块就可以做到编写代码及时生效。 因此这两个依赖都是在开发的时候需要的而不需编译进生产环境的。 yarn add -D ts-node nodemon配置我们的程序运行起来 配置Typescript文件 为我们将要用的typescript设置配置文件创建tsconfig.json文件 touch tsconfig.json现在让我们给配置文件添加编译相关的配置参数 module: commonjs — 如果使用过node的都知道这个作为编译代码时将被编译到最终代码是必不可少的。 esModuleInterop: true — 这个选项允许我们默认导出的时候使用*代替导出的内容。 target: es6 — 不同于前端代码我们需要控制运行环境得确保使用的node版本能正确识别ES6语法。 rootDir: ./ — 设置代码的根目录为当前目录。 outDir: ./build — 最终将Typescript代码编译成执行的Javascript代码目录。 strict: true — 允许严格类型检查。 最终tsconfig.json文件内容如下 {compilerOptions: {module: commonjs,esModuleInterop: true,target: es6,rootDir: ./,outDir: ./build,strict: true} }配置package.json脚本 目前还没有 package.json文件的scripts项我们需要添加几个脚本第一个是start启动开发模式另一个是 build打包线上环境代码的命令。 启动开发模式我们需要执行nodemon index.ts而打包生产代码我们已经在tsconfig.json中给出了所有需要的信息所以我们只需要执行tsc命令。 此刻下面是你package.json文件中所有的内容也可能由于我们创建项目的时间不一样导致依赖的版本号不一样。 {dependencies: {express: ^4.17.1},devDependencies: {types/express: ^4.17.11,types/node: ^14.14.22,nodemon: ^2.0.7,ts-node: ^9.1.1,typescript: ^4.1.3} }Git配置 如果使用git来管理代码还需要添加.gitignore文件来忽视node_modules目录和build目录 touch .gitignore添加忽视的内容 node_modules build至此所有的安装过程已经结束比单纯的无Typescript版本可能稍微复杂点。 创建我们的Express应用 让我们来正式开始创建express应用。首先创建主文件index.ts touch index.ts然后添加案例代码在网页中输出“hello world” import express from express;const app  express(); const PORT  3000;app.get(/, (req, res)  {res.send(Hello world); });app.listen(PORT, ()  {console.log(Express with Typescript! http://localhost:${PORT}); });在终端命令行执行启动命令 yarn run start yarn run start接下来会输出以下内容 [nodemon] 2.0.7 [nodemon] to restart at any time, enter rs [nodemon] watching path(s): *.* [nodemon] watching extensions: ts,json [nodemon] starting ts-node index.ts Express with Typescript! http://localhost:3000我们可以看到nodemon模块已经监听到所有文件的变更后使用ts-node index.ts命令启动了我们的应用。我们现在可以在浏览器打开网址http://localhost:3000将会看到网页中输出我们想要的“hello world”。 “Hello World”以外的功能 我们的 “Hello World”应用算是创建好了但是我们不仅于此还要添加一些稍微复杂点的功能来丰富一下应用。大致功能包括 保存一系列的用户名和与之匹配的密码在内存中 允许提交一个POST请求去创建一个新的用户 允许提交一个POST请求让用户登录并且接受因为错误认证返回的信息 让我们一个个去实现以上功能 保存用户 首先我们创建一个types.ts文件来定义我们用到的User类型。后面所有类型定义都写在这个文件中。 touch types.ts然后导出定义的User类型 export type User  { username: string; password: string };好了。我们将使用内存来保存所有的用户而不是数据库或者其它方式。根目录下创建一个data目录然后在里面新建users.ts文件 mkdir data touch data/users.ts现在在users.ts文件里创建一个User类型的空数组 import { User } from ../types;const users: User[]  [];提交新用户 接下来我们希望向应用提交一个新用户。我们在这里将要用到处理请求参数的中间件body-parse yarn add body-parser然后在主文件里导入并使用它 import express from express; import bodyParser from body-parser;const app  express(); const PORT  3000;app.use(bodyParser.urlencoded({ extended: false }));app.get(/, (req, res)  {res.send(Hello world); });app.listen(PORT, ()  {console.log(Express with Typescript! http://localhost:${PORT}); });最后我们可以在users文件里创建POST请求处理程序。 该处理程序将执行以下操作 校验请求体中是否包含了用户名和密码并且进行有效性验证 一旦提交的用户名密码不正确返回状态码为400的错误信息 添加一个新用户到users数组中 返回一个201状态的错误信息 让我们开始首先在data/users.ts文件中创建一个addUser的方法 import { User } from ../types;const users: User[]  [];const addUser  (newUser: User)  {users.push(newUser); };然后回到index.ts文件中添加一条/users的路由 import express from express; import bodyParser from body-parser; import { addUser } from ./data/users;const app  express(); const PORT  3000;app.use(bodyParser.urlencoded({ extended: false }));app.get(/, (req, res)  {res.send(Hello world); });app.post(/users, (req, res)  {const { username, password }  req.body;if (!username?.trim() || !password?.trim()) {return res.status(400).send(Bad username or password);}addUser({ username, password });res.status(201).send(User created); });app.listen(PORT, ()  {console.log(Express with Typescript! http://localhost:${PORT}); });这里的逻辑不复杂我们简单解释一下首先请求体中要包含username和password两个变量而且使用trim()函数去除收尾的空字符保证它的长度大于0。如果不满足返回400状态和自定义错误信息。如果验证通过则将用户信息添加到users数组并且返回201状态回来。 注意你有没有发现users数组是没有办法知道有没有同一个用户被添加两次的我们暂且不考虑这种情况。 让我们重新打开一个终端不要关掉运行程序的终端在终端里通过curl命令来发出一个POST请求注册接口 curl -d usernamefoopasswordbar -X POST http://localhost:3000/users你将会在终端的命令行中发现输出了下面的信息 User created然后再请求一次接口这次password仅仅为空字符串测试一下请求失败的情况 curl -d usernamefoopassword  -X POST http://localhost:3000/users没有让我们失望成功返回了一下错误信息 Bad username or password登录功能 登录有点类似我们从请求体中拿到username和password的值然后通过Array.find方法去users数组中查找相同的用户名和密码组合返回200状态码说明用户登录成功而401状态码表示用户不被授权登录失败。 首先我们在data/users.ts文件中添加getUser方法 import { User } from ../types;const users: User[]  [];export const addUser  (newUser: User)  {users.push(newUser); };export const getUser  (user: User)  {return users.find((u)  u.username  user.username  u.password  user.password); };这里getUser方法将会从users数组里返回与之匹配用户或者undefined。 接下来我们将在index.ts里调用getUser方法 import express from express; import bodyParser from body-parser; import { addUser, getUser } from ./data/users;const app  express(); const PORT  3000;app.use(bodyParser.urlencoded({ extended: false }));app.get(/, (req, res)  {res.send(Hello word); });app.post(/users, (req, res)  {const { username, password }  req.body;if (!username?.trim() || !password?.trim()) {return res.status(400).send(Bad username or password);}addUser({ username, password });res.status(201).send(User created); });app.post(/login, (req, res)  {const { username, password }  req.body;const found  getUser({username, password})if (!found) {return res.status(401).send(Login failed);}res.status(200).send(Success); });app.listen(PORT, ()  {console.log(Express with Typescript! http://localhost:${PORT}); });现在我们还是用curl命令去请求注册接口和登录接口登录接口请求两次一次成功一次失败 curl -d usernamejoepasswordhard2guess -X POST http://localhost:3000/users # User createdcurl -d usernamejoepasswordhard2guess -X POST http://localhost:3000/login # Successcurl -d usernamejoepasswordwrong -X POST http://localhost:3000/login # Login failed没问题结果都按我们预想的顺利返回了 探索Express类型 您可能已经发现讲到现在好像都是一些基础的东西Express里面比较深的概念没有涉及到比如自定义路由中间件和句柄等功能我们现在就来重构它。 自定义路由类型 或许我们希望的是创建这样一个标准的路由结构像下面这样 const route  {method: post,path: /users,middleware: [middleware1, middleware2],handler: userSignup, };我们需要在types.ts文件中定义一个Route类型。同时也需要从Express库中导出相关的类型RequestResponse和NextFunction。Request表示客户端的请求数据类型Response是从服务器返回值类型NextFunction则是next()方法的签名如果使用过express的中间件应该很熟悉。 在types.ts文件中重新定义Route类型 export type User  { username: string; password: string };type Method | get| head| post| put| delete| connect| options| trace| patch;export type Route  {method: Method;path: string;middleware: any[];handler: any; };如果你熟悉express中间件的话你应该知道一个典型的中间件长这样 function middleware(request, response, next) {// Do some logic with the requestif (request.body.something  foo) {// Failed criteria, send forbidden resposnereturn response.status(403).send(Forbidden);}// Succeeded, go to the next middlewarenext(); }由此可知一个中间件需要传入三个参数分别是RequestResponse和NextFunction类型。因此如果需要我们创建一个Middleware类型 import { Request, Response, NextFunction } from express;type Middleware  (req: Request, res: Response, next: NextFunction)  any;然后express已经有了一个叫RequestHandler类型所以在这里我们只需要从express导出就好了如果取个别名可以采用类型断言。 import { RequestHandler as Middleware } from express;export type User  { username: string; password: string };type Method | get| head| post| put| delete| connect| options| trace| patch;export type Route  {method: Method;path: string;middleware: Middleware[];handler: any; };最后我们只需要为handler指定类型。这里的handler应该是程序执行的最后一步因此我们在设计的时候就不需要传入next参数了类型也就是RequestHandler去掉第三个参数。 import { Request, Response, RequestHandler as Middleware } from express;export type User  { username: string; password: string };type Method | get| head| post| put| delete| connect| options| trace| patch;export type Handler  (req: Request, res: Response)  any;export type Route  {method: Method;path: string;middleware: Middleware[];handler: Handler; };添加一些项目结构 我们需要通过增加一些结构来把中间件和处理程序从index.ts文件中移除 创建处理器 我们把一些处理方法移到handlers目录中 mkdir handlers touch handlers/user.ts那么在handlers/user.ts文件中我们添加如下代码。和用户注册相关的处理代码已经被我们从index.ts文件中重构到这里。重要的是我们可以确定signup方法满足我们定义的Handlers类型 import { addUser } from ../data/users; import { Handler } from ../types;export const signup: Handler  (req, res)  {const { username, password }  req.body;if (!username?.trim() || !password?.trim()) {return res.status(400).send(Bad username or password);}addUser({ username, password });res.status(201).send(User created); };同样我们把创建auth处理器添加login方法 touch handlers/auth.ts添加以下代码 import { getUser } from ../data/users; import { Handler } from ../types;export const login: Handler  (req, res)  {const { username, password }  req.body;const found  getUser({ username, password });if (!found) {return res.status(401).send(Login failed);}res.status(200).send(Success); };最后也给我们的首页增加一个处理器 touch handlers/home.ts功能很简单只要输出文本 import { Handler } from ../types;export const home: Handler  (req, res)  {res.send(Hello world); };中间件 现在还没有任何的自定义中间件首先创建一个middleware目录 mkdir middleware我们将添加一个打印客户端请求路径的中间件取名requestLogger.ts touch middleware/requestLogger.ts从express库中导出需要定义的中间件类型的RequestHandler类型 import { RequestHandler as Middleware } from express;export const requestLogger: Middleware  (req, res, next)  {console.log(req.path);next(); };创建路由 既然我们已经定义了一个新的Route类型和自己的一些处理器就可以把路由定义独立出来一个文件在根目录创建routes.ts touch routes.ts以下是该文件的所有代码为了演示就只给/login添加了requestLogger中间件 import { login } from ./handlers/auth; import { home } from ./handlers/home; import { signup } from ./handlers/user; import { requestLogger } from ./middleware/requestLogger; import { Route } from ./types;export const routes: Route[]  [{method: get,path: /,middleware: [],handler: home,},{method: post,path: /users,middleware: [],handler: signup,},{method: post,path: /login,middleware: [requestLogger],handler: login,}, ];重构index.ts文件 最后也是最重要的一步就是简化index.ts文件。我们通过一个forEach循环routes文件中声明的路由信息来代替所有的route相关的代码。这样做最大的好处是为所有的路由定义了类型。 import express from express; import bodyParser from body-parser; import { routes } from ./routes;const app  express(); const PORT  3000;app.use(bodyParser.urlencoded({ extended: false }));routes.forEach((route)  {const { method, path, middleware, handler }  route;app[method](path, ...middleware, handler); });app.listen(PORT, ()  {console.log(Express with Typescript! http://localhost:${PORT}); });这样看起来代码结构清晰多了架构的好处就是如此。另外有了Typescript强类型的支持保证了程序的稳定性。 完整代码 Github:https://github.com/fantingsheng/express-typescript-app
http://www.pierceye.com/news/59601/

相关文章:

  • 模板网站建设的弊端免费企业建站系统排名
  • 城乡建设部注册建筑师网站投资理财产品网站建设
  • 网站首页一般做多大网站建设有哪些需要注意的关键细节
  • 网站域名ip查询seo推广优化排名软件
  • 贵阳网站建设推广清除网站黑链
  • 网站源码分享平台一级造价工程师报名时间2023年
  • 宜昌市建设监理协会网站网站开发字体
  • 长沙企业网站建设较好的公司龙岗永湖网站建设
  • 做网站公司能赚钱吗策划公司名称
  • 网站优化一年多少钱seo软件推广哪个好
  • 建设银行的财务网站科协网站页建设的意义
  • 网站做流量推广的方式微信小程序管理平台入口
  • 宽屏绿色新闻资讯网站织梦模板郑州做网站排名
  • 邢台哪儿专业做网站网站运营情况怎么写
  • 装修公司网站源代码什么是软文营销
  • 南通优化网站费用xp优化大师
  • 北京规划建设 杂志 官方网站一流的高密网站建设
  • 吉林省住房城乡建设网站的品质网站建设
  • 做图的兼职网站网站的管理和维护
  • 南开集团网站建设最新体育新闻足球
  • 定制类网站专业网页制作服务商
  • 手机网站公司哪家好西安关键词网站排名
  • 直播类网站怎么做阳光创信-网站建设首选品牌
  • 行业门户网站推广做某个网站接口违法
  • 如何更改 网站 关键词防止访问网站文件夹
  • 建设网站分几个步骤wordpress多大
  • 新浪网站首页获取网站访客qq号码源码
  • 互联网工具型网站重庆沙坪坝有哪些大学
  • 建设部网站监理变更怎么建立网上销售平台
  • 宝华路桥建设集团网站湖南seo网站多少钱