질문 타임
- node_module 안에 package-lock.json?
- npm install과 npm i 는 동일한 의미인가요?
- npm으로 설치한 프로그램들을 쓰면 패키지가 사용자들의 개발코드들을 수집해가진 않을까요?
- 그래서 외부 패키지를 사용할 때는 신중해야합니다.
GitHub에 있는 Issues란에 가셔서 문제가 많은지도 보시고 혹시 불안하시다면 정적 코드 분석툴(snyk 같은 애들) 돌려보고 보안팀에 한 번 코드 스캔해달라고 요청도 해보시면 좋죠.
그래서 보통 버전이 매우 낮거나 이슈가 많은 친구들은 잘 안쓰려고 합니다
특히 대규모 회사들은 정보유출 문제가 중대사안이라
더욱 신중해야해요
물론 이것도 프로젝트 바이 프로젝트입니다
- package나 package-lock이나 쓰는 이유같은게 아직 와닿지가 않는데.. 써봐야 아는 부분이겠죠?
- 네 ㅎㅎ 맞아요 결국엔 프로젝트 관리를 위해선 명세서가 필요하니까 그 하나의 명세서라고 편하게 생각하시는게 좋을 것 같습니다 😉
각 언어/프레임워크들을 보시면 그러한 파일들이 하나 씩 있어요. 예를 들어 Java의 경우 pom.xml 또는 build.gradle과 같은 파일들이 있습니다 ㅎㅎ go는 go.mod라는 파일이 있구요
- 처음에 npm i 로 무엇인가를 설치할때 해당 라이브러리 사용의도에 따라서 npm -i -D, npm -i 나눠서 설치해야겠네요?
- npm install이 두 가지 경우에 사용될 수가 있는데요:
- 이미 작성된 package.json의 dependencies와 devDependencies에 명시된 패키지들을 현재 컴퓨터에 설치할 때(npm ci를 더 추천). 이 경우 그냥 npm install만 실행한다.
- 새로운 패키지를 설치할 때. 이 경우는 npm install 으로 실행한다.
- 원하는 버전을 npm install 하고 싶으면
npm install axios@1.3.0
//원하는 버전을 작성
npm install axios
//가장 최신거 가져옴
- 전역으로 깔린 모듈은 어디서 확인 가능?
- 프로젝트마다 필요한 노드 버전이 다르면 노드도 프로젝트마다 다르게 설치해주나요?
nvm use 16
- 사용할 버전의 숫자를 뒤에 사용하면 된다!
- npm이랑 붙어있어서 npm버전도 바뀐다.
이론 수업!
Node.js
package
패키지 매니저
- Node.js 프로젝트의 의존성 관리, 테스크 실행, package registry배포, 프로젝트에 관련된 메타데이터 작성들을 담당.
- 서드 파티 패키지를 package registry(NPM, GitHub Package Registry, JFrog, GitLab Package Registry)로부터 다운 받아서 개발중인 프로젝트에서 사용할 수 있도록 해줌.
- 개발중인 패키지를 npm Registry로 업로드.
- package.json이라는 프로젝트 명세 파일에 따라 기능을 수행함.
- npm(NPM이랑은 다름), yarn, pnpm
- package.json 만드는 방법
npm init
- 우체국 배송 접수 담당자
package.json
- Node.js 프로젝트 명세서: 이름, 개발자, git repository 주소, 라이선스, 의존 패키지 목록
- 프로젝트에서 사용(의존)하는 서드 파티 패키지에 대한 모든 정보: 나 이번 프로젝트에 무슨 버전의 이거, 저거, 저거를 사용해요.
- package.json 파일이 없어도 Node.js를 사용해서 JS파일을 실행시킬 순 있지만 package.json이 없으면 서드 파티 패키지(라이브러리)를 JS에서 import/require해서 사용할 수가 없음.
- 이게 왜 필요해요? git repository에 올린 프로젝트를 다른 컴퓨터에서 받아서 개발을 할 때 원래 작업했던 컴퓨터와 같은 프로젝트 상태로 구성하기 위해서임. 이 파일이 없으면 현재 프로젝트가 어떤 라이브러리를 쓰는지를 바로 알 수가 없음.
- 형제 격인 package-lock.json 파일도 있는데 이 친구는 실제 프로젝트에서 사용하는 서드파티 패키지에 대한 정확한 정보를 가지고 있음. 서드파티 패키지의 지문 역할을 하는 integrity값을 가지고 있는데 이는 해당 패키지를 다시 다운 받을 때 내가 이전에 받았던 패키지와 지금 받으려는 패키지가 동일한 지 체크를 위한 값임. 정품 인증과 비슷.
- 우체국 배송 명세서
package.json & package-lock.json
- package.json: 현재 프로젝트에 대한 메타데이터 및 npm script 그리고 사용(의존)하고 있는 외부(서드 파티) 모듈을 정리한 파일
- package-lock.json: package.json에 기록된 내용을 새로운 npm install이 발생할 때마다 snapshot 형태로 생성하는 파일
- dependencies: 어플리케이션 코드에 직접적으로 사용되는 모듈들.
- devDependencies: 어플리케이션 코드에는 사용되지 않지만 테스트/프로세스 재시작/린팅 작업들을 수행 할 때 사용되는 모듈들. 간단하게 말하면 서포트 툴이다.
- 외부 모듈들이 설치되는 node_modules 경로는 항상 git의 트래킹에서 제외하자. 사이즈가 너무 크고 어차피 package-lock.json이 있어서 괜찮다.
npm 레지스트리
- 패키지를 업로드하는 공간
- Public/Private
- 개발자들은 registry로부터 필요한 서드파티 패키지를 받아 본인 코드에서 사용할 수 있음
- 회사 내부에서만 사용하는 패키지는 private registry에 올려서 관리하는 경우가 많음
서버
- 서버 = 무언가를 제공
- 클라이언트와 서버는 (주소)가 있어야 통신을 할 수 있다(주소는 누가 할당해주는 것일까?). 주소는 보통 IP 또는 Domain을 사용.
- 요청과 요청 처리 응답까지의 과정을 트렌젝션이라고 표현한다.
- 프로토콜: 데이터 교환을 위한 규약(약속).
서버의 장점
- 다수의 사용자의 데이터를 중앙에서 처리하여 데이터의 일관성을 유지하기 용이함
- 상대적으로 빠른 연산이 필요한 작업들을 성능이 좋은 중앙 서버에 위임 가능. 클라이언트 머신의 성능이 크게 중요하지 않다. 비동기 작업 가능
- 주의(중앙)하나의서버는아니다
서버의 단점
- Single point of failure(SPOF): 서버가 다운되면 클라이언트는 속 빈 강정이 된다. 물론 이를 해결하기 위한 방법들은 존재한다. 그래도 서버가 복구되지 않으면 전체적인 서비스가 돌아가지 않는다는 건 사실이다.
- 요청의 양이 많아질수록 서버가 감당하기 어려워진다.
- 해결 방법은: 서버 수직 확장(Scale up, 머신의 스펙을 올린다) 또는 수평 확장(Scale out, 가상 머신)이 필요해진다. 비용+
- 중앙에서 데이터를 관리한다 = 공격자들의 공격에 놓이기 쉽다.
- 서버 유지보수 비용 발생
웹 서버
- 정적 컨텐츠를 제공하기 위한 서버
- HTTP 요청을 다루도록 설계 되었다.
웹 어플리케이션 서버
- 클라이언트에게 정적 컨텐츠가 아닌 서비스를 제공할 수 있는 서버. 서비스 = 비즈니스 로직
서버 구조
- 하나의 서버 머신 안에 여러개의 서버 프로세스가 존재할 수 있따.
- 각 서버 프로세스가 자신만의 요청을 수신할 수 있는 것이 포트!!
- 아파트 동 호를 생각하면 쉽다. 같은 동에 있는 주민들은 크게는 한 동(IP)이지만 호수(포트)로 각자의 집을 구분하여 주소를 사용한다.
통신규약
백엔드 개발자들이 주로 접하게 되는 프로토콜
- HTTP/HTTPS: 문서라고 쓰고 Hypertext라고 읽자.
- SSH: 원격 머신에 접속 및 제어
- FTP/SFTP: 파일 전송 - rsync는?!
- WebSocket: Full-duplex(전이) 통신
- DNS: human-readable 도메인을 IP(machine friendly address)로 변환.
- SMTP & IMAP/POP3: 메일 전송, 메일 서버 복사, 메일 서버 동기화
- DHCP: 네트워크에 연결된 머신들에게 IP를 할당.
- MQTT: 경량 machine-to-machine(M2M) 통신, 메시지큐(브로커, 클라이언트) 형식으로 통신이 가능(Diagram)
HTTP
stream
-
데이터의 흐름을 추상화
-
배열, 문자열과 비슷한 데이터의 컬렉션, 다만 배열/문자열과 다른 점은 담고자 하는 데이터가 개발자가 원하는 시점에 반드시 담기지는 않는다는
점, 그리고 매우 큰 규모의 데이터를 다룰 수 있다는 점이다.
-
데이터를 덩어리로 쪼개서(chunk라는 표현을 많이 씀) 하나 씩 읽고 해당 덩어리에 대해 작업을 수행할 수 있도록 하여준다.
-
다루고자 하는 데이터가 Node.js 상에서 바로 준비될 수 없을 때 사용을 많이한다.
-
요청 = ReadableStream
-
응답 = WriteableStream
Express.js
express.js의 장점
- 간편하게 서버 개발이 가능하다
- 편리한 라우팅 기능
- 확장성이 높은 미들웨어
- 강력한 미들웨어 생태계
정리
- Node.js의 생태계 : 런타임, 패키지 매니저, npm 레지스트리
- package.json = 명세서
- package-lock.json = 스냅샷
- 서버
- express.js
실습
질문
const mySymbol = Symbol('mySymbol');
module.exports = {
[mySymbol]: 'Hello World!'
};
- 다른 모듈에서는 mySymbol을 내보내지 않는한 일반적인 방법으로는 접근할 수 없어 Hello Worlds!라는 문자열 값을 얻지 못한다.
이렇게 Symbol을 이용하면 서드파티 모듈의 내부 구현을 보호하면서도 고유한 식별자를 부여할 수 있다.
- Factory pattern with Generic
미들웨어
- HTTP 요청과 응답 사이에 단계별 동작을 수행하고, 다음 미들웨어를 실행하는 동작을 하는 함수
어플리케이션 미들웨어
app.use나 app.http메소드
라우터 미들웨어
- 라우터 객체를 이용해, 특정 최상위 url을 기점으로 기능이나 로직별로 경로를 나누는 라우팅을 적용할 수 있다.
- var router = express.Router()로 Router 객체를 생성한 뒤에 app.use()를 사용해 마운트 시켜야지만 사용 가능하다.
- app.use()에서 지정한 경로와 같은 것이 들어온다면 모두 적용시켜버리기 때문에 중복이 될 가능성이 있다.
- app.use('/apple',...) 이 있다면 /app, /apple/image, /apple/image/news 등에 모두 적용
- 라우팅을 통해 각 경로마다 기능과 로직을 달리한다.
- 라우터를 사용한다는 점 외에 어플리케이션 미들웨어와 동일하게 사용한다.
오류처리 미들웨어
- 발생할 수 있는 오류에 대해 어떻게 처리할 것인지를 정의하는 미들웨어
- 항상 4개의 파라미터가 필요하다 (err, req, res, next)
- 에러처리 핸들러를 등록하기 위해선 다른 app.use() 및 라우트 호출을 정의한 후에 마지막으로 정의해야한다.
서드파티 미들웨어
- Express 앱에 기능을 추가할 때 사용하는 미들웨어이다.
- 필요한 기능을 위한 Node.js모듈을 설치한 후, 어플리케이션 레벨 또는 라우터 레벨에서 해당 모듈을 앱에 로드한다.
라우팅
- 클라이언트에서 보내는 주소에 따라 다른 처리를 하는 것
path parameter
:
을 사용하여 표시하며, 해당 값은 req.paras 객체를 통해 얻을 수 있다.
app.get('/user/:userId', (req,res)=>{
const userId = req.params.userId;
});
Query String
- URL 뒤에
?
을 붙이고, key=value
형태로 전달하는 방식이다.
request body
- HTTP 요청의 본문에 담긴 데이터를 말한다. 주로 Post나 Put과 같은 HTTP 메소드를 이용하여 서버로 데이터를 전송할 때 사용한다.
실습 문제 1
실습 문제 2
실습 문제 3
출처 : 엘리스 아카데미