$ 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
명령어를 통해 생성할 수 있습니다.
{
"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 에서는 script 부분을 설정해줘야 합니다.
기존 설정은 지우고
"scripts": {
"build": "tsc",
"start": "node build/app.js",
"dev": "nodemon --exec ts-node src/app.ts", //src폴더 안에 app.ts 파일 동작
},
로 바꿔줍니다. 실행 할 때는
$ npm run dev
를 터미널에 입력해주면 nodemon 이 실행됩니다.
$ npx sequelize init
을 통하여 config, models, migrations 폴더 등을 생성해줍니다.
타입스크립트는 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();
})();
이제 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생성 및 테이블이 생성된 것을 볼 수 있습니다.
정말 최고에요!!