TypeScript 초기 설정 및 MySQL 연동

서수·2023년 1월 14일
1

Typescript

목록 보기
1/1
post-thumbnail

타입스크립트 초기 설정

1. package.json 설치

$ npm init -y

로 package.json 을 생성해줍니다.

$ npm i express typescript @types/express
$ npm i -D nodemon ts-node @types/node

그 후에 위에 명령어를 통해 필요한 것들을 깔아줍니다.

타입스크립트는 tsconfig.json 파일이 필요합니다.
tsconfig.json 파일은

$ tsc --init

명령어를 통해 생성할 수 있습니다.

2. tsconfig.json 설치 및 설정

{
  "include": ["src"],
  "compilerOptions": {
    "outDir": "build",
    "target":"ES6",
    "lib":["ES6","DOM"],
    "strict": true,
    "esModuleInterop": true,
    "module": "CommonJS",
    "sourceMap": true,
  },  
}

제 환경설정은 이렇게 해놨습니다. 추가적으로 필요한 설정들을 넣고 빼고 할 수 있습니다.

그 외에 설정은 아래에서 확인 해 볼수 있습니다.

{
  "compilerOptions" : {
    //기본 설정들
  	"incremental": true, //증분 컴파일 설정 여부
    "target" : "es6", //사용할 특정 버전
    "module" : "commonJS", //모듈을 위한 코드 생성 설정 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'
    "lib" : [], //컴파일에 포함될 라이브러리 파일 목록 ES6, DOM ...
    "allowJS" : true, //JS파일의 컴파일 허용 여부,
    "checkJS" : true, //.js 파일의 오류 검사 여부
    "jsx" : "react", // JSX코드 파일 생성 설정: 'preserve', 'react-native', 혹은 'react',
    "declaration" : true, // 각 .d.ts 파일의 생성 여부
    "declarationMap" : true, // 각 .d.ts 파일의 소스맵 생성 여부
    "sourceMap" : true, //.map 파일의 생성 여부
    "outFile" : "./", //단일 파일로 합쳐서 출력
    "outDir" : "./", //해당 디렉토리로 결과 출력
    "rootDir": "./", //입력 파일의 루트 디렉토리 설정, --outDir로 결과 디렉토리 구조를 조작할 때 사용
    "composite": true, //프로젝트 컴파일 여부
    "tsBuildInfoFile": "./", //증분 컴파일 정보를 저장할 파일
    "removeComments": true, // 주석 삭제 여부
    "noEmit" : true, //결과 파일 내보낼지 여부
    "importHelpers": true, // 'tslib'에서 헬퍼를 가져올지 여부
    "downlevelIteration": true, // 타겟이 ES5, ES3 일때도 'for-of', spread 그리고 destructuring 문법 모두 지원
    "isolatedModules": true, // 각 파일을 분리된 모듈로 트랜스파일('ts.transpileModule'과 비슷)
    //엄격한 타입-확인 옵션
    "strict": true, //모든 엄격한 타입체킹 옵션 활성화 여부
    "noImplicitAny": true, //any타입으로 구현된 표현식 또는 정의 에러처리여부
    "strictNullChecks": true, //엄격한 null 확인 여부
    "strictFunctionTypes": true, // 함수 타입에 대한 엄격한 확인 여부
    "strictBindCallApply": true, // 함수에 엄격한 'bind','call', 그리고 'apply' 메소드 사용 여부
    "strictPropertyInitialization": true, // 클래스의 값 초기화에 엄격한 확인 여부
    "noImplicitThis": true, // any 타입으로 구현된 this 표현식 에러처리 여부
    "alwaysStrict": true,  //strict 모드로 분석하고 모든 소스 파일에 "use strict"를 추가할 지 여부
    //추가적인 확인.
    "noUnusedLocals": true, // 사용되지 않은 지역변수에 대한 에러보고 여부
    "noUnusedParameters": true, //사용되지 않은 파라미터에 대한 에러보고 여부
    "noImplicitReturns": true, // 함수에서 코드의 모든 경로가 값을 반환하지 않을 시 에러여부 보고
    "noFallthroughCasesInSwitch": true, // switch 문에서 fallthrough 케이스에 대한 에러여부 보고
    //모듈 해석 옵션
    "moduleResolution": "node", //모듈 해석 방법 설정: 'node' (Node.js) 혹은 'classic' (TypeScript pre-1.6).
    "baseUrl": "./", //non-absolute 한 모듈 이름을 처리한 기준 디렉토리 
    "paths": {}, //'baseUrl'를 기준으로 불러올 모듈의 위치를 재지정하는 엔트리 시리즈
    "rootDirs": [], //결합된 컨텐츠가 런타임에서의 프로젝트 구조를 나타내는 루트 폴더들의 목록
     "typeRoots": [], //타입 정의를 포함할 폴더 목록, 설정 안 할 시 기본적으로 ./node_modules/@types로 설정
     "types": [], //컴파일중 포함될 타입 정의 파일 목록
     "allowSyntheticDefaultImports": true, //default export이 아닌 모듈에서도 default import가 가능하게 할 지 여부, 해당 설정은 코드 추출에 영향은 주지 않고, 타입확인에만 영향을 줍니다.
     "esModuleInterop": true, //모든 imports에 대한 namespace 생성을 통해 CommonJS와 ES Modules 간의 상호 운용성이 생기게할 지 여부,  'allowSyntheticDefaultImports'를 암시적으로 승인합니다.
     "preserveSymlinks": true, //symlik의 실제 경로를 처리하지 않을 지 여부
     "allowUmdGlobalAccess": true, //UMD 전역을 모듈에서 접근할 수 있는 지 여부
      //소스맵 옵션
     "sourceRoot": "", //소스 위치 대신 디버거가 알아야 할 TypeScript 파일이 위치할 곳
     "mapRoot": "", //생성된 위치 대신 디버거가 알아야 할 맵 파일이 위치할 곳
     "inlineSourceMap": true, //분리된 파일을 가지고 있는 대신, 단일 파일을 소스 맵과 가지고 있을 지 여부
     "inlineSources": true, //소스맵과 나란히 소스를 단일 파일로 내보낼 지 여부, '--inlineSourceMap' 혹은 '--sourceMap'가 설정되어 있어야 한다.
      //실험적 옵션
     "experimentalDecorators": true, //ES7의 decorators에 대한 실험적 지원 여부
     "emitDecoratorMetadata": true, //decorator를 위한 타입 메타데이터를 내보내는 것에 대한 실험적 지원 여부
      //추가적 옵션
      "skipLibCheck": true, //정의 파일의 타입 확인을 건너 뛸 지 여부
      "forceConsistentCasingInFileNames": true //같은 파일에 대한 일관되지 않은 참조를 허용하지 않을 지 여부
  }
}

