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 를 수행하여, 코드의 복잡도나 중복되는 코드를 간결화 시켰다.
//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 => {
중복되어 들어가있던 코드들이다. 유지보수시 각 파일로 들어가 수정해주어야 하는 번거로움이 있었다. 스코프가 작지만, 아닌 경우는 하나하나 찾아 수정해줘야 하는 끔찍한 상황이다.
//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.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);
});
바닐라자바스크립트 만을 이용해 만들었다. 스코프가 크지 않지만, 아래는 메소드를 이용해 만들어 학습해 보았다.
//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 에 기록하여 생략했다. 모듈화를 공부하면서, 협업시 함께 수월하게 작성할 수 있는 방법을 알았고, 유지보수에 강점을 두고 있다는 점을 느꼈다. 하지만, 더 작게, 효율적으로 모듈화 시킬수 있는 방법을 더 생각해보고 발전해 나아가야겠다. 스코프가 작은 상태에서 무작정 쓰는것도 바람직 하지 않아 보이기도 한데... ( 내가 잘 못쓰고 있는 것 같은 느낌적인 느낌)
다음 협업에서 좀 더 익혀 활용해 적용해 봐야 할것 같다.