배꼽파지 않도록 잘 개발해요

[코드잇] 자바스크립트 모듈 본문

코드잇 Codeit/Front-End

[코드잇] 자바스크립트 모듈

꼽파 2024. 1. 6. 15:38


  • 1. 모듈 사용법

  • 2. npm과 서드파티 모듈

  • 1. 모듈 사용법

    모듈

    모듈의 장점

    · 코드를 효율적으로 관리할 수 있음

    · 다른 프로그램에서 재사용할 수 있음

    · 이미 만들어진 모듈도 많음

     

    Node.js

    ·크로스플랫폼 오픈소스 자바스크립트 런타임 환경

    ·윈도우, 리눅스, macOS 등을 지원함.

    ·V8 자바스크립트 엔진으로 구동되며, 웹 브라우저 바깥에서 자바스크립트 코드를 실행할 수 있음.

     

    프론트엔드 개발도 Node.js 환경에서 많이 함.
    - 코드 개발 시에는 서드파티 모듈과 Node.js가 제공하는 기능을 활용
    - 개발이 완료되면 최종 결과물을 빌드해서 웹 브라우저에서 실행함.

     

    모듈의 정확한 의미는 context에 따라 달라질 수 있음.
    웹브라우저에서의 모듈 : ES 모듈 = 모듈 파일 하나
    node.js에서의 모듈 : 불러올 수 있는 파일 또는 디렉토리, 불러올 수 있는 코드의 묶음


    import와 export

    · 모듈의 핵심 기능 : 코드를 필요한 단위로 나누어 놓고, 필요한 것을 불러와서 사용하는 것임.
    · 모듈 문법을 활용하기 위해서는 mjs 확장자를 사용해야함.

    calculator 파일에 있는 것을 main 파일로 가져와서 사용
    파일 경로는 항상 디렉토리 위주로 작성

     

    calculator.mjs

    export const PI = 3.14;
    
    export function add(a, b) {
        return a + b;
    }

    main.mjs

    import { PI, add } from '../calculator.mjs';
    
    console.log(PI);  // 3.14
    console.log(add(1, 2));  // 3

     

    as로 원하는 이름 지정 가능함

    import { PI, add as addNumbers } from './calculator.mjs';
    
    console.log(addNumbers(1, 2));

     

    namespace import(네임스페이스 임포트)

    모든 named export를 import할 때 별표문자(*)를 사용함.

    import * as calculator from './calculator.mjs';
    
    console.log(calculator.PI);

    default export

    calculator.mjs

    export const PI = 3.14;
    
    export default function add(a, b) {
        return a + b;
    }

    main.mjs

    import add from '../calculator.mjs';
    
    console.log(add(1, 2));  // 3

    괄호를 빼도 제대로 작동함.

     

    calculator.mjs

    export const PI = 3.14;
    
    export default function add(a, b) {
        return a + b;
    }

     

    main.mjs

    import foo from '../calculator.mjs';
    
    console.log(foo(1, 2));  // 3

    calculator.mjs에서 default export한 것을 'foo'라는 이름으로 import하겠다는 의미임.

    반드시 import한 변수/함수 이름과 일치하지 않아도 됨.

     

    calculator.mjs

    export const PI = 3.14;
    
    export default function add(a, b) {
        return a + b;
    }

    main.mjs

    import foo, { PI } from '../calculator.mjs';
    
    console.log(PI * 3);  // 9.42
    console.log(foo(1, 2));  // 3

    이렇게 일반 export와 병용하여 쓸 수 있음.

     

    function 앞에는 default를 쓸 수 있음.

    const나 let 앞에는 default 키워드 사용 불가능함.

     

    모듈 하나마다 default export 1개만 사용 가능함.


    named export vs default export

    • 파일에서 여러 함수와 변수를 export 하고 싶을 떄 : named export
    • 파일에서 하나의 메인 함수나 변수를 export 하고 싶을 때 : default export

      Named Exports Default export
    export 구문 export const 변수 = 값;
    export { 변수/함수, 변수/함수 ... }
    export { 변수/함수 as 별칭 }
    export default 변수/함수명
    export default function 함수명() {}
    import 구문 import { 변수/함수 } from 모듈
    import { 변수/함수 as 별칭 } from 모듈
    import 변수명 from 모듈
    (중괄호 생략 가능, 이름 마음대로 지정 가능)
    모듈 내 사용법 변수명, 함수명 등을 사용
    별칭을 사용하여 이름 변경 가능
    변수명을 사용
    제약 사항 여러 값들을 한번에 내보낼 수 있음 한 모듈 당 하나의 default export만 가능
    const, let 선언과 동시에 export 가능 선언 이후에만 default export 가능

     

    모든 변수/함수명에 export 지정하기

    export const PI = 3.14;
    
    export function add(a, b) {
        return a + b;
    }
    
    export function subtract(a, b) {
        return a - b;
    }
    
    export function multiply(a, b) {
        return a * b;
    }
    
    export function divide(a, b) {
        return a / b;
    }

     

    변수/함수명을 객체 안에 담아서 객체 이름 앞에 export 쓰기

    const PI = 3.14;
    
    function add(a, b) {
        return a + b;
    }
    
    function subtract(a, b) {
        return a - b;
    }
    
    function multiply(a, b) {
        return a * b;
    }
    
    function divide(a, b) {
        return a / b;
    }
    
    const calculator = {
        PI,
        add,
        subtract,
        multiply,
        divide,
    };
    
    export default calculator;

     

    맨 마지막에 export { 변수/함수 }로 작성

    const PI = 3.14;
    
    function add(a, b) { 
      return a + b;
    }
    
    function subtract(a, b) { 
      return a - b;
    }
    
    function multiply(a, b) { 
      return a * b;
    }
    
    function divide(a, b) { 
      return a / b;
    }
    
    export { PI, add, subtract, multiply, divide };
    import calculator from '../calculator.mjs';
    
    console.log(calculator.PI * 3);  // 9.42
    console.log(calculator.add(1, 2));  // 3

    ES 모듈과 CommonJS 모듈

    모듈은 node.js에서 사용되기 시작했음.
    · 웹브라우저는 간단한 스크립트를 실행하므로, 코드를 모듈화할 필요가 없었음.
    · node.js 환경은 복잡한 프로그램을 개발하므로, 코드를 모듈화하지 않고서는 감당하기 어려웠음.

    ECMAScript 모듈 (ES 모듈) CommonJS 모듈
    2015년에 등장한 모듈 시스템 Node.js에서 원래 사용되던 모듈 시스템
    import / export 문법 require / module.exports 문법
    웹 브라우저와 Node.js에서 모두 사용 가능 Node.js에서만 사용 가능
    (웹브라우저에서는 사용 불가능)

     

    · 현재 ES모듈이 자바스크립트의 표준 모듈 시스템이 되었음.

    · node.js에서는 CommonJS 모듈이 디폴트임.

    → CommonJS모듈을 사용하기 위해 mjs 확장자를 사용해야 함.

     

    ECMAScript 모듈 (ES 모듈)

    import { PI } from './calculator.mjs';
    
    function circle(x) {
    	return PI * x * x;
    }
    
    function square(x) {
    	return x * x;
    }
    
    export default {
    	circle,
    	square,
    }

     

    CommonJS 모듈

    const calculator = require('./calculator.js');
    
    function circle(x) {
    	return calculator.PI * x * x;
    }
    
    function square(x) {
    	return x * x;
    }
    
    module.exports = {
    	circle,
    	square,
    }

     

    require(CommonJS)와 import(ES Module)

    // CommonJS Module
    const express = require('express');
    
    // ES Module
    import express from 'express';

     

    웹 브라우저에서 모듈 사용하기

    <body>
      <script type="module" src="main.js"></script>
    </body>

    모듈을 사용할 때는 실행할 파일만 <script> 태그로 연결해 주고 type="module" 속성을 추가


    2. npm과 서드파티 모듈

    npm과 서드파티 모듈

    · npm : node package manager의 줄인말

    ·서드파티 모듈 : 다른 개발자나 회사들이 만들어 놓은 모듈

    · node.js의 서드파티 모듈 생태계는 워낙 방대해서 웬만한 것들은 다 서드파티 모듈을 불러와서 사용하면 될 정도임.
    · 서드파티모듈은 인터넷의 npm registry에 모여 있음.

     

    ·  vscode 터미널 단축키 : ctrl + `

    ·  터미널에서 모듈 설치하는 명령어

    npm install date-fns 
    // data-fns 설치

     

    자바스크립트의 Date 객체와 format 형식을 아규먼트로 전달해주면 그대로 날짜를 포맷팅해줌.
    new Date에서 월은 인덱스 0에서 시작함.

    import { format } from 'date-fns';
    
    const dateString = format(new Date(2023, 5, 8), 'MM-dd-yyyy');
    
    console.log(dateString);  // 23-05-08

     

    node.modules와 json파일은 npm install을 실행한 디렉토리에 생김.

    node.modules 폴더 안에는 설치한 모듈이 저장되고, date-fns가 필요로 하는 다른 모듈들도 알아서 설치가 됨.
    이 date-fns는 js 모듈 안에서만 사용 가능함.

     

    https://date-fns.org/

     

    Modern JavaScript Date Utility Library

    date-fns provides the most comprehensive yet simple and consistent toolset for manipulating JavaScript dates in a browser & Node.js.

    date-fns.org


    package.json

    · package.json : 현재 패키지에 대한 정보가 기록되어 있는 곳
    · dependencies 필드는 패키지에 필요한 서드파티 모듈의 목록

        "scripts": {
            "start": "node ./module_practice/lib/main.js",
            "test": "node test.js"
        }

    · ^ (캐럿 기호) : 버전 범위
    · 꼭 해당 버전이 아니라고 해도 특정 범위에 들어가는 범위면 괜찮다는 의미임.

    · 가장 왼쪽의 0이 아닌 버전이 바뀌지 않는 선에서의 버전 업데이트만 허용함.

    ex. ^2.29.3 → 메이저 버전 2만 바뀌지 않으면 됨.

    {"type":"module","dependencies":{"date-fns":"^3.1.0"}}

    · type : 패키지 안에서 사용할 모듈 시스템을 정함
    · import, export 같은 ES 문법을 사용하기 위해서 JS 파일 확장자를 mjs로 사용했었어야 함.
    · "type":"module"로 설정해놓으면 JS 모듈 안에서는 기본적으로 ES 모듈 문법을 사용할 수 있음.

        "scripts": {
            "start": "node main.js",
            "test": "node test.js"
        }

    ·  scripts 필드에 있는 커맨드는 "npm run *command*를 통해 실행할 수 있음.

    ·   커맨드가 start, restart, stop, test 중 하나라면 run이 필요 없음.

    npm run start
    npm start
    // start 같은 명령어는 모두 가능함

    Semantic Version

    의미론적 버전

    X : 메이져 버전(major version) 코드에 정말 큰 변화가 있어서 이전 버전과 호환이 안 될 때 업데이트
    Y : 마이너 버전(minor version) 기존 코드에 영향을 주지 않는 어떤 새로운 기능이 추가됐을 때 업데이트함.
    ex. 기존 작성한 코드 동작 + 새로운 함수 이용 (2.29.3 → 2.30.0)
    Z : 패치 버전(patch version) 기존 코드에 전혀 영향을 주지 않는 변화가 있을 때 어베이트
    ex. 버그 수정이나 코드 효율성 높임 (2.29.3 → 2.29.4)

    https://docs.npmjs.com/cli/v6/using-npm/semver#ranges

     

    semver | npm Docs

    The semantic versioner for npm

    docs.npmjs.com


    package-lock.json

    • package.json 파일 : 버전 범위를 주로 기록

    • package-lock.json 파일 : 현재 설치된 서드파티 모듈들과 버전을 정확히 기록

     

    · node.js환경에서 협업을 할 때는 만들고 있는 패키지를 공유함.
    · 패키지 폴더를 공유 대상에게 바로 보내거나, 압축해서 보내거나, git 같은 협업툴을 사용함.
    · 패키지의 node modules directory는 용량이 크기 때문에 공유하지 않음.
    · 대신 package.json파일을 공유하면 dependencies 필드를 이용해서 패키지들을 설치할 수 있음.


    package.json이 있는 폴더에서

    npm install


    dependencies 필드에 있는 서드파티 모듈들(필요한 패키지)이 설치됨.

    ·  코드를 공유하는 사람과 공유 받는 사람이 사용하는 패키지 버전이 다를 수 있음.
    ·  협업을 할 때에는 협업하는 사람들끼리 완전히 똑같은 환경을 구성하는 것이 좋음.
    ·  이때 package-lock.json 파일이 있는 상태에서 npm install을 하면 정확히 똑같은 버전의 패키지들이 설치됨.
    → node_modules 디렉토리 내용은 공유한 사람의 것과 완전히 일치하게 됨.

    ·  결론 : 공유하는 사람과 똑같은 환경을 구성해야되는 상황이면 package.json 파일, package-lock.json 파일을 둘 다 공유하는게 좋음.


    npm 커맨드

    npm install (npm i)
    @version

    # 커맨드
    npm install pkg_name@version
    
    # 예시
    npm install date-fns@2.29.0

     

    --global (-g)
    import 하지 않고 커맨드 라인에서 사용

    # 커맨드
    npm install pkg_name --global
    
    # 예시
    npm install nodemon --global

     

    --save-dev (-D)
    디버깅 툴이나 테스팅 툴 같이 개발할 때 필요하지만 소프트웨어 운영(배포)에는 필요하지 않음.

    # 커맨드
    npm install pkg_name --save-dev
    
    # 예시
    npm install jest --save-dev

    --save-dev 옵션을 사용하면 설치한 패키지가 

    package.json의 dependencies 필드에 기록 (X)

    devDependencies라는 필드에 기록 (O)

     

    npm list (npm ls)

    # 현재 디렉토리 안에 설치된 패키지 목록
    npm list
    
    # 전역 설치된 패키지 목록
    npm list -g



    npm update (npm up)
    패키지를 가장 최신 버전으로 업데이트

    # 모든 패키지 업데이트
    npm update
    
    # pkg_name 업데이트
    npm update pkg_name
    # 모든 패키지 업데이트 (전역 패키지)
    npm update -g
    
    # pkg_name 업데이트 (전역 패키지)
    npm update -g pkg_name


    npm uninstall (npm un)

    # pkg_name 제거
    npm uninstall pkg_name
    
    # pkg_name 제거 (전역 패키지)
    npm uninstall -g pkg_name

     


     

    728x90