TypeScript node 프로젝트 에서 의 실천
10750 단어 자바 scripttypescriptsequelizekoa.js
TS 를 선택 한 이유
거 경 회사 에서 생산 한 정태 적 이 고 강 한 유형의 컴 파일 형 언어 로 서 이 언어 는 몇 년 동안 등장 되 었 고 지역사회 의 유지 아래 안정 적 인 언어 라 고 믿 습 니 다.우 리 는 자바 스 크 립 트 는 동적 약 유형 해석 형 스 크 립 트 언어 로 동태 적 으로 많은 편 의 를 가 져 왔 다 는 것 을 알 고 있 습 니 다. 우 리 는 코드 실행 에서 변수 유형 을 임의로 수정 하여 기대 하 는 목적 을 달성 할 수 있 습 니 다.그러나 이것 은 양날 의 검 입 니 다. 거대 한 프로젝트 가 당신 앞 에 나타 나 면 매우 복잡 한 논리 에 직면 하여 코드 를 통 해 특정한 변수 가 어떤 유형 인지 알 기 어렵 습 니 다. 이 변 수 는 무엇 을 해 야 하 는 지 자칫 구 덩이 를 밟 을 수 있 습 니 다.
한편, 정적 강 유형 컴 파일 은 많은 장점 을 가 져 올 수 있다. 그 중에서 가장 중요 한 것 은 개발 자 들 이 부주의 한 문 제 를 근절 하 는 데 도움 을 줄 수 있다 는 것 이다. 그림 은 rollbar 가 통계 한 수천 개 프로젝트 중 수량 이 가장 많은 10 개 이상 이다.
유형 이 일치 하지 않 고 변수 가 비어 있 기 때문에 인정 할 수 있 는 횟수 보다 이상 하 다 는 것 을 알 수 있 습 니 다.예 를 들 어 이 점 은 TS 에서 잘 개선 되 었 습 니 다. 모든 변수의 인용 은 자신의 유형 을 지정 해 야 합 니 다. 그리고 아래 에 코드 에서 무엇 을 사용 할 수 있 고 어떤 방법 을 지원 할 수 있 는 지 위 에서 정 의 를 내 려 야 합 니 다. 이 힌트 는 개발, 컴 파일 기간 에 개발 자 에 게 제시 하여 온라인 에서 문제 가 발견 되 지 않도록 하고 수정 해 야 합 니 다.
또 다른 정적 컴 파일 형식 이 가 져 온 장점 은 함수 서명 입 니 다.아니면 위 에서 말 한 것 처럼 동적 스 크 립 트 언어 이기 때문에 개발 기간 에 호출 할 함수 가 어떤 인 자 를 전달 해 야 하 는 지 정확하게 알려 주 는 편집기 가 있 기 어렵 습 니 다. 함수 가 어떤 종류의 반환 값 을 되 돌려 줍 니까?
TS 에서 하나의 함수 에 대해 먼저 모든 매개 변수의 유형 과 반환 값 의 유형 을 정의 해 야 합 니 다.이렇게 함수 가 호출 될 때 우 리 는 이 함수 의 효 과 를 뚜렷하게 볼 수 있다.
이것 은 가장 기본 적 이 고 프로그램 을 안정 시 킬 수 있 는 두 가지 특성 입 니 다. 물론 TS 에 더 많은 기능 이 있 습 니 다: TypeScript | Handbook
TypeScript node 에서 의 응용
TS 홈 페이지 에 대량의 예시 가 있 는데 그 중에서 Express 버 전의 예 를 찾 았 습 니 다. 이 를 약간 수식 하여 koa 프로젝트 에 사 용 했 습 니 다.
환경 의존
TS 를 사용 하기 전에 이 물건 들 을 준비 해 야 합 니 다.
npm i -g typescript
전역 에 TS 를 설치 하고 사용 하 는 tsc 명령 을 컴 파일 합 니 다 npm i -g nodemon
, 전역 에 nodemon 을 설치 하고 tsc 컴 파일 후 자동 으로 서버 프로그램 새로 고침 reflect-metadata
: 대량의 장식 기의 가방 은 모두 의존 하 는 기초 가방 으로 데 이 터 를 주입 하 는 데 사용 된다 routing-controllers
: 장식 기 를 사용 하여 koa - router 개발 sequelize
: 추상 화 된 데이터베이스 조작 sequelize-typescript
: 상기 플러그 인의 장식 기 버 전, 실 체 를 정의 할 때 사용 우선, 현재 프로젝트 의 구 조 를 방출 합 니 다.
.
├── README.md
├── copy-static-assets.ts
├── nodemon.json
├── package-lock.json
├── package.json
├── dist
├── src
│ ├── config
│ ├── controllers
│ ├── entity
│ ├── models
│ ├── middleware
│ ├── public
│ ├── app.ts
│ ├── server.ts
│ ├── types
│ └── utils
├── tsconfig.json
└── tslint.json
src
는 주요 개발 디 렉 터 리 로 모든 TS 코드 가 이 안에 있 습 니 다. 컴 파일 을 거 친 후에 src
와 같은 등급 의 dist
폴 더 가 생 성 됩 니 다. 이 폴 더 는 node
엔진 이 실제 실행 하 는 코드 입 니 다.src
에서 주요 코드 는 다음 과 같은 구조 로 나 뉜 다 (자신의 프로젝트 의 실제 상황 에 따라 첨삭).|folder|desc
1
controllers
인터페이스 요청, 원본
apps
, routes
폴 더 를 처리 하 는 데 사 용 됩 니 다.2
middleware
각종 미들웨어, 전역 or 사용자 정의 미들웨어 를 저장 합 니 다.
3
config
각종 설정 항목 의 위 치 는 포트,
log
경로, 각종 바라 바라 의 상수 정 의 를 포함한다.4
entity
여기에 저 장 된 것 은 모든 실체 정의 입 니 다.
5
models
entity
에서 온 실 체 를 사용 하여 sequelize
초기 화 작업 을 수행 하고 sequelize
대상 을 던 집 니 다.6
utils
저 장 된 각종 일상 개발 에서 추출 한 공공 함수
7
types
각종 객 제 화 된 복합 유형의 정 의 를 저장 하고 각종 구조, 속성, 방법 반환 값 의 정의 (현재 자주 사용 되 는 Promise 판 redis 와 qconf 포함)
controllers
controllers 는 데이터베이스 가 아 닌 논리 만 처리 하고 model 대상 을 조작 하여 데이터 의 첨삭 검 사 를 진행 합 니 다.
회사 의 대부분 Node 프로젝트 버 전이
Node 8.11
로 업그레이드 되 었 음 을 감안 하여 우 리 는 새로운 문법 을 시도 할 것 이다.즉, 우 리 는 버 릴 것 이다 Generator
, 포옹 async
/ await
.Koa
, Express
인 터 페 이 스 를 쓴 어린이 신발 은 한 항목 이 커지 면 실제로 중복 되 는 비 논리 코드 가 많이 생 긴 다 는 것 을 잘 알 고 있 을 것 이다.router.get('/', ctx => {})
router.get('/page1', ctx => {})
router.get('/page2', ctx => {})
router.get('/page3', ctx => {})
router.get('/pageN', ctx => {})
모든 경로 에서 감청 을 하면 서 반복 되 는 작업 을 많이 하고 있다.
router.get('/', ctx => {
let uid = Number(ctx.cookies.get('uid'))
let device = ctx.headers['device'] || 'ios'
let { tel, name } = ctx.query
})
거의 모든 경로 의 머리 는 파 라 메 터 를 얻 는 작업 을 하고 있 고 파 라 메 터 는
header
, body
심지어 cookie
와 query
에서 나 올 수 있다.그래서 우 리 는 원래 koa 의 사용 방법 에 대해 비교적 큰 변경 을 했 고 routing - controllers 의 대량의 응용 장식 기 를 사용 하여 대부분의 비 논리 코드 를 처리 하 는 데 도움 을 주 었 다.
원래 router 의 정의:
module.exports = function (router) {
router.get('/', function* (next) {
let uid = Number(this.cookies.get('uid'))
let device = this.headers['device']
this.body = {
code: 200
}
})
}
TypeScript 와 장식 기의 정 의 를 사 용 했 습 니 다:
@Controller
export default class {
@Get('/')
async index (
@CookieParam('uid') uid: number,
@HeaderParam('device') device: string
) {
return {
code: 200
}
}
}
인 터 페 이 스 를 검색 하기 쉽 고 선명 하 게 하기 위해 우 리 는 기 존의
bd-router
기능 을 버 렸 다.controllers
아래 파일 에 해당 하 는 인 터 페 이 스 를 직접 설명 하여 감청 합 니 다.middleware
전역 미들웨어 라면 클 라 스
@Middleware
장식 기 를 직접 추가 하고 설정 type: 'after|before'
하면 된다.특정한 미들웨어 라면 일반적인 class 를 만 들 면 됩 니 다. 그리고 사용 해 야 할 controller
대상 에 지정 @UseBefore
/ @UseAfter
(class 에 쓸 수도 있 고 method 에 쓸 수도 있 습 니 다).모든 미들웨어 는 대응 하 는 MiddlewareInterface 인 터 페 이 스 를 계승 하고 실현
use
방법 이 필요 하 다.// middleware/xxx.ts
import {ExpressMiddlewareInterface} from "../../src/driver/express/ExpressMiddlewareInterface"
export class CompressionMiddleware implements KoaMiddlewareInterface {
use(request: any, response: any, next?: Function): any {
console.log("hello compression ...")
next()
}
}
// controllers/xxx.ts
@UseBefore(CompressionMiddleware)
export default class { }
entity
파일 은 데이터 모델 만 정의 하고 논리 적 인 조작 은 하지 않 습 니 다.
마찬가지 로 sequelize + 장식 기 를 사용 하 였 으 며, enity 는 데이터베이스 와 통신 하 는 데이터 모델 을 만 드 는 데 만 사 용 됩 니 다.
import { Model, Table, Column } from 'sequelize-typescript'
@Table({
tableName: 'user_info_test'
})
export default class UserInfo extends Model {
@Column({
comment: ' ID',
autoIncrement: true,
primaryKey: true
})
uid: number
@Column({
comment: ' '
})
name: string
@Column({
comment: ' ',
defaultValue: 0
})
age: number
@Column({
comment: ' '
})
gender: number
}
sequelize 가 연결 을 만 드 는 것 도 해당 하 는 데이터베이스 주소, 계 정, 비밀번호, database 등 정보 가 필요 하기 때문에 같은 데이터베이스 의 모든 실 체 를 하나의 디 렉 터 리 에 두 는 것 을 추천 합 니 다. sequelize 가 해당 하 는 모델 을 불 러 오 는 데 편리 하고 config 에서 해당 하 는 설정 정 보 를 만 들 고 실 체 를 저장 하 는 key 열 을 추가 하 는 것 을 추천 합 니 다.이렇게 하면 데이터베이스 링크 를 만 들 고 데이터 모델 을 불 러 올 때 이 경로 의 모든 실 체 를 동적 으로 가 져 올 수 있 습 니 다.
// config.ts
export const config = {
// ...
mysql1: {
// ... config
+ entity: 'entity1' // key
},
mysql2: {
// ... config
+ entity: 'entity2' // key
}
// ...
}
// utils/mysql.ts
new Sequelize({
// ...
modelPath: [path.reolve(__dirname, `../entity/${config.mysql1.entity}`)]
// ...
})
model
model 의 포 지 셔 닝 은 해당 하 는 실체 에 따라 추상 화 된 데이터베이스 대상 을 만 드 는 것 입 니 다. sequelize 를 사 용 했 기 때문에 이 디 렉 터 리 의 파일 은 매우 간결 해 집 니 다.기본적으로 sequelize 대상 을 초기 화하 고 모델 을 불 러 온 후에 던 지 는 것 입 니 다.
export default new Sequelize({
host: '127.0.0.1',
database: 'database',
username: 'user',
password: 'password',
dialect: 'mysql', //
modelPaths: [path.resolve(__dirname, `../entity/${configs.mysql1.entity}`)], //
pool: { //
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
operatorsAliases: false,
logging: true // true sequelize SQL
})
utils
모든 공공 함수 가 여기에 놓 여 있 습 니 다.색인 파일 (index. ts) 을 작성 하 는 것 을 추천 합 니 다. 대략적인 형식 은 다음 과 같 습 니 다.
// utils/get-uid.ts
export default function (): number {
return 123
}
// utils/number-comma.ts
export default function(): string {
return '1,234'
}
// utils/index.ts
export {default as getUid} from './get-uid'
export {default as numberComma} from './number-comma'
새로운
util
을 추가 할 때마다 index
에 해당 하 는 색인 을 추가 하면 한 줄 을 통 해 도입 하고 싶 은 모든 utils
을 도입 할 수 있다 는 장점 이 있 습 니 다.import {getUid, numberComma} from './utils'
configs
configs 아래 에 저 장 된 것 은 바로 각종 설정 정보 입 니 다. 제3자 인터페이스 URL, 데이터 베이스 설정, 로그 경 로 를 포함 합 니 다.각종 balabala 의 정적 데이터.설정 파일 이 많 으 면 여러 파일 로 나 눈 다음
utils
방식 으로 색인 파일 을 작성 하 는 것 을 권장 합 니 다.types
여기에 저 장 된 것 은 모든 사용자 정의 형식 정의 입 니 다. 일부 오픈 소스 커 뮤 니 티 에서 제공 하지 않 았 지만 우리 가 사용 하 는 제3자 플러그 인 은 여기 서 정 의 를 내 려 야 합 니 다. 일반적으로 자주 사용 하 는 것 은 있 지만 일부 작은 가방 은 TS 의 지원 이 없 을 수도 있 습 니 다. 예 를 들 어 우리 가 사용 하 는 것
node-qconf
:// types/node-qconf.d.ts
export function getConf(path: string): string | null
export function getBatchKeys(path: string): string[] | null
export function getBatchConf(path: string): string | null
export function getAllHost(path: string): string[] | null
export function getHost(path: string): string | null
형식 정의 파일 은 접 두 사 를 d. ts types 아래 에 있 는 모든 파일 을 직접 참조 할 수 있 도록 규정 하고 있 으 며, 상대 적 인 경로 에 관심 을 가지 지 않 아 도 됩 니 다. (다른 일반적인 model 은 상대 적 인 경 로 를 써 야 합 니 다. 이것 은 매우 난처 한 문제 입 니 다.)
질문
현재 GitHub 창고 에는 2600 + 가 열 려 있 는 상태 인 issues 가 있 습 니 다. bug 탭 을 선택 한 후에 도 900 + 가 존재 합 니 다.그래서 사용 하 는 과정 에서 구 덩이 를 밟 지 않 을 것 이 라 고 장담 하기 어렵 지만 한 프로젝트 가 이렇게 활발 한 issues 를 가지 고 있 으 니 이 프로젝트 의 인기 정 도 를 측면 에서 설명 할 수 있다.
현재 직면 하고 있 는 유일한 난처 한 문 제 는 파일 경 로 를 참조 하려 면 반드시 다 써 야 한 다 는 것 이다.
import module from '../../../../f**k-module'
작은 매듭
TypeScript 를 처음 시도 해 보 았 습 니 다. 이 언어 를 깊이 좋아 하 게 되 었 습 니 다. 작은 문제 도 있 지만 극복 할 수 있 습 니 다.)정적 강 한 유형의 컴 파일 언어 를 사용 하면 많은 bug 를 개발 기간 에 없 앨 수 있 습 니 다.
상기 설명 을 바탕 으로 하 는 간단 한 예제: 코드 창고
즐 거 운 시간 보 내세 요. TS 관련 질문 이 있 으 시 면 소란 피 우 러 오 세 요.
NPM loves U.
。
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.