한눈에 보기: 워드프레스 JavaScript는 블록 에디터(Gutenberg)와 사용자 인터랙션의 중심입니다. ES6(let/const, 화살표 함수, 모듈), DOM·이벤트(버블링/위임), Fetch/async·await로 REST API를 연동하고, wp.data·wp.element 기반의 에디터 확장을 이해하면 커스텀 블록·사이드바·툴바 버튼까지 확장할 수 있습니다. 서버 권한·Nonce는 PHP와 워드프레스 글의 보안 루틴과 함께 설계하세요.
1. ES6 핵심 문법: let/const, 화살표 함수, 모듈
ES6는 변수 스코프와 함수 표현을 명확하게 해 줍니다. var
대신 let
/const
를 기본으로 사용하면 호이스팅·재할당 문제를 피할 수 있습니다. 화살표 함수는 간결한 문법과 this
바인딩 일관성을 제공합니다.
워드프레스 프런트/에디터 스크립트는 모듈 번들러(예: webpack, Vite)로 ES 모듈을 하나의 번들로 묶어 로드하는 것이 일반적입니다. 에디터 환경에서는 @wordpress/*
패키지를 import하여 코어 API를 사용합니다.
예시: ES6 문법 스니펫입니다.
const state = { count: 0 };
const inc = (n = 1) => ({ ...state, count: state.count + n });
export default inc;
테마/플러그인에선 wp_enqueue_script()
로 번들된 파일을 등록하고, 의존성 배열에 코어 핸들(wp-element
, wp-data
등)을 명시합니다.
<?php
add_action('enqueue_block_editor_assets', function () {
wp_enqueue_script(
'my-editor-js',
get_theme_file_uri('/assets/editor.bundle.js'),
['wp-element','wp-data','wp-edit-post','wp-plugins'],
null,
true
);
});
핵심 요약: let/const + 화살표 함수 + 모듈 번들 조합이 현대 워드프레스 JS의 기본입니다.
2. DOM·이벤트: 버블링·위임과 실전 패턴
브라우저 이벤트는 하위 → 상위로 버블링됩니다. 목록·카드 같은 반복 요소에서는 이벤트 위임이 성능과 유지보수에 유리합니다. 상위 컨테이너에 단 한 번 리스너를 등록해 하위 타겟을 분기합니다.
아래 예시는 좋아요 버튼을 위임으로 처리하는 패턴입니다.
document.addEventListener('click', (e) => {
const btn = e.target.closest('[data-like]');
if (!btn) return;
const id = btn.dataset.like;
btn.classList.toggle('is-active');
// 후속: fetch로 서버 반영
});
에디터 내부에서도 유사하게 동작하지만, 블록 UI는 React 기반이므로 가능하면 wp.element
(=React) 이벤트 모델을 선호하세요.
핵심 요약: 반복 요소엔 위임, 복잡 UI엔 React 이벤트가 안정적입니다.
3. Fetch/비동기: async/await, REST API 연동
워드프레스 REST API는 데이터 CRUD의 표준 인터페이스입니다. 인증은 관리자/로그인 세션에서 Nonce(쿠키 기반)가 기본이며, 외부 앱은 OAuth/앱 비밀키 등 별도 인증이 필요합니다.
예시: 게시글 목록을 가져오는 최소 패턴입니다.
async function getPosts() {
const res = await fetch('/wp-json/wp/v2/posts?per_page=5', {
headers: { 'X-WP-Nonce': window.wpApiSettings?.nonce }
});
if (!res.ok) throw new Error('Network error');
return await res.json();
}
getPosts().then(console.log).catch(console.error);
폼 전송은 FormData
·URLSearchParams
로 간결하게 처리하세요. 파일 업로드나 대량 데이터는 큐/스피너/재시도 전략을 포함하면 UX가 좋아집니다.
핵심 요약: async/await + Nonce 헤더가 안전한 기본값입니다.
4. Gutenberg와 JS: 스크립트 등록·wp.data 개념
블록 에디터는 React/Redux 스타일의 상태 관리(wp.data
)를 사용합니다. 현재 포스트, 선택된 블록, 설정 패널 상태 등은 select
/dispatch
로 읽고 갱신합니다.
예시: 현재 포스트 제목 읽기.
const { select } = wp.data;
const title = select('core/editor').getEditedPostAttribute('title');
console.log('Title:', title);
에디터 스크립트는 enqueue_block_editor_assets
에서 등록하고, 코어 핸들을 의존성으로 지정합니다(1번 섹션 코드 참고). 프런트 전용 상호작용은 wp_enqueue_scripts
훅에서 별도 번들을 등록하세요.
핵심 요약: 에디터 상태는 wp.data로 읽고, UI는 wp.element로 구성합니다.
5. 에디터 확장 스니펫: 사이드바·툴바 버튼
간단한 예로 포스트 편집 화면에 커스텀 사이드바 패널을 추가해 보겠습니다. wp.plugins.registerPlugin
으로 플러그인을 등록하고, PluginDocumentSettingPanel
로 설정 패널을 추가합니다.
const { registerPlugin } = wp.plugins;
const { PluginDocumentSettingPanel } = wp.editPost;
const { createElement: el, useState } = wp.element;
function MyPanel() {
const [note, setNote] = useState('');
return el(PluginDocumentSettingPanel, { name: 'my-panel', title: '메모' },
el('input', {
value: note,
onChange: (e) => setNote(e.target.value),
placeholder: '게시글 메모...'
})
);
}
registerPlugin('my-doc-panel', { render: MyPanel });
툴바 버튼도 유사하게 @wordpress/rich-text
또는 @wordpress/block-editor
컴포넌트를 조합해 구현합니다. 실제 저장은 메타 필드/포스트 속성과 연동해야 하므로 PHP 측 register_post_meta
로 스키마를 먼저 선언하세요.
핵심 요약: registerPlugin + Panel 컴포넌트로 에디터 UI를 빠르게 확장할 수 있습니다.
6. 보안·권한: Nonce로 안전한 AJAX/REST
사용자 입력이 서버에 도달하면 Nonce 검증과 권한 확인이 필요합니다. JS에서는 헤더로 Nonce를 보내고, PHP에서는 wp_verify_nonce()
로 확인합니다. 권한은 current_user_can()
으로 점검하세요.
<?php
add_action('wp_enqueue_scripts', function(){
wp_enqueue_script('my-ajax', get_theme_file_uri('/assets/app.bundle.js'), [], null, true);
wp_localize_script('my-ajax', 'MyApp', [
'nonce' => wp_create_nonce('my_action'),
'rest' => rest_url('my/v1/note')
]);
});
async function saveNote(text){
const res = await fetch(MyApp.rest, {
method: 'POST',
headers: {
'X-WP-Nonce': MyApp.nonce,
'Content-Type': 'application/json'
},
body: JSON.stringify({ text })
});
if (!res.ok) throw new Error('권한 또는 Nonce 오류');
return await res.json();
}
핵심 요약: Nonce → 권한 → 정화/검증 순서가 서버 왕복의 안전 기본기입니다.
7. 성능·번들링: npm·코드 스플리팅·디버깅
번들 크기는 인터랙션 성능과 직결됩니다. 에디터 전용·프런트 전용 번들을 분리하고, 필요 시 dynamic import로 지연 로딩하세요. 개발 모드에서는 소스맵을 켜고, 프로덕션에서는 미니파이·트리쉐이킹을 활성화합니다.
워드프레스 코어 제공 스크립트 핸들을 중복 번들하지 않도록 주의하세요. 예: React는 wp-element
로 제공되므로 외부 번들로 포함하면 중복입니다.
// 필요할 때만 모듈 로드
document.querySelector('[data-chart]')?.addEventListener('click', async () => {
const { renderChart } = await import('./charts.js');
renderChart();
});
핵심 요약: 분리·지연·중복 제거가 JS 성능 최적화의 3축입니다.
8. FAQ
Q. jQuery를 꼭 써야 하나요?
아니요. 워드프레스 최신 흐름은 ES6 + Fetch + 코어 JS 패키지입니다. 레거시 테마 유지보수라면 jQuery를 쓸 수 있지만, 신규 개발은 바닐라/React 권장입니다.
Q. 에디터와 프런트가 다르게 보입니다.
에디터 전용 스타일/스크립트를 등록하고 전역 토큰(theme.json)을 공유하세요. CSS 글의 컨테이너/align 규칙을 적용하면 차이가 줄어듭니다.
Q. REST 호출이 401/403을 반환합니다.
Nonce 누락/만료, 권한 부족이 원인입니다. wp_localize_script()
로 Nonce를 주입했고, 서버에서 wp_verify_nonce()
와 current_user_can()
을 수행하는지 확인하세요.
Q. React를 어디까지 써야 하나요?
에디터 UI·블록 개발은 React 필수입니다. 프런트 인터랙션은 규모/성격에 따라 바닐라 + Web Components나 React 중 선택하세요. 블록 개발은 React로 Gutenberg 블록 개발 글에서 이어집니다.
핵심 요약: 댓글로 올 질문을 본문/FAQ에 선제 반영해 자가 해결이 가능하도록 구성했습니다.
9. 이 글의 범위와 문의 안내
이 글은 워드프레스 JavaScript/ES6와 에디터 확장에 초점을 둡니다. 특정 사이트의 개별 오류나 플러그인 충돌 등 1:1 디버깅은 범위에 포함되지 않습니다. 이슈 발생 시 기본 테마 전환 → 플러그인 단계적 비활성화 → 콘솔/네트워크 확인 순서로 점검하세요.
심화는 REST API & JSON, Gutenberg React 블록, Hooks 완전정복에서 이어집니다.
핵심 요약: 본문과 연결 글만으로 자가 해결이 가능하도록 설계했으며, 개별 디버깅은 범위를 벗어납니다.
10. 출처
👉 다음 단계 학습 가이드
- 블록 개발: JS를 활용한 블록 제작은 「React와 Gutenberg 블록 개발: 커스텀 블록 제작과 UI 확장」로 이어집니다.
- 외부 연동: 비동기 통신은 「워드프레스 REST API & JSON: 외부 연동과 헤드리스 기초」에서 확인하세요.