Node.js

ryusudol·2024년 1월 28일
post-thumbnail

1. JavaScript & Node.js란

  • Brendan Eich라는 사람이 1995년에 제작함
  • 정적인 웹 사이트를 보다 더 dynamic하게 만들기 위해 제작됨
  • Brendan Eich가 10일만에 만듦
  • 부족한 부분이 많았는데, 부족한 부분을 개선해서 지금의 JavaScript가 됨
  • JavaScript는 Type Checking을 하지 않아서 편리하기는 하나, 거대 프로젝트에서는 이유를 알 수 없는 에러가 자주 발생함 → 이 문제를 해결하기 위해 JavaScript에 Type Checking 기능을 추가한 언어가 제작됨: TypeScript
    // Normal cases
    const user1 = {
    	name: "New Yorker",
    	age: 25
    };
    
    // This often happens in JS and it doesn't throw an error.
    const user2 = {
    	name: 25
    	age: "New Yorker"
    };
    // Defining a type for an object.
    interface User {
    	name: string;
    	age: number;
    }
    
    // Correct case
    const user3: User = {
    	name: "New Yoker",
    	age: 25
    };
    
    // Wrong case -> TypeScript throws an error for this
    const user4: User = {
    	name: 25,
    	age: "New Yoker"
    };

Node.js

  • 기존엔 JavaScript 실행은 Browser 환경에서만 가능했음
  • 이후 Node.js가 개발되면서 JavaScript를 Browser가 아닌, 일반 컴퓨터 상에서도 실행시킬 수 있게 됨
  • Node.js는 npm이라는 package manager와 함께 다니며, 아주 거대한 커뮤니티를 형성함
    • npm에는 몇 가지 문제가 있음
      1. 보안적으로 취약함(현재는 보안적으로 상당히 보완됨)
      2. 종속적 관계를 가지는 여러 패키지들 간 버전 충돌이 잦음
      3. 패키지 다운로드 속도가 느림
      4. 다운로드 UI가 복잡함
    • Facebook(현 Meta) 사에서 yarn이라는 별도의 package manager를 제작함
      1. npm에 비해 높은 수준의 보안 제공
      2. 종속적 관계의 package 간 버전 충돌이 발생하지 않도록 자체적으로 버전을 관리함
      3. Package 다운로드 속도가 더 빠름
      4. 다운로드 UI가 더 간결함
    • 이러한 yarn의 장점 덕분에 yarn을 사용한 다운로드 횟수가 npm을 따라잡는 중

2. JavaScript 문법

변수 선언

  • var, let, const
    • var: 예전 JavaScript에서 변수 선언 시 사용하던 키워드 → 일단 변수를 한 번 생성하면 삭제되지 않고 메모리에 계속 남아 메모리 공간을 낭비하게 됨 → 오늘날에도 var 키워드를 사용할 순 있지만, 사실상 conventionally 사용하지 않음
    • let: 값이 추후 바뀔 가능성이 있는 변수를 선언할 때 사용
      for (let i = 0; i < 5; i++) {
      	console.log(`${i + 1} iteration`);
      }
    • const: 고정된 값을 저장할 변수를 선언할 때 사용
      const myName = "Suhyeon Ryu";
  • const와 let을 구분해서 사용하면, 함께 작업하는 사람들이 해당 변수의 사용 목적이나 특징을 쉽게 파악할 수 있어 팀워크에 도움됨

자료형

  • number, string, boolean, Array, Object
  • JavaScript는 자체적으로 Type 추론을 함
  • TypeScript에서의 Type으로도 사용됨

