{
"name": "seminar4",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "nodemon",
"build": "tsc && node dist"
},
"devDependencies": {
"@types/express": "^4.17.14",
"@types/node": "^18.11.9",
"nodemon": "^2.0.20"
},
"dependencies": {
"@prisma/client": "^4.6.1",
"express": "^4.18.2",
"prisma": "^4.6.1"
}
}
{
"name": "seminar4",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "nodemon",
"build": "tsc && node dist"
},
"devDependencies": {
"@types/express": "^4.17.14",
"@types/node": "^18.11.9",
"nodemon": "^2.0.20"
},
"dependencies": {
"@prisma/client": "^4.6.1",
"express": "^4.18.2",
"prisma": "^4.6.1"
}
}
{
"compilerOptions": {
"target": "es6", // ์ด๋ค ๋ฒ์ ์ผ๋ก ์ปดํ์ผ
"allowSyntheticDefaultImports": true, // default export๊ฐ ์๋ ๋ชจ๋์์ default imports๋ฅผ ํ์ฉ
"experimentalDecorators": true, // decorator ์คํ์ ํ์ฉ
"emitDecoratorMetadata": true, // ๋ฐ์ฝ๋ ์ดํฐ๊ฐ ์๋ ์ ์ธ์ ๋ํด ํน์ ํ์
์ ๋ฉํ ๋ฐ์ดํฐ๋ฅผ ๋ด๋ณด๋ด๋ ์คํ์ ์ธ ์ง์
"skipLibCheck": true, // ์ ์ ํ์ผ ํ์
์ฒดํฌ ์ฌ๋ถ
"moduleResolution": "node", // commonJS -> node ์์ ๋์
"module": "commonjs", // import ๋ฌธ๋ฒ
"strict": true, // ํ์
๊ฒ์ฌ ์๊ฒฉํ๊ฒ
"pretty": true, // error ๋ฉ์์ง ์์๊ฒ
"sourceMap": true, // ์์ค๋งต ํ์ผ ์์ฑ -> .ts๊ฐ .js ํ์ผ๋ก ํธ๋์ค ์ .js.map ์์ฑ
"outDir": "./dist", // ํธ๋์ค ํ์ผ (.js) ์ ์ฅ ๊ฒฝ๋ก
"allowJs": true, // js ํ์ผ ts์์ import ํ์ฉ
"noImplicitAny": true, // any ์ฐ๋ฉด ์์
"noFallthroughCasesInSwitch": true, // switch๋ฌธ์์ break๋์ง ์๊ณ ํต๊ณผ๋๋ ๊ฒ ๋ฐฉ์ง
"esModuleInterop": true, // ES6 ๋ชจ๋ ์ฌ์์ ์ค์ํ์ฌ CommonJS ๋ชจ๋์ ๊ฐ์ ธ์ฌ ์ ์๊ฒ ํ์ฉ
"forceConsistentCasingInFileNames": true, // ํ์ผ ์ฐธ์กฐ์ ๋์๋ฌธ์ ๊ตฌ๋ถ ์๊ฒฉ
"noUnusedLocals": true, // ์์ฐ๋ ๋ก์ปฌ ๋ณ์ ์ฒดํฌ
"noUnusedParameters": true, // ํจ์ ํ๋ผ๋ฏธํฐ ์ค ์์ฐ๋ ๊ฒ ์ฒดํฌ
"typeRoots": [
"./src/types/express.d.ts", // ํ์
(*.d.ts)ํ์ผ์ ๊ฐ์ ธ์ฌ ๋๋ ํ ๋ฆฌ ์ค์
"./node_modules/@types" // ์ค์ ์ํ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ./node_modules/@types
]
},
"include": [
"./src/**/*" // build ์ ํฌํจ
],
"exclude": [
"node_modules", // build ์ ์ ์ธ
"tests"
]
}
๐ก ๋๋ฃ๋ค๊ณผ ๋งํฌ๋ฅผ ํต์ผํ๊ธฐ ์ํด ์ปจ๋ฒค์ ์ ์ง์ ํฉ๋๋ค. ์คํฉ์ง์กธ์ ์ฝ๋๊ฐ ์๋, ํ ์ฌ๋์ด ์ง ๊ฒ๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ถํ ์ ์ง๋ณด์๋ ํ์ ์์ ๋์์ด ๋ฉ๋๋ค. ๋ด๊ฐ ์ฝ๋๋ฅผ ์๊ฐํ๋ฉด์ ์งค ์ ์๋๋ก ํด์ฃผ๋ ๋ฃฐ์ด๋ผ๊ณ ์๊ฐํด๋ ์ข์ต๋๋ค!
๋ช ๋ช ๊ท์น(Naming Conventions)
- ์ด๋ฆ์ผ๋ก๋ถํฐ ์๋๊ฐ ์ฝํ์ง ์ ์๊ฒ ์ด๋ค.
-
ex)
// bad function q() { // ...stuff... } // good function query() { // ..stuff.. }
- ์ค๋ธ์ ํธ, ํจ์, ๊ทธ๋ฆฌ๊ณ ์ธ์คํด์ค์๋
camelCase
๋ฅผ ์ฌ์ฉํ๋ค.
-
ex)
// bad const OBJEcttsssss = {}; const this_is_my_object = {}; function c() {} // good const thisIsMyObject = {}; function thisIsMyFunction() {}
- ํด๋์ค๋ constructor์๋
PascalCase
๋ฅผ ์ฌ์ฉํ๋ค.
-
ex)
// bad function user(options) { this.name = options.name; } const bad = new user({ name: 'nope', }); // good class User { constructor(options) { this.name = options.name; } } const good = new User({ name: 'yup', });
- ํจ์ ์ด๋ฆ์ ๋์ฌ + ๋ช
์ฌ ํํ๋ก ์์ฑํ๋ค.
ex)
postUserInformation( )
- ์ฝ์ด ์ฌ์ฉ์ ์ต๋ํ ์ง์ํ๋ค.
- ์ด๋ฆ์ ๋ค ๋จ์ด ์ด์์ด ๋ค์ด๊ฐ๋ฉด ํ์๊ณผ ์์๋ฅผ ๊ฑฐ์น ํ ์ฌ์ฉํ๋ค
๋ธ๋ก(Blocks)
- ๋ณต์ํ์ ๋ธ๋ก์๋ ์ค๊ดํธ({})๋ฅผ ์ฌ์ฉํ๋ค.
-
ex)
// bad if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function() { return false; } // good function() { return false; }
- ๋ณต์ํ ๋ธ๋ก์
if
์else
๋ฅผ ์ด์ฉํ๋ ๊ฒฝ์ฐelse
๋if
๋ธ๋ก ๋์ ์ค๊ดํธ( } )์ ๊ฐ์ ํ์ ์์น์ํจ๋ค.
-
ex)
// bad if (test) { thing1(); thing2(); } else { thing3(); } // good if (test) { thing1(); thing2(); } else { thing3(); }
์ฝ๋ฉํธ(Comments)
- ๋ณต์ํ์ ์ฝ๋ฉํธ๋
/** ... */
๋ฅผ ์ฌ์ฉํ๋ค.
-
ex)
// good /** * @param {String} tag * @return {Element} element */ function make(tag) { // ...stuff... return element; }
- ๋จ์ผ ํ์ ์ฝ๋ฉํธ์๋
//
์ ์ฌ์ฉํ๊ณ ์ฝ๋ฉํธ๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ ์ฝ๋์ ์๋ถ์ ๋ฐฐ์นํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ฝ๋ฉํธ์ ์์ ๋น ํ์ ๋ฃ๋๋ค.
-
ex)
// bad const active = true; // is current tab // good // is current tab const active = true; // good function getType() { console.log('fetching type...'); // set the default type to 'no type' const type = this._type || 'no type'; return type; }
๋ฌธ์์ด(Strings)
- ๋ฌธ์์ด์๋ ์ฑํฌ์ฟผํธ
''
๋ฅผ ์ฌ์ฉํ๋ค.
-
ex)
// bad const name = "Capt. Janeway"; // good const name = 'Capt. Janeway';
- ํ๋ก๊ทธ๋จ์์ ๋ฌธ์์ด์ ์์ฑํ๋ ๊ฒฝ์ฐ๋ ๋ฌธ์์ด ์ฐ๊ฒฐ์ด ์๋
template strings
๋ฅผ ์ด์ฉํ๋ค.
-
ex)
// bad function sayHi(name) { return 'How are you, ' + name + '?'; } // bad function sayHi(name) { return ['How are you, ', name, '?'].join(); } // good function sayHi(name) { return `How are you, ${name}?`; }
ํจ์(Functions)
- ํ์ดํ ํจ์๋ฅผ ์ฌ์ฉํ๋ค.
-
ex)
var arr1 = [1, 2, 3]; var pow1 = arr.map(function (x) { // ES5 Not Good return x * x; }); const arr2 = [1, 2, 3]; const pow2 = arr.map(x => x * x); // ES6 Good
์กฐ๊ฑด์๊ณผ ๋ฑ๊ฐ์(Comparison Operators & Equality)
==
์ด๋!=
๋ณด๋ค===
์!==
์ ์ฌ์ฉํ๋ค.- ๋จ์ถํ์ ์ฌ์ฉํ๋ค.
-
ex)
// bad if (name !== '') { // ...stuff... } // good if (name) { // ...stuff... }
- ๋น๋๊ธฐ ํจ์๋ฅผ ์ฌ์ฉํ ๋
Promise
ํจ์์ ์ฌ์ฉ์ ์ง์ํ๊ณasync
,await
๋ฅผ ์ฐ๋๋ก ํ๋ค
๐ฑ git branch ์ ๋ต
main branch
: ๋ฐฐํฌ ๋จ์ branch
develop branch
: ์ฃผ์ ๊ฐ๋ฐ branch, main merge ์ ๊ฑฐ์น๋ branch
feature branch
: ๊ฐ์ ๊ฐ๋ฐ branch
- ํ ์ผ issue ๋ฑ๋ก ํ issue ๋ฒํธ๋ก branch ์์ฑ ํ ์์
- ex) feature/#
issue num
- ex) feature/#
- ํด๋น branch ์์
์๋ฃ ํ PR ๋ณด๋ด๊ธฐ
- ํญ์ local์์ ์ถฉ๋ ํด๊ฒฐ ํ โ remote์ ์ฌ๋ฆฌ๊ธฐ
- reviewer์ ์๋ก tagํ code-review
- comment ์ merge ๋ถ๊ฐ!
- main
- develop
- feature
โโโ #1
โโโ #2
๐ป git commit message convention
ex) Feat/#
issue num User API ํ์ผ ์ถ๊ฐ
- Chore : ์ฝ๋ ์์ , ๋ด๋ถ ํ์ผ ์์
- Feat : ์๋ก์ด ๊ธฐ๋ฅ ๊ตฌํ
- Add : Feat ์ด์ธ์ ๋ถ์์ ์ธ ์ฝ๋ ์ถ๊ฐ, ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐ, ์๋ก์ด ํ์ผ ์์ฑ ์
- Fix : ๋ฒ๊ทธ, ์ค๋ฅ ํด๊ฒฐ
- Del : ์ธ๋ชจ์๋ ์ฝ๋ ์ญ์
- Docs : README๋ WIKI ๋ฑ์ ๋ฌธ์ ๊ฐ์
- Move : ํ๋ก์ ํธ ๋ด ํ์ผ์ด๋ ์ฝ๋์ ์ด๋
- Rename : ํ์ผ ์ด๋ฆ์ ๋ณ๊ฒฝ
- Merge: ๋ค๋ฅธ๋ธ๋ ์น๋ฅผ mergeํ๋ ๊ฒฝ์ฐ
- Style : ์ฝ๋๊ฐ ์๋ ์คํ์ผ ๋ณ๊ฒฝ์ ํ๋ ๊ฒฝ์ฐ
- Init : Initial commit์ ํ๋ ๊ฒฝ์ฐ