CORS 오류와 자바스크립트 모듈화

CORS 오류 해결

자바스크립트 파일을 분리하기하던 중 일부 조원들은 분리한 기능이 정상적으로 작동하고 일부 조원들은 작동하지 않는 것을 발견했다. 작동하는 조원들은 공통적으로 라이브서버를 사용하고 있었는데, 알아보니 보안상 이유로 type="module" 속성이 붙은 스크립트는 로컬 환경에서 실행이 되지 않는다고 한다. 배포시에는 서버를 사용하기 때문에 라이브서버 환경에서만 되는 것이 큰 문제는 아니라는 피드백을 받아 우선은 다같이 라이브서버를 사용하기로 했다.

 

해결 방법

1) (경우에 따라) module 속성 제거

2) 라이브 서버 등 임시 서버 환경 사용

 

module이 뭔지 정확히 알아봐야겠다는 생각이 들어 좀 더 찾아보았다.

 

 

module

분리된 파일 각각을 module이라고 부른다. 모듈은 파일 하나를 의미하며, 스크립트 하나가 모듈 하나다.

모듈에 지시자 export, import를 적용하여 불러온 모듈에서 변수, 함수에 접근할 수 있다!

  • export - 외부 모듈에서 접근할 수 있는 변수나 함수 지정
  • import - 외부 모듈 가져오기
import { functionName } from 'module.js';

functionName();
// module.js
export function functionName() {
	alert("임포트 성공");
}

 

이렇게 활용하면 다른 스크립트에서 module.js의 functionName을 사용할 수 있다.

 

하나의 스크립트 파일에서 필요한 스크립트 파일들을 활용하기 위해 이와 같은 방법을 사용했다.

// index.html
<script type="module" src="./modules/app.js"></script>
// app.js

import { firebaseFn } from "./firebase.js"
import { cardFn } from "./cards.js"
import { modalFn } from "./modal.js"
import { setScrollEvent } from "./title.js"

firebaseFn().then((memberArray)=> {
    cardFn(memberArray)
    modalFn(memberArray)
})

setScrollEvent();

 

 

만약 특정 스크립트 내의 모든 export된 요소들을 한번에 import하려면 *을 사용할 수 있다.

import * as MathFunctions from './math.js';

MathFunction.add(19, 3);

 

module 특징

최초 호출 시 단 한번만 실행되고, 모듈을 import하는 모든 모듈에 객체가 보내진다.

// module.js
export let admin = {
	name: "John"
};

-----------------------------
// other.js
import { admin } from './module.js';
admin.name = 'minyeong';

-----------------------------
// theOther.js
import { admin } from './module.js';
console.log(admin.name);  // minyeong 출력

새로운 module.admin이 새로 생기는 것이 아니며, 따라서 다른 모듈에서도 변경된 이름 사용할 수 있다.

 

브라우저 관련 특징

지연 실행

항상 HTML 문서가 모두 준비된 후에 실행된다. 따라서 module 스크립트는 항상 HTML 문서 내 요소에 접근할 수 있다.

 

외부 스크립트

모듈 속성을 가진 스크립트는 src 속성값이 동일할 경우 한번만 실행된다.

<script type="module" scr="my.js"></script>
<script type="module" scr="my.js"></script>

 

모듈이 저장되어있는 원격 서버가 Access-Control-Allow-Origin: * 헤더를 제공해야 불러올 수 있다.

→ 이 특징이 문제가되어 라이브서버/로컬 환경에서의 차이가 발생하지 않았을까?

 

경로없는 모듈 금지

반드시 상대경로 혹은 절대경로가 있어야 한다!

import { say } from 'sayHi.js';  // 금지!

 

 

참고자료

https://ko.javascript.info/modules-intro

 

모듈 소개

 

ko.javascript.info