亚洲女同成aV人片在线观看|亚洲www啪成人一区二区麻豆|亚洲国产中日韩精品综合|亚洲国产成人精品一级片|亚洲无码在线视频免费

搭建node服務(wù)(三):使用TypeScript
發(fā)布時(shí)間:2026-05-04 19:50:49

# 搭建(jian)node服務(wù)(三):?使用TypeScript> JavaScript 是搭建一門(mén)動(dòng)態(tài)弱類(lèi)型語(yǔ)言,對變量的服務(wù)類(lèi)型非常寬容。??JavaScript使用靈活,使用開(kāi)發(fā)速度快,搭建但是服務(wù)由于類(lèi)型思維的缺失,一點(diǎn)小的使用修改都有(you)可能導致意想不到的錯誤,使用TypeScript可以很好的搭建解決這種問(wèn)題。TypeScript是服務(wù)JavaScript的一個(gè)超集,擴展了 JavaScript 的使用語(yǔ)法,增加了靜態(tài)類(lèi)型、搭建類(lèi)、服務(wù)模塊、??使用接口和類(lèi)型注解等功能,搭建可以編譯成純JavaScript。服務(wù)本文將介紹如何在node服務(wù)中使用TypeScrヽ(′▽?zhuān)?ノipt。使用 

一(╯°□°)╯、安裝依賴(lài)```npm install typescript --savenpm install ts-node?? --savenpm install nodemon --save```或者```yarn add typescriptyarn add ts-nodeyarn ad??d nodemon```另外,還需要安裝依賴(lài)模塊的類(lèi)型庫:```npm install @types/koa --savenpm install @types/koa-router --save…```或者```yarn add @types/( ?▽?)koayarn add @types/koa-router…``` 

 二、tsconfig.json當使用tsc命令進(jìn)行編譯時(shí),如果未指定ts文件,編譯器會(huì )從當前目錄開(kāi)始去查找tsconfig.json文件,并根據tsconfig.json的配置進(jìn)行編譯。 

 1.指定文件可以通(tong)過(guò)files屬性來(lái)指定需要編譯(′_`)的文件,如下所示:```{ "files(╯‵□′)╯": [ "src/server.ts" ]}```另外也可以通過(guò)使用"include"和"exclude"屬性來(lái)指定,采用類(lèi)似glob文件匹配模式??,如下所示:```{ "include": [ "src/**/*" ], "exclude": [ "node_modules", "**/*.spec.ts" ]}`(′▽?zhuān)?``支持的通配符:

 1. * 匹配0或多個(gè)字符(不包括目錄分隔符) 

2. ? 匹配??一個(gè)任意字符(不包括目錄分隔符) 

3. **/ 遞歸匹配任意子目錄 

 2.常用配置compilerOptions 屬性用于ヾ(′▽?zhuān)??配置編譯選項,與tsc命令的選項一致??,常用的配置如下所示:```{ "compilerOptions": { // 指定編譯為ECMAScript的哪個(gè)版本。默認為"ES3" "target": "ES6", // 編譯為哪種模塊系統。如果ta(⊙_⊙)rget為"ES3"或者"ES5",??默認為"CommonJS",否則默認為"ES6" "module": "CommonJS", // 模塊解析策略,"Classic" 或者 "Node"。如果module為"AMD"、"Syst??em"或者"ES6",默認為"Classic",否則默認為"Nod(′▽?zhuān)?e" "moduleR??esolu??tion": "Node", // 是否支持使用import cjs from 'cjs'的方式引入commonjs包 "esModuleI??nterop": true, // 編譯過(guò)程中需要引入的庫。target為"ES5"時(shí),默認引入["DOM","ES5","ScriptHost"];target為"ES6"時(shí),默認引入["DOM","ES6","DOM.Iterable","ScriptHost"] "lib": ["ES6"], // 編譯??生??成的js文件所輸出的根目錄,默認輸出到ts文件所在的目錄 "outDir": "dist", // 生成相應的.map文(wen)件 "sourceMap": true }, "include": [ "src/**/*" ],(′?_?`) "exclude": [ "node_modules", "**/*.spec.ts" ]}``` 

 1)targettarget是編譯目標,可以指定編譯為ECMAScript的哪個(gè)版本ヽ(′ー`)ノ,默認為"(??ヮ?)?*:???ES3"。ECMAScript的版本有:"E??S3" 、"ES5"、 "ES6" 或者 "ES2015"、 "E(′▽?zhuān)?)S201??6"、(′?`) "ES2017"、"ES2018"、"ES2019"、 "ES2020"、"ESNext"。 

2)modulemodule指定編譯為哪種模塊系統,如果target為"ES3"或者"ES5",默認為"CommonJS",否則默認為"ES6"??蛇x用的模塊系統有:"None"、 "CommonJS"、 "AMD",、"System"、 "UMD"、"ES6"或者"ES2015"、"ESNext"。

3)moduleResoluti???o┐(′д`)┌nmoduleResolution指定模塊解析策略,模塊解析策略有:"Classic"、"Node",如果module為"AMD"、"System"或者"ES6",默認為"Cl??assic",否則默認為"Node"。 

示例1:在/root/src/modu?leA.t??s中以import { b } from "./moduleB" 方式相對引用一個(gè)模塊(⊙_⊙)。Classic解析策略,查找過(guò)程:```/root/src/moduleB.ts/r??oot/src/moduleB.d.ts```Node解析策略,查找過(guò)程:```/root/src??/moduleB.ts/root/src/moduleB.tsx/root/src/moduleB.d.( ???)ts/root/src/moduleB/package.json (如果指定了"??types"屬性)/root/src/moduleB(′?ω?`)/index.ts/root/src/moduleB/index.tsx/root/src/mod??uleB/index.d.ts``` 

 示例2:在/root(?????)/src/moduleA.ts中以import { b } from "moduleB" 方式非相對引用一個(gè)模塊。Classic解析策略,查找過(guò)程:```/root/src/moduleB.ts/??root/src/modu??leB.d.ts/root/moduleB.ts/root/moduleB.d.ts/module(′;д;`)B.ts/moduleB.d.ts```Node解析策略,查找過(guò)程:```/root/src/no(╬?益?)de_modules/moduleB.ts/root/src/node_modules/moduleB.tsx/root/src/node_modules/moduleB.d.ts/root/src/node_modules/moduleB/package.json (如果指定了"types"屬性)/root/src/node_mod??ules/mod(′?`*)uleB/index.ts/root/??src/node_modules/moduleB/index.tsx/root/src/node_modules/moduleB/ind??ex.d.ts/root/n??ode_modules/modul??eB.ts/root/node_modules/moduleB.tsx/root/node_modules/moduleB.d.ts/root/node_modules/moduleB/package.json (如果指定了"types"屬性)/root/node_modules/moduleB/index.ts/root/node_modu??le??s/moduleB/index.tsx/root/node_(′?`*)modules/moduleB/inde??x.d.ts/node_modules/moduleB.ts/node_modules/moduleB.tsx/node_modules/moduleB.d.ts??/??node_modules/moduleB/package.json (如果指定了"types"屬性(′ω`))/node_modules/moduleB/index.ts/node_modules/moduleB/index.tsx??/no??de_modules/moduleB/(′?_?`)index.d.ts``` 

4)esModuleIn??terope( ?ω?)sModuleInterop為true時(shí),表示支持使用im(′▽?zhuān)?port d from 'cjs'的(O_O)方式引入commonjs包。當commonjs模塊(′▽?zhuān)?)轉化為esm時(shí),會(huì )增加 __importStar 和 __importDefault 方法來(lái)處理轉化問(wèn)題。 

示例:cjs為commonjs模塊,代碼如下:```modul??e??.exports = { name: 'cjs' };```另外一個(gè)模塊以esm方式引用了cjs模塊,代碼如下:```import cjsDefault from 'cjs';import * as cjsStar from 'cjs';console.log('cjsDefault =', cjsDefault);console.lo??g('cjsStar =', cjsStar);```輸出結果為:```cjsDefault = { name: 'cjs' }cjsStar = { name: 'c(′?`)js', default: { name: 'cjs' } }```編譯后生成的代碼如下:```var __importDヾ(′?`)?efault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "defau(′_ゝ`)lt": mo??d };};var __importStar = (this && this.__importStar) || function (mod) { if (mod &am( ?ω?)p;??& mod.__esModule) return mod; var result = { }; if (mod != null) for (var k in mod) if (Object.hasOw(′?_?`)nProperty.call(mod,(?_?;) k)) result = mod; result["default"](T_T) = mod; retu??rn result;};Object.defineProperty(exports, "__esModule", { value: true });const cjs_1 = __importDefault(require(′?`)("cjs")??);const(′?`*) cjsStar = __importS??tar(require("cjs"));console.log('cjsDefault =', cjs_1.default);console.log('cjsStar =', cjsStar);``` 

 5)liblib指定編譯過(guò)程中需要引入的庫。target為"ES5"時(shí),默認引入["DOM","ES5","ScriptHost"??];??target為"ES6"時(shí),默認引入["DOM","ES6","DOM.Iterable","ScriptHost"]。由于本示例TypeScript是用于服務(wù)端的,不需要使用DOM和ScriptHost,所以lヽ(′▽?zhuān)?ノib設為["ES6"]??。 

6)outDir輸出目錄,編譯生成的js文件??所輸出的根(′ω`)目錄,默認輸出到ts文件所在的目錄。 

 7)sourceMap是否生成source map文件,通過(guò)使用source map 可以在錯誤信息中可以???顯示源碼位置。要想根據source map 顯示錯誤信息源碼位置,還需要在入口(′_`)文件引入source-map-support 模塊,如下:```import 'source-map-support/register';```&nb(???)sp;

 三、 腳本命令入口文件為src/server.ts,package.json中的scripts配置如下:- package(′▽?zhuān)?).json```{ "scrip(⊙_⊙)ts": { "dev": "nodemon --watch src -e ts,ts(′▽?zhuān)?)x --exec ts-node src/server.ts", "build": "tsc", "start": "node dist/server.js" }, …}``` 

