JavaScript / HTML에 스크립트 넣기와 외부 JS 파일 연결하기

JavaScript를 HTML 문서에서 실행하려면 <script> 요소 안에 코드를 쓰거나 src로 별도의 .js 파일을 연결합니다. 화면의 요소를 찾는 코드라면 HTML이 먼저 해석되도록, 본문 끝에 인라인 스크립트를 두거나 외부 스크립트에 defer를 사용하세요.

HTML 안에 직접 작성하기

한 페이지에서만 쓰는 짧은 코드는 <script>와 </script> 사이에 적을 수 있습니다. 아래 전체 예제를 UTF-8의 inline.html로 저장해 브라우저에서 여세요. 버튼을 누르면 문구가 바뀌며, 버튼을 누르기 전에는 기존 문구가 그대로 보입니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>HTML 안에 JavaScript 쓰기</title>
</head>
<body>
<h1>스크립트 연결 확인</h1>
<p id="message">버튼을 눌러 주세요.</p>
<button id="change" type="button">문구 바꾸기</button>
<script>
const button = document.querySelector('#change');
const message = document.querySelector('#message');
button.addEventListener('click', () => {
  message.textContent = '버튼을 눌러 문구를 바꿨습니다.';
});
</script>
</body>
</html>

예제는 버튼과 문단이 만들어진 뒤, 닫는 </body> 앞에서 스크립트를 실행합니다. 따라서 document.querySelector()가 두 요소를 찾을 수 있습니다. 같은 코드를 <head>에 일반 인라인 스크립트로 옮기면 그 시점에는 버튼이 아직 만들어지지 않아 이벤트 연결이 실패할 수 있습니다. 인라인 스크립트에 defer만 붙여도 이 문제는 해결되지 않습니다.

별도의 JavaScript 파일 연결하기

여러 페이지에서 코드를 공유하거나 HTML과 동작 코드를 분리하려면 index.html과 app.js를 같은 폴더에 만듭니다. HTML의 <head>에서 src="app.js"를 지정하고 defer를 붙이면, 브라우저는 HTML 해석과 함께 파일을 가져오되 문서 해석이 끝난 다음 실행합니다.

index.html 파일 전체 내용:

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>외부 JavaScript 연결하기</title>
  <script src="app.js" defer></script>
</head>
<body>
  <h1>스크립트 연결 확인</h1>
  <p id="message">버튼을 눌러 주세요.</p>
  <button id="change" type="button">문구 바꾸기</button>
</body>
</html>

같은 폴더의 app.js 파일 전체 내용:

const button = document.querySelector('#change');
const message = document.querySelector('#message');
button.addEventListener('click', () => {
  message.textContent = '버튼을 눌러 문구를 바꿨습니다.';
});

두 파일을 저장한 뒤 index.html을 열어 버튼을 누릅니다. 인라인 예제와 똑같이 문구가 바뀌어야 합니다. 파일이 js/app.js에 있다면 src="js/app.js"처럼 HTML 파일을 기준으로 상대 경로를 바꿉니다. .js 파일 안에는 <script> 태그를 쓰지 않습니다.

defer와 async를 구분하기

연결 방식 실행 시점 적합한 경우
본문 끝 인라인 <script> 앞에 나온 HTML을 해석한 직후 한 페이지의 짧은 동작
외부 <script src="app.js" defer> 문서 해석 뒤, 스크립트 순서를 보존 DOM이나 다른 스크립트에 의존하는 코드
외부 <script src="app.js" async> 다운로드가 끝나는 대로 실행 다른 코드·DOM의 순서에 의존하지 않는 코드

defer는 src가 있는 일반 스크립트에서 동작하며, 여러 파일을 적은 순서대로 실행합니다. async는 다운로드가 끝나는 시점에 실행하므로 서로의 순서를 기대하면 안 됩니다. type="module"인 스크립트는 기본적으로 문서 해석 뒤 실행되지만 파일 불러오기와 범위 규칙이 다릅니다. 이 글의 예제는 일반 스크립트입니다. 기준은 MDN의 script 요소 문서를 참고하세요.

동작하지 않을 때 확인할 점

  1. 브라우저에서 개발자 도구의 콘솔을 열어 문법 오류나 null 관련 오류를 확인합니다. null이 나오면 선택자가 HTML의 id와 일치하는지, 실행 시점에 요소가 이미 있는지 검사하세요.
  2. 외부 파일을 쓴다면 개발자 도구의 네트워크 탭에서 app.js 요청이 성공했는지 확인합니다. 404라면 HTML 파일 위치를 기준으로 src 경로와 실제 파일 이름의 대소문자를 맞춥니다.
  3. 파일 경로와 코드가 맞다면 브라우저를 새로고침합니다. 기존 파일이 남아 보이면 캐시를 우회해 다시 확인하세요. 사이트의 콘텐츠 보안 정책이 인라인 코드를 막는 경우에는 해당 정책에 맞게 외부 파일을 연결해야 합니다.

확인 후에는 예제 버튼을 다시 눌러 문구가 바뀌는지 살펴보세요. MDN의 JavaScript 추가 안내에도 인라인 코드와 외부 파일을 연결하는 기본 흐름이 정리되어 있습니다.