-
Notifications
You must be signed in to change notification settings - Fork 4
๐งญ ๊ณตํต ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ํ
- TypeScript
TypeScript ์ปดํ์ผ๋ฌ(tsc vs. swc)- ํจํค์ง ๋งค๋์ npm vs. pnpm vs. yarn
- ESLint
- Prettier
- ๋์์ธ + ์์ด์ดํ๋ ์ ํด (Figma vs.
Creatie)
- J025 : server์ client ํด๋๋ฅผ ๋ถ๋ฆฌํ๊ณ ๊ณตํต์ ํจํค์ง๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ npm์ด๋ yarn์ workspace ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์์ ๊ด๋ฆฌํ๋ ๊ฒ์ผ๋ก ํด๊ฒฐ๋๋ ๋ฌธ์ ๋ผ๊ณ ๋ณด์ ๋๋ค. ๋ชจ๋ ธ๋ ํฌ๋ ๋จ์ํ ์๋ฒ, ํด๋ผ์ด์ธํธ ๊ตฌ๋ถ์ด ์๋๋ผ ์ฌ๋ฌ ๊ฐ์ง ํ๋ก๊ทธ๋จ์ ๊ฐ์ ๋๋ ํ ๋ฆฌ์์ ํ ๋ฒ์ ๊ด๋ฆฌํ ๋ ๋์ ์ด ํ์ํ ๊ฐ๋ ์ผ๋ก ์๊ฐ๋ฉ๋๋ค. ๋ณดํต ์ฉ๋ ๋ฌธ์ ๋ ์ค์นํ๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ๊ฑฑ์ ํ๋๋ฐ ์ ํฌ ๊ท๋ชจ(ํ๋์ ํ๋ก๊ทธ๋จ ๊ฐ๋ฐ)์์ ํ์์๋ ๊ฒ ์๋์ง?
- J046 : ๋ชจ๋ ธ๋ ํฌ๋ ๊ท๋ชจ๊ฐ ํฐ ํ์ฌ, ๋ค์์ ํ๋ก์ ํธ๋ฅผ ํ ๋ฒ์ ๊ด๋ฆฌํ๋ ์๋ฏธ๊ฐ ํฐ ๊ฒ ๊ฐ๋ค. ๊ทธ๋์ ์ฐ๋ฆฌ ํ๋ก์ ํธ๋ฅผ ๋ชจ๋ ธ๋ ํฌ๋ผ๊ณ ํ ์ ์์์ง๋ ์ ๋ชจ๋ฅด๊ฒ ์ ์ฌ๋ฌ ํ๋ก์ ํธ์ ํจํค์ง๋ฅผ ํ ๋ฒ์ ๊ด๋ฆฌํ๋ ๊ฒ = ๋ชจ๋ ธ๋ ํฌ ํ๋์ ํ๋ก์ ํธ์ ํ๋ก ํธ์๋โ ๋ฐฑ์๋ ํจํค์ง๋ฅผ ํ ๋ฒ์ ๊ด๋ฆฌํ๋ ๊ฒ โ ๋ชจ๋ ธ๋ ํฌ ๋ผ๊ณ ์๊ฐ
- J166: ๋ชจ๋ ธ๋ ํฌ๋ ํ๋ก์ ํธ๊ฐ ๊ณต์ ๊ฐ ํ์ํ ํจํค์ง๊ฐ ์์ ๋ ์ฐ๋๊ฑฐ ๊ฐ์. ์ฐ๋ฆฌ๋ ๊ฐ๊ฐ FE, BE ํ๋ก์ ํธ๊ฐ ๊ณต์ ํด์ผํ๋ ํจํค์ง/ํ์ผ์ด ์๋๊ฑฐ ๊ฐ์์ ํ์์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ณตํต์ผ๋ก eslint, prettier ๊ฐ์ ํจํค์ง๋ฅผ ์ค์นํ ํ์๋ ์์ด๋ณด์
- J290 : ๊ฐ์ ์ ์ฅ์์ ์๊ธฐ๋ง ํด๋ ๋ชจ๋ ธ๋ ํฌ๋ผ๊ณ ํ๋๊ฐ?
my-monorepo/
โโโ packages/ # ๊ฐ ํจํค์ง๋ฅผ ๊ด๋ฆฌํ๋ ํด๋
โ โโโ client/ # ํด๋ผ์ด์ธํธ ์ฝ๋ (์: React, Vue ๋ฑ)
โ โ โโโ src/
โ โ โโโ package.json
โ โโโ server/ # ์๋ฒ ์ฝ๋ (์: Express, Nest ๋ฑ)
โ โ โโโ src/
โ โ โโโ package.json
โ โโโ shared/ # ํด๋ผ์ด์ธํธ์ ์๋ฒ์์ ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ ์ฝ๋
โ โโโ src/
โ โโโ package.json
โโโ package.json # ๋ฃจํธ package.json (์ํฌ์คํ์ด์ค ๊ด๋ฆฌ์ ์คํฌ๋ฆฝํธ ์ค์ )
โโโ pnpm-workspace.yaml # pnpm ๋ชจ๋
ธ๋ ํฌ ์ค์ ํ์ผ (pnpm์ ์ฌ์ฉํ ๋๋ง ํ์)
์์งํ npm ์ฐ๋๊ฒ.. ๋ซ์ง ์๋?
- node_modules์ ํ์ผ๋ก ์์ฑ
- node_modules์ ํ๋๋งํฌ๋ก ์์ฑ
- ์ฌ์ค npm์ด๋ ๋ค๋ฅผ ๊ฑด ํฌ๊ฒ ์์
- ์ด์ฐจํผ ํฌ๊ฒ ์์กด์ฑ์ด๋ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ํฌ๊ฒ ์ข์ง์ฐ์งํ ํ๋ก์ ํธ๋ ์๋ ๊ฒ ๊ฐ์
https://toss.tech/article/lightning-talks-package-manager
https://toss.tech/article/node-modules-and-yarn-berry
- PnP โ node_modules ๋์ pnp.cjs ํ์ผ์ ์ฌ์ฉ
- Zero-install
https://devocean.sk.com/blog/techBoardDetail.do?ID=166592&boardType=techBlog
https://engineering.ab180.co/stories/yarn-to-pnpm
- VSCode ํธํ ๋ฌธ์
- ESLint ์ ๋๋ค?
- ๋ฌ๋ ์ปค๋ธ
- npm
- workspace๋ฅผ ์ฌ์ฉํด์ eslint, prettier ํจํค์ง ๊ณต์
yarn์ npm๊ณผ ํฌ๊ฒ ๋ค๋ฅธ ์ ์ด ์๋ ๊ฒ ๊ฐ๊ณ , yarn berry๋ ๋ฌ๋ ์ปค๋ธ๊ฐ ๋๋ฌด ๋์.
npm์ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ง์ ์ ์ผ๋ก ๊ฒฝํํ ํ์์ด ์๊ณ ๊ธฐ์กด์ ํ์๋ค์ด ๋ชจ๋ ์ฌ์ฉํ๋ npm์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ .
- import vs. require
-
eslint:recommendedhttps://eslint.org/docs/latest/rules/ - prettier?
eslint-config-prettiereslint-plugin-prettier - typescript?
@typescript-eslint/eslint-pluginhttps://typescript-eslint.io/rules/
// eslint.config.js
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from 'typescript-eslint';
export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
},
},
);
// eslint.config.js
import js from "@eslint/js";
export default [
js.configs.recommended,
{
rules: {
"no-unused-vars": "warn"
}
}
];// tsconfing.json
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
// tsconfig.app.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
// tsconfig.node.json
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
}
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
open: true,
},
});
-
"editor.formatOnSave": true โ VSCode
-
useTabs: false โ spaces vs tab
-
tabWidth: space 2 vs space 4
-
endOfLine: CRLF(/r/n) vs LF?(/n)
โ ํต์ผ์ ํ์ง ์์ผ๋ฉด Git์์ ์ถฉ๋ https://www.lesstif.com/gitbook/git-crlf-20776404.html
-
singleQuote: true โ Double Quote vs Single Quote
-
semi: true
-
trailingCommas: all https://prettier.io/docs/en/options.html#trailing-commas
-
์์
[ 12, 34, 56, 78, ] function fn( ab, cd, ef, ) { }
-
-
bracketSpacing: true (
{ test: 1234 }) https://prettier.io/docs/en/options.html#bracket-spacing -
arrowParrens: always
-
printWidth: 100
-
// prettier-ignore -
+) ํ์ดํ ํจ์ vs ์ผ๋ฐ ํจ์
- ๐ง ํ ๋น๋ฉ ๋ฐ ๋ธ๋์น ์ ๋ต
- ๐ง ์ฃผ์ ์ ์ ๋ฐ ํ ํ๋ฆฟ ์์ฑ
- ๐ป ํ๋ก์ ํธ ์ด๋ฆ ๋ฐ ๋ก๊ณ ์ ํ๊ธฐ
- ๐ป ๊ธฐํ ์ธ๋ถ์ฌํญ ์ ํ๊ธฐ
- ๐ป ๊ธฐ์ ์คํ ์์
- ๐ป ๋ฐฑ๋ก๊ทธ ์ด์ ์์ฑ
- ๐ป ๊นํ๋ธ ์ํค
- ๐ ๊ธฐํ ๋ฐ MVP ์ ์ง ํ์
- 2๏ธโฃ ์คํ๋ฆฐํธ 2 ์ฃผ๊ฐ ๊ณํ
- ๐งญ ๊ณตํต ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ํ
- ๐ฆบ ์ด๋ฒคํธ ํ๋ฆ๋
- ๐ฅ ๋ฐฑ์๋ ์๊ทธ๋๋ง ์๋ฒ ๋ฌธ์
- ๐ฝ ์คํ๋ฆฐํธ 5โ 6 ๋ฐฉํฅ์ฑ
- ๐ ์ต์ข ๋ฐํ ์ค๋น
- ๐ฟ Github Actions CD(์๋๋ฐฐํฌ)
- ๐ API
- โซ forEach๋ async๋ฅผ ๊ธฐ๋ค๋ ค์ฃผ์ง ์๋๋ค
- ๐งช WebRTC SFU ๋ฐ๋ชจ
- ๐ TURN ์๋ฒ ์ธ์ฆ ๋ฐฉ์
- ๐ ๏ธ [ํธ๋ฌ๋ธ์ํ ] /socket.io ๊ฒฝ๋ก๋ก ์ง์์ ์ผ๋ก HTTP ์์ฒญ์ ๋ณด๋ด๋ ๋ฌธ์
- ๐น WebRTC ํ์ํ์์์ ์นด๋ฉ๋ผ ์ํ์ ๋ฐ๋ฅธ ์์คํ ์์ ์ฌ์ฉ๋ ๋ถ์
- ๐ฅ ๋์นญ NAT์์์ WebRTC ์ฐ๊ฒฐ ์๋ฆฝ ๊ณผ์
- ๐ ํ ์คํธ ์ฝ๋์ ๋ชจํน