1.執行 npm run dev 命令可以啟動(dòng)開(kāi)發(fā)環(huán)境,當src下的文件被修改后會(huì )自動(dòng)重新啟動(dòng)服務(wù)。

 2.執行 npm run build 命令會(huì )進(jìn)行編譯,由于tsconfig.json中 outDir 指定輸出目錄為dist,編譯后的js文件將出輸出到dist目錄。 

3.執行 np(╯°□°)╯︵ ┻━┻m run start 命令可以啟動(dòng)應用,啟動(dòng)前需要執行 npm run build 進(jìn)行編譯。 

四、自定義類(lèi)型TypeScript 會(huì )自動(dòng)(′?`)從 node_modules/@types 目錄獲取模塊的類(lèi)型定義,引用的模塊都需要安裝對應類(lèi)型庫,如:```npm install @types/koa --save```安裝后,會(huì )在node_modules/@types 目錄下找到koa 文件夾,該文件夾下有koa相關(guān)的類(lèi)型定義文件。當引用koa??模塊時(shí)會(huì )自動(dòng)引入node_modules/?? 和 node_modules/@types下的 koa 包。如( ???)果某個(gè)模塊沒(méi)有類(lèi)型庫或者對某個(gè)模塊??進(jìn)行了擴展需要修改類(lèi)型定義,這時(shí)需要引入自定義的??類(lèi)型。

 示例:給koa增加bodyparser中間件 

1.設置typeR??oots- tsconfig.jsヽ(′ー`)ノon```{ "compilerOptions": { … // 類(lèi)型(′?ω?`)聲明文件所在目錄 "ty??peRoots": ["./node_modules/@types"??, "./src/types"],},"include": [ "src/**/*" ], "exclude": [ "node_modules", "**/*.??spec.ts" ]}```src/types是存放自定義類(lèi)型的目錄,本示例??中src/types目錄已被include包含,如果(guo)自定義的類(lèi)型目(′?ω?`)錄未被include包含還需要在include中添加該目錄。

 2.編寫(xiě)類(lèi)型定義文件- src/types/koa/in??dex.d.ts```i??mport * as Koa from "koa";d??eclare module "koa" { interface Request { body?: ob(╯°□°)╯ject; rawBody: string; }}```這里給(gei)koa的request對象增加body和r??awBody兩個(gè)屬性,分別用于存放請求體的jsˉ\_(ツ)_/ˉon對象和原始字??符串。 

