[TIL]2023.06.02 리팩토링: javascript 쪼개기(module화)

Nick·2023년 6월 5일
0

TIL: 오늘을 돌아보자

목록 보기
14/95
post-thumbnail
post-custom-banner

search 로직을 리팩토링 하면서, 스크립트 모듈화를 진행하였다.

모듈화를 왜 할까?

특정 관심사에 해당하는 기능을 수행하는 변수와 함수를 모아 구분해줌 으로서
관심사의 분리 <재사용성, 유지보수성, 깃 협업능률 향상> 에 유리하다!
모듈 별로 독립적인 scope 생성해 위의 장점을 살리 수 있다!

스크립트 지연 실행 기본 내장

<script defer>  // 스크립트에 따로 설정해줄 필요없이 html파씽이 지연되어 오류를 발생 시키지 않는다!

Strict Mode 기본 내장

"use strict"
// 변수 선언없이 즉시 사용 방지
a = 10;
console.log(a); // Uncaught ReferenceError: a is not defined
// 예약어를 변수명으로 사용 방지
let arguments; // Invalid use of 'arguments' in strict mode.

리팩토링 과정

기존 폴더구조

폴더 구조는 static > list.js , search.js 로 분리해 두었지만, 두가지 js 파일에는 중복되어 쓰이는 코드가 존재한다. 아래에서 코드를 보여줄 예정!

리팩토링 폴더구조

modules 폴더에 js 파일을 구조화해 만들어 두었다.
서로 export, import 를 수행하여, 코드의 복잡도나 중복되는 코드를 간결화 시켰다.

기존 fetch 구문

//search.js/ list.js 중복 적용
 const options = {
            method: 'GET',
            headers: {
                accept: 'application/json',
                Authorization: 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIyNmM2ODZkMDdhMTcxNDUyZWUyYzM2MGUwODFjNjAxMyIsInN1YiI6IjY0NzRjMGFhNWNkMTZlMDBiZjEyNDQ2OSIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.qgYpZS6S6GHYU8eq2rRevqoZz5g80tZ7hZ5KJ3soHVU'
            }
        };
        const url = 'https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1';

        fetch(url, options)
            .then(response => response.json())
            .then(data => {

중복되어 들어가있던 코드들이다. 유지보수시 각 파일로 들어가 수정해주어야 하는 번거로움이 있었다. 스코프가 작지만, 아닌 경우는 하나하나 찾아 수정해줘야 하는 끔찍한 상황이다.

리팩토링 fetch 구문

//option.js
export const OPTIONS = {
    method: 'GET',
    headers: {
        accept: 'application/json',
        Authorization: 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIyNmM2ODZkMDdhMTcxNDUyZWUyYzM2MGUwODFjNjAxMyIsInN1YiI6IjY0NzRjMGFhNWNkMTZlMDBiZjEyNDQ2OSIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.qgYpZS6S6GHYU8eq2rRevqoZz5g80tZ7hZ5KJ3soHVU'
    },
};
// fetchurl.js
export const URL = 'https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1';

두개의 js 파일로 구분하여, 중복되는 곳에 반영되고, 다른 API 사용시 유지보수 하는데, 독립적으로 분리를 하여 용이하게 만들었다!

기존 list 불러오기 관련 코드

// list.js 
 let rows = data['results'];
                const cardList = document.querySelector('.cardList');
                cardList.innerHTML = '';
                
                
                console.log(data)
                rows.forEach((a) => {
                    let _title = a['title'];
                    let _overview = a['overview'];
                    let _poster_path = a['poster_path'];
                    let _vote_average = a['vote_average'];
                    let _id = a['id'];

                    let temp_html = `
                        <div class="movie-card" data-id="${_id}">
                            <img src="https://image.tmdb.org/t/p/w500${_poster_path}">
                            <h3 class ="info-title">${_title}</h3>
                            <p class ="info-overview">${_overview}</p>
                            <p class ="info-vote_average">Rating: ${_vote_average}</p>
                        </div>
                    `;
                    cardList.insertAdjacentHTML('beforeend', temp_html);
                });

바닐라자바스크립트 만을 이용해 만들었다. 스코프가 크지 않지만, 아래는 메소드를 이용해 만들어 학습해 보았다.

리팩토링 list 불러오기 관련 코드

//makelist.js
export function makeList(movies) {
    // 구조분해할당
    for (let i in movies) {
        const { id, title, poster_path, overview, vote_average } = movies[i];

        // 생성
        const cardList = document.getElementById("cardList");
        const outerDiv = document.createElement("div");
        const img = document.createElement("img");
        const h3 = document.createElement("h3");
        const p1 = document.createElement("p");
        const p2= document.createElement("p");

    
        // 생성 속성 부여
        outerDiv.setAttribute("class", "movie-card");
        outerDiv.setAttribute("id", id);
        img.setAttribute("src", `https://image.tmdb.org/t/p/w500/${poster_path}`);
        img.setAttribute("alt", "title");
        h3.setAttribute("class", "info-title");
        p1.setAttribute("class", "info-overview");
        p2.setAttribute("class", "info-vote_average");

        h3.innerText = title;
        p1.innerText = overview;
        p2.innerText = vote_average;

        // 태그 위치를 조립.
        outerDiv.appendChild(img);
        outerDiv.appendChild(h3);
        outerDiv.appendChild(p1);
        outerDiv.appendChild(p2);
        cardList.appendChild(outerDiv);
      }
}

주석에 있는 것처럼, 어디에서나 속성값을 가져다 쓸 수 있게 만들었고
메소드를 이용해 makelist.js 를 만들었으며 아래 main.js에 export해 주었다.

//main.js 에서
// card list 카드 목록 처리cardClick
async function cardList(arr) {
  const movies = await fetchMovie();
  if (!arr) {
    makeList(movies);
  } else {
    const cardList = document.getElementById("cardList");
    cardList.innerHTML = "";
    makeList(arr);
  }
}
cardList();

import한 값을 이용해, card list를 불러왔다.

마무리하며

search 기능은 지난 TIL 에 기록하여 생략했다. 모듈화를 공부하면서, 협업시 함께 수월하게 작성할 수 있는 방법을 알았고, 유지보수에 강점을 두고 있다는 점을 느꼈다. 하지만, 더 작게, 효율적으로 모듈화 시킬수 있는 방법을 더 생각해보고 발전해 나아가야겠다. 스코프가 작은 상태에서 무작정 쓰는것도 바람직 하지 않아 보이기도 한데... ( 내가 잘 못쓰고 있는 것 같은 느낌적인 느낌)
다음 협업에서 좀 더 익혀 활용해 적용해 봐야 할것 같다.

profile
배우고 도전하는것을 멈추지 않는 개발자 입니다.
post-custom-banner

0개의 댓글