package.json 설정

package.json 에서는 script 부분을 설정해줘야 합니다.
기존 설정은 지우고

"scripts": {
    "build": "tsc",
    "start": "node build/app.js",
    "dev": "nodemon --exec ts-node src/app.ts", //src폴더 안에 app.ts 파일 동작
  },

로 바꿔줍니다. 실행 할 때는

$ npm run dev

를 터미널에 입력해주면 nodemon 이 실행됩니다.

mySQL 연동하기

설치

$ npx sequelize init

을 통하여 config, models, migrations 폴더 등을 생성해줍니다.

Config

타입스크립트는 config.json 파일은 config.ts 파일로 변환해줘야 합니다.
그리고 필수적으로 dotenv 를 사용하여 DB 정보들을 숨겨줘야합니다. (git 을 사용한다면 gitignore도 필수입니다.)

//config/config.ts
import dotenv from 'dotenv';
dotenv.config();

type Config = {
  username: string, 
  password: string, 
  database : string, 
  host : string, 
  [key: string]: string | boolean; 
}

interface IConfig {
  development : Config;
}

const config:IConfig = {
  development : {
    username : process.env.DB_USERNAME!, //설정한 username
    password : process.env.DB_PASSWORD!, //설정한 비밀번호
    database : process.env.DB_DBNAME!, //설정한 DB 이름
    host : process.env.DB_HOST!, //엔드포인트
    dialect : "mysql"
  }
};

export default config;

이제 DB 생성을 위한 TS 파일을 만들어 줘야 합니다.

//config/dbcreate.ts
import { Sequelize, Options } from 'sequelize';
import dotenv from 'dotenv';
dotenv.config();

class options implements Options {
    dialect!:'mysql';
    username!: string;
    password!: string;
    host!: string;
}

const createDBOptions = new options();
createDBOptions.username = process.env.DB_USERNAME
createDBOptions.password = process.env.DB_PASSWORD
createDBOptions.host = process.env.DB_HOST!;
createDBOptions.dialect = 'mysql';

let db_name = process.env.DB_DBNAME || "personalProject";
const dbCreateSequelize = new Sequelize(createDBOptions);

console.log(`==create DB ${db_name}`);

dbCreateSequelize
.getQueryInterface()
.createDatabase(db_name)
.then(() => {
    console.log('DB create Success');
})
.catch((e) => {
    console.log('create DB Error :', e)
})

그리고 migration 을 위한 파일도 만들어 줘야합니다.

//config/migrate.ts
import sequelize from "../models";
import Users from '../models/user';

const dropTable = [Users]; //model 에서 만든 Table 들 전부 안에 입력.
const createTable = [Users]; //model 에서 만든 Table 들 전부 안에 입력.

async function migrate() {
    for (let i=0; i < dropTable.length; i++){
        await dropTable[i]
        .drop()
        .then(() => {
            console.log(`Success drop ${dropTable[i]} Table`)
        })
        .catch((err) => {
            console.log(`Error in drop ${dropTable[i]} Table`, err)
        })
    } 
    
    for (let i=0; i< createTable.length; i++){
        await createTable[i]
        .sync({force:false})
        .then(() => {
            console.log(`Success create ${createTable[i]} Table`)
        })
        .catch((err) => {
            console.log(`Error in Create ${createTable} Table`)
        });
    }
    sequelize.sync();
}

(async () => {
    await sequelize.query(`DROP TABLE IF EXISTS topicMapping`);
    await migrate();
})();

package.json 설정

이제 DB 생성 및 migration 을 해주려면 package.json 의 script 를 수정해야 합니다.

"scripts": {
    "build": "tsc",
    "start": "node build/app.js",
    "dev": "nodemon --exec ts-node src/app.ts",
    "dbcreate": "ts-node ./src/config/dbcreate.ts",
    "migrate": "ts-node ./src/config/migrate.ts"
  },

dbcreate 부분과 migrate 부분이 추가가 된 것을 볼 수 있습니다.
이제 이 script 를 실행하려면 터미널에 다음 명령어들을 입력해 줍니다.

$ npm run dbcreate // DB 생성 명령어
$ npm run migrate // migration 명령어

그럼 mySQL 에 DB생성 및 테이블이 생성된 것을 볼 수 있습니다.

참고자료

https://geonlee.tistory.com/214

profile
패션디자인과 출신 비전공자가 개발자로 성장하려 만든 노트

1개의 댓글

comment-user-thumbnail
2023년 1월 16일

정말 최고에요!!

답글 달기