3.編寫(xiě) jsonBodyParser 插件- src/middleware/jsonBodyParser.ts```import Koa from "koa";function getRawBody(ctx: Koa.Context): Promise { return new Promise((resolve, reject) => { try { let pos(′?_?`)tData: string = ''; ctx.req.addListener('data', (data)(′?_?`) => { postData += data; }); ctx.req.on('end', () => { resolve(postData); }); } catch (e) { console.error('獲取body內容失敗', e); reject(??e); } })}export default function jsonB( ?▽?)odyParser (): Koa.Middleware { return async(ctx: Koa.Context, next: Koa.Next) => { const rawBody: string?? = await getRawBody(ctx); const request: Koa.Request = ctx.request; request.rawBody = rawBody; if (rawBody) { try { request.body = JSON.parse(rawBody); } catch (e) { request.body = { }; } } await ne???xt(); };}```jsonBody(??-)?Parser()會(huì )返回一個(gè)koa中間件,這個(gè)中間件將獲取請求體的內容,將原始內容字符串賦值到ctx.request.rawBody,將請求體內容json(??-)?對象賦值到ctx.request.body。由于src/types/koa/index.d.ts自定義類(lèi)型已經(jīng)擴展了Koa.Request的這兩個(gè)屬性,執行npm run build命令,使用 tsc 進(jìn)行編譯,可以編譯成功。但是(shi)當執行 npm run dev 時(shí),會(huì )提示編譯錯誤,那是因為ts-node默認不會(huì )根據配置中的files、include 和 exclude 加載所有ts文件,而是從入口文件開(kāi)始根據引用和依賴(lài)加載文件。最簡(jiǎn)單的解決辦法就是在 ts-node 命令后增加(′?_?`) --files 參數,表示按配置的files、ヾ(′▽?zhuān)??include 和 exclude加載(′ω`*)ts文件,如下:- package.json```{ "scripts": { "dev": " nodemon --watch src -e ts,tsx --exec ts-node --files src/server.ts", }}``` 

五、說(shuō)明本文介紹了如何在node服務(wù)中使用TypeScript,具體的TypeScrip??t語(yǔ)法規則網(wǎng)上有很多相關(guān)的資料,這里就不再介紹了。本文相關(guān)的代碼已提交到GitHub以供參考,項目地址:[https://github.com/liu??linsp/node-server-typescript-demo]。 

亚洲女同成aV人片在线观看|亚洲www啪成人一区二区麻豆|亚洲国产中日韩精品综合|亚洲国产成人精品一级片|亚洲无码在线视频免费 顺昌县| 额尔古纳市| 深水埗区| 会宁县| 千阳县| 威海市| 松桃| 福清市| 太白县| 颍上县| 贞丰县| 虹口区| 图木舒克市| 怀集县| 木里| 襄汾县| 永修县| 永平县| 邯郸县| 通州市| 茶陵县| 嫩江县| 洛阳市| 竹山县| 宁远县| 宾阳县| 益阳市| 南岸区| 台山市| 沂源县| 福安市| 苏尼特左旗| 乌兰浩特市| 闻喜县| 大港区| 德江县| 三明市| 普洱| 常宁市| 元氏县| 大冶市| http://444 http://444 http://444 http://444 http://444 http://444