๐ ๋ฆฐํ (Linting)์ ์ฝ๋๋ฅผ ๋ถ์ํ์ฌ ์ ์ฌ์ ์ธ ์ค๋ฅ, ๋ฒ๊ทธ, ์คํ์ผ ๊ฐ์ด๋ ์๋ฐ ๋ฑ์ ๋ฌธ์ ๋ฅผ ์ฐพ์๋ด๋ ๊ณผ์ ์ ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ฆฐํธ ๋๊ตฌ(ex: ESLint, JSLint, Pylint)๋ฅผ ์ฌ์ฉํ์ฌ ์์ค ์ฝ๋๋ฅผ ๊ฒ์ฌํ๋ฉฐ, ์ด๋ฌํ ๋๊ตฌ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ํนํ๋ ๊ท์น๊ณผ ๊ท์น ์ธํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฝ๋๋ฅผ ๋ถ์ํฉ๋๋ค.
๋ฆฐํธ
๋ ์ฝ๋์ ์ผ๊ด์ฑ๊ณผ ํ์ง์ ์ ์งํ๋ฉฐ, ๋ฒ๊ทธ๋ฅผ ์ฌ์ ์ ์๋ฐฉํ๊ณ ๊ฐ๋
์ฑ์ ํฅ์์ํค๋ ๋ฐ ๋์์ ์ค๋๋ค.
ex) ๋ณ์๋ฅผ ์ ์ธํ์ง ์๊ณ ์ฌ์ฉํ๋ ๋ฑ์ ์ค๋ฅ๋ฅผ ์ฐพ์๋ด๊ฑฐ๋, ์ฝ๋ ์คํ์ผ ๊ฐ์ด๋์ ๋ง์ง ์๋ ์ฝ๋๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค.
๐ ํฌ๋งทํ (Formatting)์ ์ฝ๋์ ๊ตฌ์กฐ์ ์์์ ์ผ๊ด๋๊ฒ ์ ๋ฆฌํ๋ ๊ณผ์ ์ ๋๋ค.
์ฝ๋ ํฌ๋งทํ ๋๊ตฌ(ex: Prettier, Black, clang-format)๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ์ฝ๋๋ฅผ ์์ํํ๊ฑฐ๋ ์ ๋ฆฌํ ์ ์์ต๋๋ค.
ํฌ๋งทํ
์ ์ฝ๋๋ฅผ ์ฝ๊ธฐ ์ฝ๊ณ ์ผ๊ด๋ ์คํ์ผ๋ก ์ ์งํ๋ ๋ฐ ๋์์ด ๋๋ฉฐ, ์ฝ๋๋ฒ ์ด์ค ์ ์ฒด์์ ์ผ๊ด๋ ์์์ ์ ์งํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
ex) ๋ค์ฌ์ฐ๊ธฐ, ์ค ๋ฐ๊ฟ, ๊ณต๋ฐฑ์ ์ฌ์ฉ ๋ฑ์ ์๋์ผ๋ก ์กฐ์ ํ์ฌ ์ฝ๋์ ๊ฐ๋
์ฑ์ ํฅ์์ํต๋๋ค.
eslint / prettier
vscode์ ๊ฐ๊ฐ ์ค์น๋ฅผ ํด์ค๋๋ค.
$ npm init @eslint/config
์๋ก์ฝ๋กฌ ์ค์น๋ฅผ ํ๋ค.
package.json์ ์ฃผ์์ ๋ฌ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ js๋ก ์ ํํ๋ค.
โ ๏ธ ์๋ชป ์ ํ ํ์ ๋ ๋ค์ ์ค์น ํ๋ ๋ฒ
$ npm remove eslint
bash์ ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ ํ
.eslintrc.js
ํ์ผ์ ์ญ์ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค์ ์ฒ์๋ถํฐ ์ค์นํ๋ฉด ๋๋ค.
module.exports = {
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"overrides": [
{
"env": {
"node": true
},
"files": [
".eslintrc.{js,cjs}"
],
"parserOptions": {
"sourceType": "script"
}
}
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-unused-vars": "warn"
}
}
$ npm i -D prettier
.prettierrc.js์ ํ์ผ์ ๋ง๋ ๋ค.
module.exports = {
// ํ์ดํ ํจ์ ์ ๋งค๊ฐ๋ณ์ () ์๋ต ์ฌ๋ถ (ex: (a) => a)
arrowParens: 'always',
// ๋ซ๋ ๊ดํธ(>) ์์น ์ค์
// ex: <div
// id="unique-id"
// class="contaienr"
// >
htmlWhitespaceSensitivity: 'css',
bracketSameLine: false,
// ๊ฐ์ฒด ํ๊ธฐ ๊ดํธ ์ฌ์ด ๊ณต๋ฐฑ ์ถ๊ฐ ์ฌ๋ถ (ex: { foo: bar })
bracketSpacing: true,
// ํํญ ์ค์ (์ค ๊ธธ์ด๊ฐ ์ค์ ๊ฐ๋ณด๋ค ๊ธธ์ด์ง๋ฉด ์๋ ๊ฐํ)
printWidth: 80,
// ์ฐ๋ฌธ ๋ํ ์ค์
proseWrap: 'preserve',
// ๊ฐ์ฒด ์์ฑ key ๊ฐ์ ์ธ์ฉ ๋ถํธ ์ฌ์ฉ ์ฌ๋ถ (ex: { 'key': 'xkieo-xxxx' })
quoteProps: 'as-needed',
// ์ธ๋ฏธ์ฝ๋ก (;) ์ฌ์ฉ ์ฌ๋ถ
semi: true,
// ์ฑ๊ธ ์ธ์ฉ ๋ถํธ(') ์ฌ์ฉ ์ฌ๋ถ
singleQuote: true,
// ํญ ๋๋น ์ค์
tabWidth: 2,
// ๊ฐ์ฒด ๋ง์ง๋ง ์์ฑ ์ ์ธ ๋ท ๋ถ๋ถ์ ์ฝค๋ง ์ถ๊ฐ ์ฌ๋ถ
trailingComma: 'es5',
// ํญ ์ฌ์ฉ ์ฌ๋ถ
useTabs: false,
};
๐ค vscode์์ ์ค์นํ๊ณ npm์ผ๋ก ์ค์นํ๋ ๊ฒ์ ์ฐจ์ด์ ?
์ฌ๋ฌ๊ฐ์ง ์ด์ ๊ฐ ์์ง๋ง ๊ทธ ์ค ํ๋๋ ์๊ฐ์ ์ธ ํจ๊ณผ๋ก ๋ณด๊ธฐ ์ํด์ ์ค์น ํ๊ณ ๋ ์ฝ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด ์ค์นํ๋ค.
devDependencies
โ ๋จ์ํ ๊ฐ๋ฐ์ฉ์ผ๋ก๋ง ํ์ํ ๊ฒ, ๋ฐฐํฌ ์ ํฌํจ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ฉ๋์ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
dependencies
โ ๋ชจ๋ ์ฝ๋๊ฐ ๋น๋๋ ๋ ํ๋ก์ ํธ ์์ ๊ผญ ๋ค์ด๊ฐ์์ด์ผ ๋๋ค๋ ๋ป
๊ฐ๋จํ ๋งํ๋ฉด,
devDependencies
๋ ๊ฐ๋ฐ ์์๋ง ํ์ํ ์์กด์ฑ์ ํฌํจํ๋ ๋ฐ๋ฉด, dependencies
๋ ์ค์ ๋ก ์ ํ๋ฆฌ์ผ์ด์
์ด ์คํ๋๋ ๋ฐ ํ์ํ ์์กด์ฑ์ ํฌํจํ๋ค.
์ด๋ ํ๋ก๋์ ํ๊ฒฝ๊ณผ ๊ฐ๋ฐ ํ๊ฒฝ ์ฌ์ด์ ์ฐจ์ด๋ฅผ ๋ฐ์ํ๋ฉฐ, ํ๋ก์ ํธ์ ๋ฐฐํฌ ๋ฐ ์คํ์ ์ํ ์์กด์ฑ์ ๊ด๋ฆฌํ๋ ๋ฐ ๋์์ด ๋๋ค.
npm โก๏ธ ๋์๊ด
npm -g โก๏ธ ์ฑ
์ ๊ตฌ๋งค
npx โก๏ธ ์ฑ
์ ์ด์ด๋ณผ ์ ์๋ ๋๊ตฌ / ํ๋ฒ ๋ณผ ์๋ ์์ / ํ์์ ๊ฐ์ ๋๋
package.json โก๏ธ ์ฑ
์ ๋น๋ ธ๋ค๋ ์๊ธฐ๋ก ์ด ๋ช
๋ถ (์ง์์ง ์๋ ์์)
package-lock.json โก๏ธ ์๊ธฐ๋ก ์ด ๋ช
๋ถ๋ฅผ ๋ฐ์ดํฐ๋ก ์ ์ฅ
"scripts"
์ ๋ค์ด์์ผ๋ฉด npx๊ฐ ์๋ npm์ผ๋ก ๋ฐ๋ก ์ฌ์ฉ!!
const liveServer = require('live-server');
const params = {
port:5500,
host:'localhost',
root: './client',
open:false
}
liveServer.start(params);
ํ์ผ์ ์์ฑํ ํ ๋ ธ๋๋ก ๋ผ์ด๋ธ ์๋ฒ ์คํํ๊ธฐ