연산자

  • 산술 연산자 (+, -, *, / 등등)
  • 비교 연산자 (==, ===, <=, >=, !== 등등)
    // ==과 ===의 차이
    
    // ==은 데이터의 값만 같으면 true
    undefined == null; // true
    "99" == 99 // true
    
    // ===은 데이터의 Type까지 비교 확인
    undefined === null; // false
    "99" === 99 // false
  • 논리 연산자 (&&, ||, <<, >>, !, !!, ?, ??)
    // && -> AND
    true && true; // true
    true && false; // false
    false && true; // false
    false && false; // false
    // || -> OR
    true || true; // true
    true || false; // true
    false || true; // true
    false || false; // false
    // <<, >>
    8 << 3 // 64
    32 >> 2 // 8
    // !: true|false 변경, !!: boolean으로 변환
    !true // false
    !false // true
    ![] // false
    
    !!true // true
    !![] // true -> 비어있는 Array라도 일단 '존재'하기 때문에 true
    !!null, !!undefined // false
    // ?: optional
    const user1 = {
    	name: "Shawn"
    };
    
    console.log(user1.name);
    console.log(user1.age?);
    console.log(user2?.name);
    // ??: 앞의 값이 존재하면 그 값을, null이나 undefined이면 뒤의 값을 반환
    0 ?? "hey" // 0
    false ?? "hey" // false
    null ?? "hey" // "hey"
    undefined ?? "hey" // "hey"
  • 조건문 (if)
  • 반복문 (for, while)
  • 함수 (function, arrow function)
    function add(n1, n2) {
    	return n1 + n2;
    }
    
    const add = (n1, n2) => {
    	return n1 + n2;
    }
  • 객체 (Object)
  • 배열 (Array)
    // TypeScript에선 꺽쇠를 사용하여 배열 element의 Type 지정 가능
    Array<number> myArr = [1, 2, 3, 4, 5];
  • 비동기 (Promise, async/await)
    - Promise -> fulfilled or rejected

JavaScript는 Single-threaded 언어이기 때문에 여러 작업을 동시처리 하지 못함 → setTimeout이나 비동기처리 작업을 위해 ‘Callback Queue’를 도입하여 비동기적 작업 처리를 가능하도록 함

💡 async/await 작동 원리는 아래 페이지 참고

async await 동작원리

핵심 정리

  1. async/await로 선언한 함수는 Generator 함수로 변경됨
  2. Generator 함수가 실행될 때 yield를 기준으로 promise에서 then 메소드로 넘겨가면서 실행함
  3. then 메소드로 넘어간 부분이 MicroTaskQueue로 전달되면서 CallStack이 비워진 후 실행

3. Node.js만의 기능

os 모듈

const os = require('os');
import os from "os";
  • 운영체제 관련 정보와 메소드를 가지고 있어, 개발자가 운영체제 관련 데이터가 필요한 경우 별도의 package 설치 없이 즉각적으로 가져다 쓸 수 있음
// property
os.version

// method
os.freemem()
os.hostname()
os.release()
os.type()
os.totalmem()

fs 모듈

const fs = require('fs');
import fs from "fs";
  • 파일 처리와 관련된 작업을 할 때 사용하는 모듈
fs.readFile(filename, [option], callback);
fs.readFileSync(filename, [options]);
fs.writeFile(filename, data, [options], callback);
fs.writeFileSync(filename, data, [options]);

path 모듈

const path = require('path');
import path from "path";
  • 운영체제마다 다를 수 있는 경로 처리 방법 차이를 조율하여 경로 관련 작업을 용이하게 해줌
  • 경로 관련 구분자
    1. sep
    2. delimiter
{ sep: path.sep, delimiter: path.delimiter }
// Macbook의 경우, { sep: '/', delimiter: ':' }로 나타남
path.join("Users", "Suhyeon", "SKKU.txt"); // 'Users/Suhyeon/SKKU.txt'
path.dirname("/Users/Suhyeon/SKKU.txt"); // 'Users/Suhyeon'
path.basename("Users/Suhyeon/SKKU.txt"); // SKKU.txt
path.basename("Users/Suhyeon/SKKU.txt", ".txt"); // SKKU

http 모듈

const http = require('http');
import http from "http";
  • http 모듈을 사용하여 서버에 request을 보내고 response를 받을 수 있음
  • 이 또한 Node.js에 자체적으로 번들링 되어 있기 때문에 별도의 Package를 설치할 필요 없음
import http from "http";

const server = http.createServer((req, res) => {
	if (req.method === "GET") {
		res.writeHead(200);
		res.end('GET World !');
	}
	if (req.method === "POST") {
		res.writeHead(201);
		res.end('POST World !');
	}
});

server.listen(3000, () => {
	console.log("The server is listening . . .");
});
profile
📜 코딩 공부 기록

0개의 댓글