저장을 습관화

230606 TIL - 모듈 Module (2) 본문

공부/TIL

230606 TIL - 모듈 Module (2)

ctrs 2023. 6. 6. 22:51

0. 지난 이야기

2023.06.05 - [TIL] - 230605 TIL - 모듈 Module

// File: 1.html
// ...(전략)
<body>
    <script src="./2.js"></script>
    <script src="./3.js"></script>
    <script src="./4.js"></script>
</body>
// ...(후략)

// File: 2.js
const test = "testString";

// File: 3.js
window.alert(test);

// file: 4.js
const test = "isThisWork?";

이전 시간에 html 파일에 사용할 js 파일들을 나열해줬더니

2.js와 4.js가 서로 변수 선언이 충돌하던 일이 있었다. 

이상하다 생각했는데 HTML에는 스코프라는 개념이 없기 때문에 원래 이러는게 정상이었다.

 

만약 억지로 두 파일의 내용을 공유하고 싶지 않다면 4.js 파일 안에 변수 선언 내용을 {중괄호}로 묶어줘야 했었다.

하지만 module을 사용하면...

 

1. module 설명

module 긴 파일을 여러개로 쪼개 관리하면서 다른 파일의 코드를 가져다 사용하기 위한 기능이다.

 

전체 코드베이스를 유지 보수하기 쉽고, 모듈 간의 의존성을 관리할 수 있다. 

<body>
    <script src="./2.js"></script>
    <script src="./3.js"></script>
    <script src="./4.js" type="module"></script>
</body>

1-1. script 태그에 type="module" 속성을 넣으면 해당 파일만의 독립적인 스코프를 보장한다.

 

위와 같은 상황에서는 4.js에서 indentifier test has aready been declared 에러가 발생하지 않았다.

만약 <script src="./2.js" type="module"></script>처럼 적어줬다면

3.js에서 test is not defined 에러가 발생할 것이다....

 

1-2. <sciprt> 태그를 defer속성과 함께 <body> 태그가 아닌 <head> 태그 안에 넣어 지연실행 시킬 때가 있는데

defer 기능은 type="module" 속성에 기본 내장되어 있기 때문에 또 적어줄 필요가 없다.

 

1-3. 엄격모드 (strict mode)

ES5부터 추가된 기능이다.

이전까지 javascript는 사소한 에러들은 개발자의 실수로 판단, 에러 메시지를 띄우지않고 그냥 무시했다고 한다.

그때 당시에는 이러한 상태를 '느슨한 모드'라고 불렀던 모양이다.

 

이를 해제하기 위해 자바스크립트 상단에 'use strict'; 구문을 적어줬으나,

모듈은 항상 엄격모드로 실행도니다.

 

따라서 HTML에서 type="module" 속성을 받은 JS 파일은 별도로 'use strict'; 구문을 적어줄 필요가 없다.

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode

 

Strict mode - JavaScript | MDN

Callout: 가끔 엄격하지 않은 기본값을 " 느슨한 모드 (en-US)(sloppy mode)"라고 부르기도 합니다. 공식적인 용어는 아니지만 혹시 모르니 알아두세요.

developer.mozilla.org

 

1-4. import 사용시 가장 중요한 것

import { functionName } from "./file.js"

file.js <- 확장자명을 꼭 명시할 것

 

2. 실습

6-1. 실습 예제 따라가기

- index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>practiceForModule</title>
  </head>
  <body>
    <script src="./modules/main.js" type="module"></script>
  </body>
</html>

- main.js

import { add, div, mul, sub } from "./math.js";

console.log(add(1, 2)); // 3
console.log(sub(3, 1)); // 2
console.log(mul(4, 2)); // 8
console.log(div(6, 3)); // 2

- math.js

export const sub = (a, b) => a - b;
export const mul = (a, b) => a * b;
export const div = (a, b) => a / b;
export const add = (a, b) => a + b;

- 결과

html에선 함수의 선언이 있던 math.js 를 언급하지도 않았지만

module 속성을 받은 main.js가 받은 경로를 찾아가 add, div, mul, sub 함수를 가져왔다.

 

 

그러면 또 궁금한게

 

6-2. import, export 없이 둘 다 html에 등록해줬다면?

main.js
math.js
index.html

함수 선언의 내용이 있는 math.js가 함수를 실행할 main.js보다 밑에 있었기 때문에 not defined 에러가 발생

이건 import없이 export만 했을때, export없이 import만 했을때, <script src="./modules/math.js>가 빠졌을때

모두 같다.

 

 

6-3. import, export는 해주되, 둘 다 type="module" 속성을 받으면?

index.html
결과

잘된다..

main.js와 math.js 모두 type="module"의 기능을 받아

독립적인 스코프를 갖고, defer 속성을 갖고, 엄격하게 관리받게 되는 것과

함수를 내보내는 것은 별개의 상황인걸까

 

그럼 함수를 export하는 math.js에게 type="module" 속성을 주지 않는 이유는 뭘까..

내일 질문해봐야겠다.

 

1) 아 math.js도 다른 파일에서 함수를 import 받아올 수도 있으니

module 속성 받았다고 export나 다른 무언가 기능이 막혀선 안되겠구나

 

2) 그리고 아예 html에서 math.js를 선언하지 않은 이유는

어차피 math.js의 경로는 import하는 main.js에 적혀있으니까

 

'독립적인 스코프'라는 키워드에 너무 집중하고 있었나 보다

 

 

'공부 > TIL' 카테고리의 다른 글

230608 TIL - 로컬 스토리지와 JSON과 unexpected token  (0) 2023.06.08
230607 TIL  (0) 2023.06.08
230605 TIL - 모듈 Module  (0) 2023.06.05
230602 TIL  (0) 2023.06.02
230601 TIL  (0) 2023.06.02