js에서의 파일 분리법(외부 함수 불러들이기 해결 완료)
파일 분리 이전의 준비
일반적으로 선언한 js에서는 함수를 정의할 때에 function 함수명
으로 작성하는 반면, 다른 곳에서 불러들여야하는 함수를 정의 시에는 export function함수명
으로 작성한다.
파일 혹은 클래스 분리의 기준
나의 경우 다음과 같은 원칙을 생각하며 나눈다.
- 단일 책임의 원칙
클래스 혹은 파일은 하나의 기능만을 가지도록 한다.
나는 처음에 이 기준이 감이 안와서 하나의 클래스에 코드가 100줄에 육박하면 클래스나 파일을 나눌 지점이 없는지 확인해보았다. - 모듈화
간혹 코틀린과 같이 다른 언어에 비해 문법이 간소화된 언어라면 모든 기능별로 파일을 분리하면 굉장히 작은 크기의 파일이 많이 나오는 경우가 생긴다.
따라서 나는 이 경우 논리적으로 묶일 수 있는 내용(예를 들어서 카카오 로그인과 네이버 로그인은 모두 소셜 로그인 파일에 넣는다든지)을 기준으로 파일을 구분하였다. - 가독성
개발자는 기본적으로 협업을 지향해야하는 직업이다.
따라서 다른 이가 나의 코드를 읽을 때에 어떻게 하면 편할지에 대해 기본적으로 생각해야하는 직업인데, 코드를 분리해놓으면 기능별로 어떤 코드가 어디에 있는지 다른 사람들도 찾기 편해진다.
그러나 import가 되지 않는다
내 딴에는 원인이 없는 (색인):1 Uncaught ReferenceError: 함수명 is not defined
at HTMLButtonElement.onclick ((색인):1:1)
onclick @ (색인):1
오류가 뜨기 시작했다.
네트워크에서 분명 저 함수가 담겨있는 js파일은 제대로 읽고 있는 것을 확인하였다.
또한, 분리를 하기 직전까지 코드가 돌아가는 것을 확인했기 때문에 코드 자체의 문제일 확률은 낮았다.
해결방안 1 mjs로 업그레이드
- 실패
이 방법으로 성공하셨다는 사람들이 많아서 기대하였으나, 나는 실패하였다.
또한, script의 순서를 바꾸면 된다는 사람들도 많았는데 미리 말하자면 나는 이 방법으로도 문제가 해결되지 않았다.두번째 시도 as를 사용한 import
- 실패
as를 사용하여 다른 명칭을 사용하도록 하고 전체 파일을 import해보았다.
그 결과 json과 api서버는 제대로 작동하는것(오류코드 확인하기)을 확인하였다.
Uncaught ReferenceError
에러가 뜬 것으로 보아, 내가 export한 함수 자체를 찾지 못하고 있다는 것을 확인할 수 있었다.
지금 서버는200코드
로 정상작동하고 있는 것으로 보아 함수 혹은 인자를 찾지 못하는 것으로 판단하고 이후 수정을 진행하였다.세번째 시도 블록의 범위 확인하기
js를 배운지 얼마 안됐기 때문에 혹여나 블록 범위가 문제인지 다시한번 확인을 해보았다.
지금 나의 경우 버튼을 append해주고 있는데 이 과정에서 혹시 .append()시 import한 것들이 import가 되지 않는 것인지부터 검색해보았다.
그러나, import는 멀쩡하게 되고있었으며 click함수에consloe.log
를 붙여본 결과 인자 역시 내가 예상하는 인자가 전달되고 있음을 확인하였다.export한 함수의 호출여부 확인하기
export함수의 끝에
console.log
를 찍어 호출이 되고있는지를 이제야 살펴보았다.
그 결과 놀랍게도 함수가 실행되지 않고있음을 발견하였고, 현재에는 함수 호출이 되지 않는 원인을 찾는 중이다.script로 직접 불러오기
맨 처음 생각한 가설 중에 하나는 append를 불러오는 과정에서 import가 되지 않을 수도 있다는 것이었다. 그래서 이 가설이 원인일까 싶어 스크립트를 통해 직접 append 안에도 함수를 불러들였으나, 내 예상과 달리 작동하지 않는 것을 확인하였다.
마지막 해결방안
이번에 넥슨 api를 호출하면서 알게 된 내용이다.
위에서 나온 오류와 정말 똑같은 현상을 겪었는데 아래에 서술 할 몇가지 방법을 통해서 해결하였으니 혹시 비슷한 문제를 겪는 사람이라면 아래의 내용을 쫓아오면 해결이 될 가능성이 크다.쿼리 셀렉터 확인
쿼리 셀렉터
함수의 범위는 해당 파일의 컨텍스트 내다.
따라서 상속을 통해 함수를 export했더라도 그 함수 위에서 정의한 쿼리 셀렉터는 함께 옮겨지는 것이 아니기 때문에, 다시 쿼리 셀렉트 구문을 작성해주어야한다.인자 다시 확인하기
function get_symbol(ocid) { $.ajax({ type: "GET", url: "/symbol_result", contentType: 'application/json', data: { 'ocid': ocid }, success: function(response) { var character_class = response.character_class; $.ajax({ type: "POST", url: "/symbol_char", contentType: 'application/json', data: JSON.stringify({ 'character_class': character_class }), success: function(postResponse) { updateUI(postResponse); }, error: function(postError) { console.error(postError); } }); }, error: function(error) { console.error(error); } }); } function updateUI(response) { console.log(response); var resultSpan = $(".home_body #characterNameSpan"); if (!resultSpan.length) { console.error("Span element not found."); return; } if (response.character_class) { resultSpan.text(response.character_class); notice.style.display = 'none'; } else { resultSpan.text("No character class available"); } }
이런 식으로 위에 function에 response를 제대로 정의하였더라도 아래 함수에서 사용할 때에는 다시 response를 인자로 받아주어야한다.
이는 상속을 했을 때에도 마찬가지이다.attr사용시 주의
나는 ui를 업데이트할 때에 처음에는 attr을 썼는데 이때 만약 span클래스가 정의되어있지 않다면
null
에러가 나거나 이상하게 글자가 겹치는 현상이 일어날 수도 있다.
따라서 미리 span영역을 뺀 뒤 디자인하는 것이 세팅에 용이하다.
댓글남기기