์๋ ํ์ธ์ dev_writer์ ๋๋ค.
์ค๋์ ๋ค์ ์ฌํํ ์ฃผ์ ๋ก, JS/TS ํ๋ก์ ํธ๋ฅผ Webstorm์์ ์์ํ ๋ ์ด๋ป๊ฒ ํ๋ฉด ์ข ๋ ํธํ๊ฒ ์์ํ ์ ์๋์ง ์ ๋ฆฌํด ๋ณด๋ ๊ธ์ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
๊ทธ๋์ IntelliJ์์ ์คํ๋ง ํ๋ก์ ํธ๋ง ์งํํ๋ค ๋ณด๋ JS/TS ์ ๊ท ํ๋ก์ ํธ๋ฅผ Webstorm์์ ์์ํ๋ ๋ฐฉ๋ฒ์ ์์ฃผ ์ฐพ๊ฒ ๋์๋๋ฐ, ์ด ์ฐธ์ ๋ธ๋ก๊ทธ์ ์ ๋ฆฌํด ๋๋ฉด ๊ฐ์ธ์ ์ผ๋ก๋ ์๊ธดํ๊ฒ ์ฐ์ผ ๊ฒ ๊ฐ์ ์ ๋ฆฌํด๋ณด๊ณ ์ ํฉ๋๋ค.
์คํ ํ๊ฒฝ: Mac
์คํ ์ธ์ด: TypeScript
์คํ ํ๋ ์์ํฌ: Express
Webstorm, nvm, node๋ ์ปดํจํฐ์ ์ค์น๋์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. React ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐ๋, Nest.js ํ๋ ์์ํฌ๋ฅผ ์ฐ๋ Eslint๋ Prettier ์ค์ ์ ๋ณธ ๊ธ๊ณผ ๋์ผํ๊ฒ ์ ์ฉ๋ ์ ์๊ธฐ์ ๊ทธ๋ฐ ์ฐจ์์์๋ ์์ฑํ๊ฒ ์ต๋๋ค.
1๋จ๊ณ: ๋น ํ๋ก์ ํธ ์์ฑ
Webstorm์์ ๋น ํ๋ก์ ํธ๋ฅผ ์์ฑํฉ๋๋ค.
2๋จ๊ณ: npm init
npm init์ ์ด์ฉํ์ฌ ํ๋ก์ ํธ ์ด๊ธฐ ์ค์ ์ ์งํํฉ๋๋ค.
์ ์ํด ๋ ๊ฐ์ด ์๋ค๋ฉด ๊ฐ ๋จ๊ณ์์ ์ํฐ๋ง ์ ๋ ฅํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.
devholic@devholicui-MacBookAir express % npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (express)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/devholic/Desktop/express/package.json:
{
"name": "express",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": ""
}
Is this OK? (yes)
3๋จ๊ณ: npm ํจํค์ง ์ค์น
๋ค์์ผ๋ก๋ ํ์ํ ํจํค์ง๋ค์ ์ค์นํฉ๋๋ค.
// Express
npm i express
npm i --save-dev @types/express
// TypeScript
npm i --save-dev typescript ts-node
// Nodemon
npm i --save-dev nodemon
// ESLint & Prettier
npm i --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier prettier
- Express: ๋ณธ ๊ธ์์ ์งํํ ํ๋ ์์ํฌ์
๋๋ค.
- @types/express: express ๋ชจ๋์ ๋ํ ํ์ ์ ์ง์ํฉ๋๋ค. tsconfig.json์์์ Any ํ์ ์ ๊ท์ ํ๋ค๋ฉด (noImplicitAny) express๋ฅผ ์ํฌํธ ํ ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์ค์นํด ๋ก๋๋ค.
- TypeScript: ๋ณธ ๊ธ์์ ์งํํ ์ธ์ด์
๋๋ค.
- ts-node: TypeScript ์ฝ๋๋ฅผ ์คํํ ์ ์๋๋ก ํด์ฃผ๋ Node.js ์คํ๊ธฐ์ ๋๋ค. TypeScript ํ์ผ์ ๋ฐ๋ก ์คํํ ์ ์๊ฒ ํด ์ค๋๋ค. (์ ํ ์ฌํญ)
- Nodemon: ์๋์ผ๋ก ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํ๊ณ ์ฌ์์ํด ์ฃผ๋ ๋๊ตฌ์ ๋๋ค.
- ESLint: ์ฝ๋ ํ๋ฆฌํฐ๋ฅผ ๋ณด์ฅํ๋๋ก ๋์์ฃผ๋ ๋๊ตฌ์
๋๋ค.
- @typescript-eslint/parser: ESLint๋ ์์ํ ์๋ฐ์คํฌ๋ฆฝํธ๋ง ์ดํดํ ์ ์๊ธฐ ๋๋ฌธ์, ํ์ ์คํฌ๋ฆฝํธ์์๋ ์ ์ฉ๋๊ธฐ ์ํด ์ค์นํฉ๋๋ค.
- @typescript-eslint/eslint-plugin: ํ์ ์คํฌ๋ฆฝํธ ์ ์ฉ ์ถ๊ฐ ๊ท์น์ ์ ๊ณตํฉ๋๋ค.
- eslint-config-prettier: ESLint์ Prettier ๊ฐ์ ์ถฉ๋์ ๋ฐฉ์งํฉ๋๋ค.
- Prettier: ์ผ๊ด๋ ํ ์คํธ ์์ฑ์ ๋์์ฃผ๋ ๋๊ตฌ์ ๋๋ค.
4๋จ๊ณ: ๊ฐ ์ค์ ํ์ผ ์์ฑ
๊ฐ ์ค์ ํ์ผ๋ค์ ํ๋ก์ ํธ ๋ฃจํธ์ ์์ฑํด ๋ก๋๋ค.
ํ์ ์คํฌ๋ฆฝํธ ์ค์ ์์ฑ (tsconfig.json)
package.json์์์ module์ ๋ณ๋๋ก ์ง์ ํ์ง ์์์ต๋๋ค. (์ฆ, node ํ๊ฒฝ์ CommonJS)
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"esModuleInterop": true,
"sourceMap": true, // ์ ํ
"outDir": "./dist" // ์ ํ
},
"include": [
"src/**/*.ts",
"tests/**/*.spec.ts",
]
}
- compilerOptions: ํ์
์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ์ ๋ํ ์ต์
์ ์ง์ ํฉ๋๋ค.
- target: ์ด๋ ๋ฒ์ ์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํํ ์ง๋ฅผ ์ ํํ ์ ์์ต๋๋ค. ๋๋ถ๋ถ ES6 ์ดํ๋ฅผ ์ง์ํ๊ธฐ์ ES6์ผ๋ก ๋์์ต๋๋ค.
- module: ๋ณํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๊ฐ ์ด๋ค ๋ชจ๋์ ๋ฐ๋ฅผ์ง ์ ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด CommonJS๋ก ์ค์ ํ๋ค๋ฉด ๋ด๋ถ์ ์ผ๋ก require๋ฅผ ์ฌ์ฉํ๋ฉฐ, ES6์ผ๋ก ์ค์ ํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋์์๋ import๋ฅผ ์ฌ์ฉํ๊ฒ ํฉ๋๋ค. ๊ฐ์ธ์ ์ผ๋ก๋ ๊ฐ๋ฐ ํ๊ฒฝ์์๋ ECMAScript๋ฅผ ์ ํธํ์ง๋ง ์ปดํ์ผ๋ ์๋ฐ์คํฌ๋ฆฝํธ๊น์ง ECMAScript๋ก ํ๋ฉด ์์์น ๋ชปํ ์์ธ (undici-types ๋ชจ๋ ์กฐํ ๋ถ๊ฐ๋ฅ ๋ฑ)๊ฐ ๋ฐ์ํ ์ ์๋ ๊ฑธ๋ก ๋ณด์ CommonJS๋ก ๋๋๋ก ํ์์ต๋๋ค.
- strict: ํ์ ์คํฌ๋ฆฝํธ์ ํ์ ์ฒดํน ๋์ ๋ฑ์ ํ์ฑํํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ๋ true์ ๋๋ค.
- noImplicitAny: ๋ณ์ ๋ฑ์ ๋ช ์์ ์ผ๋ก any๋ฅผ ์ ๊ฑฐ๋ ๋ค๋ฅธ ํ์ ์ ์ ์ด์ผ๋ง ์ ์ ์๋๋๋๋ก ํฉ๋๋ค.
- strictNullChecks: number ๋ฑ์ ํ์ ์ null, undefined๋ฅผ ๋ฃ์ผ๋ ค๊ณ ํ ๋ ์๋ฌ๋ฅผ ๋์ง๋๋ก ํ ์ ์์ต๋๋ค.
- esModuleInterop: CommonJS๋ก ์์ฑ๋ ๋ชจ๋๋ค์ ES6 ๋ชจ๋ ์ฌ์์ ๋ง๊ฒ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ํฉ๋๋ค.
- sourceMap, outDir: outDir์ ๋ณํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ์์ฑ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ณ , sourceMap์ ํ์
์คํฌ๋ฆฝํธ ์ฝ๋์์ ์์ฑ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ์์ค ๋งต์ ํฌํจ ํ๋๋ก ํ์ฌ ๋๋ฒ๊น
์ ์๋ณธ ํ์
์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์ถ์ ํ ์ ์๋๋ก ํฉ๋๋ค.
- ๋ค๋ง, ts-node๋ฅผ ์ค์นํ๊ณ start ์คํฌ๋ฆฝํธ์์ ์ด๋ฅผ ์ด์ฉํ๋ค๋ฉด sourceMap, outDir์ ์ง์ ํ ํ์๊ฐ ์์ต๋๋ค. (๊ทธ ๋์ ์ปดํ์ผ ๋ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ณด์ด์ง ์๊ธฐ์, ๋ ์ค์ ์ ํํ๋ฉด ๋ฉ๋๋ค.)
- include: ์ปดํ์ผํ ํ์ผ๋ค์ ์ง์ ํฉ๋๋ค. ๊ฐ๋ฐ ํ์ผ๊ณผ ํ ์คํธ ํ์ผ์ ๋ํด ์ ์ฉ๋๋๋ก ์ง์ ํ์ต๋๋ค.
Nodemon ์ค์ (nodemon.json)
nodemon.json์ ์ ์ํฉ๋๋ค.
{
"watch": ["src"],
"ext": "ts",
}
- watch: ๊ฐ์ํ ๊ตฌ๊ฐ์ ์๋ฏธํฉ๋๋ค.
- ext: ๊ฐ์ํ ํ์ฅ์๋ฅผ ์๋ฏธํฉ๋๋ค.
์ดํ package.json์ ์คํฌ๋ฆฝํธ์ ์๋์ ๊ฐ์ด nodemon์ ๋ถ์ด๋ฉด ๋ฉ๋๋ค.
"scripts": {
"start": "nodemon --exec 'tsc && node' dist/index.js",
},
...
ESLint
ESLint ์ค์ ์ ESLint 9๊ฐ ๋์ค๋ฉด์ ๊น๋ค๋ก์์ก๋๋ฐ, ํด๋น ๋ถ๋ถ์ ์์ง ํด๊ฒฐํ์ง ๋ชปํด ์๋ ๋ช ๋ น์ด๋ฅผ ์ด์ฉํ๊ฒ ์ต๋๋ค.
devholic@devholicui-MacBookAir express % npm init @eslint/config
> express@1.0.0 npx
> create-config
@eslint/create-config: v1.4.0
โ How would you like to use ESLint? · problems
โ What type of modules does your project use? · esm
โ Which framework does your project use? · none
โ Does your project use TypeScript? · typescript
โ Where does your code run? · node
The config that you've selected requires the following dependencies:
eslint, globals, @eslint/js, typescript-eslint
โ Would you like to install them now? · No / Yes
โ Which package manager do you want to use? · npm
โ๏ธInstalling...
added 2 packages, changed 1 package, and audited 301 packages in 1s
77 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Successfully created /Users/devholic/Desktop/express/eslint.config.mjs file.
์ดํ eslint.config.mjs ํ์ผ์ด ์์ฑ๋๋๋ฐ, ๋น๋ ํด๋์ธ dist์์๋ eslint๋ฅผ ์ ์ฉํ์ง ์๋๋ก ignore๋ฅผ ์ถ๊ฐํฉ๋๋ค.
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
/** @type {import('eslint').Linter.Config[]} */
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.browser } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
{
ignores: ['dist/*'],
},
// ๋ง์ฝ rules๋ฅผ ์ ์ฉํ๊ณ ์ถ๋ค๋ฉด ์๋์ฒ๋ผ ์์ฑํ๋ฉด ๋ฉ๋๋ค.
{
rules: {
// args all: ๋ชจ๋, none: ๊ฒ์ฌ X, after-used: ์ ์ธ๋ ์ธ์ ์ค ์ฌ์ฉ๋์ง ์๋ ๊ฒ๋ง ๊ฒฝ๊ณ
'@typescript-eslint/no-unused-vars': ['error', { args: 'all' }],
// ์คํ์ผ ๊ฒฝ๊ณ ์์
indent: ['error', 2],
}
}
];
๋ํ, Webstorm์์ ์์ฑํ ESLint๋ฅผ ๋ฐ๋ฅด๋๋ก ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ ์ฅํ ๋๋ง๋ค ESLint์ ๋ง๊ฒ ๊ณ ์น๋ ๊ฒ์ด ์ ์ฉ๋ฉ๋๋ค.
ESLint๋ ์๋ ๊ตฌ์ฑ์ ๋ฐ๋์ต๋๋ค.
Prettier
Prettier ์ค์ ๋ Webstorm๊ณผ ํจ๊ปํ ์ ์์ต๋๋ค.
๋จผ์ . prettierrc์ ํด๋น ์ฝ๋์ฒ๋ผ ์ค์ ์ ์์ฑํฉ๋๋ค.
{
"semi": true,
"singleQuote": true,
"tabWidth": 2
}
๊ทธ๋ค์, Webstorm ์ค์ > ์ธ์ด ๋ฐ ํ๋ ์์ํฌ > JavaScript > Prettier์์ ์๋ ํจํค์ง ๊ตฌ์ฑ > Prettier ํจํค์ง๋ฅผ ์ค์นํ prettier๋ก ๋ก๋๋ค.
์ดํ <์ ์ฅ ์ ๋ชจ๋ ์ก์ >์์ Prettier ์คํ๋ ์ค์ ํด ๋ก๋๋ค.
๊ฐํน Prettier์์ ํญ ํฌ๊ธฐ๋ฅผ 2๋ก ํ์์๋ ๋ถ๊ตฌํ๊ณ 4๋ก ๋ ๊ฒฝ์ฐ๊ฐ ์์ ํ ๋ฐ์, ๊ทธ๋ด ๊ฒฝ์ฐ์๋ Webstorm ์ค์ > ์๋ํฐ > ์ฝ๋ ์คํ์ผ > JavaScript, TypeScript ๋ถ๋ถ์์์ ์ค์ ์ 2๋ก ํด ๋๋ฉด ํด๊ฒฐ๋ฉ๋๋ค.
์ฝ๋๋ฅผ ์๋ฌด๋ ๊ฒ๋ ์ด์ง๋ฝ๊ฒ ์์ฑํด ๋ ๋ค
Cmd + S๋ฅผ ๋๋ฅด๋ฉด, Prettier์ ์ํด ์๋ ์์ ๋ฉ๋๋ค.
์ต์ข ์ ๋ฆฌ
์ต์ข ์์ฑํ package.json๊ณผ ์์ src/index.ts๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
// package.json
{
"name": "express",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"lint": "eslint .",
"build": "tsc",
// ์ํํ nodemon์ ์ํด ts-node๋ฅผ ์ด์ฉํ๋๋ก ํจ
"start": "nodemon --exec ts-node src/index.ts",
"prestart": "npm run lint && npm run clean && npm run build",
"clean": "rimraf dist"
},
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"express": "^4.21.2"
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"@types/express": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"globals": "^15.14.0",
"nodemon": "^3.1.9",
"prettier": "^3.4.2",
"rimraf": "^6.0.1", // dist ํด๋ ์ ๊ฑฐ ์ฉ๋
"ts-node": "^10.9.2",
"typescript": "^5.7.3",
"typescript-eslint": "^8.22.0"
}
}
// ์์ index.js
import express from 'express';
const app = express();
app.get('/', (req, res) => {
console.log('Hello World!!');
res.send('Welcome to the API!');
});
app.listen(3000, async () => {
// ๋น๋๊ธฐ ํ
์คํธ
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log('Server started on port 3000');
});
์ฐธ๊ณ ์๋ฃ
- ๐ ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ ์ค์ - tsconfig ์ต์ ์ด์ ๋ฆฌ
- NoImplicitAny, StrictNullChecks ์ดํดํ๊ธฐ
- [๋ ธ๋] ๋ ธ๋ nodemon TypeScript ์ ์ฉ
- WEBSTORM prettier, ESLint ์ค์
- Prettier, ESLint ์ดํดํ๊ณ ์ฌ์ฉํ๊ธฐ
- [VS Code] Prettier ์ค์ ํ๊ธฐ (Prettier ์ค์ ๋ฒ ๋ ์๊ณ ์ถ์ ๊ฒฝ์ฐ ์ฐธ๊ณ )
- ๋ฌดํฑ๋๊ณ ESLint ์ต์ ๋ฒ์ ์ค์นํ๋ฉด ๊ณ ์ํ๋ ์ด์ v9.2.0
- ESLint docs
'๐ ํ (๊ธฐ์ ์ ์ฉ ๋ฐฉ๋ฒ ๋ฑ) > JS&TS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[axios] axios ๋ฐ axios์ ์ธํฐ์ ํฐ ์์๋ณด๊ธฐ (3) | 2024.12.28 |
---|