jQuery → 쇠퇴와 유산 — 아직도 인터넷의 77%에 깔려있는 좀비
jQuery → 쇠퇴와 유산 — 아직도 인터넷의 77%에 깔려있는 좀비
"jQuery는 죽었다고? 니가 오늘 방문한 웹사이트 10개 중 7개에 jQuery가 있음. 좀비도 이 정도면 대단한 거임."
jQuery를 묘지에 넣어야 하나 말아야 하나 고민 많이 했음.
왜냐하면 아직 안 죽었거든.
2024년 기준 전 세계 웹사이트의 약 77%가 jQuery를 사용 중임. WordPress 하나가 전체 웹의 43%를 차지하는데, WordPress에 jQuery가 기본 탑재됨.
근데 신규 프로젝트에서 jQuery를 쓰는 곳은 거의 없음. "아직 깔려 있지만 새로 설치하진 않는 것" — 이게 좀비의 정의 아님?
묘비명 (예정)
jQuery (2006 - ????) "여기 Write Less, Do More의 왕이 잠들... 지 않음. 아직 살아있음. 언제 죽을지 아무도 모름. 어쩌면 인터넷이 먼저 죽을 수도 있음."
jQuery가 해결한 문제: 브라우저 전쟁
jQuery를 이해하려면 2006년의 브라우저 상황을 알아야 함.
// 2006년, 브라우저별로 다른 코드를 써야 했음
// 이게 진짜 현실이었음 ㅋㅋ
// AJAX 요청 하나 보내려면:
function createXHR() {
if (typeof XMLHttpRequest !== 'undefined') {
// Firefox, Safari, Opera
return new XMLHttpRequest();
} else if (typeof ActiveXObject !== 'undefined') {
// Internet Explorer
try {
return new ActiveXObject('Msxml2.XMLHTTP.6.0');
} catch (e1) {
try {
return new ActiveXObject('Msxml2.XMLHTTP.3.0');
} catch (e2) {
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch (e3) {
throw new Error('AJAX 지원 안 함');
}
}
}
}
}
// 이벤트 리스너 추가하려면:
function addEvent(element, type, handler) {
if (element.addEventListener) {
// 표준 (Firefox, Safari, Opera)
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
// IE
element.attachEvent('on' + type, handler);
} else {
// 구형 브라우저
element['on' + type] = handler;
}
}
// CSS 스타일 가져오려면:
function getStyle(element, property) {
if (window.getComputedStyle) {
return window.getComputedStyle(element)[property];
} else if (element.currentStyle) {
// IE
return element.currentStyle[property];
}
}
// opacity 설정하려면:
function setOpacity(element, value) {
element.style.opacity = value; // 표준
element.style.filter = 'alpha(opacity=' + (value * 100) + ')'; // IE
}
2006년의 브라우저 점유율
- Internet Explorer 6: ~60% (CSS도 제대로 못 그림)
- Internet Explorer 7: ~15% (조금 나아졌지만 여전히 괴물)
- Firefox 2: ~15% (구원자처럼 보였음)
- Safari: ~5% (Mac 전용)
- Opera: ~2% (소수 정예)
IE6의 CSS 버그:
- 더블 마진 버그 (float 요소의 마진이 2배)
- PNG 투명도 미지원
- position: fixed 미지원
- min-height/max-height 미지원
- :hover가 a 태그에만 동작
프론트엔드 개발의 50%는 IE 버그 우회였음.
jQuery의 등장: Write Less, Do More
2006년 1월, John Resig이 jQuery를 발표함.
// jQuery 이전:
var elements = document.getElementsByClassName('item'); // IE는 지원 안 함
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = 'none';
elements[i].style.backgroundColor = 'red';
}
// jQuery 이후:
$('.item').hide().css('background-color', 'red');
// ㅋㅋㅋㅋ 이건 사기였음
jQuery의 킬러 피처들
// 1. CSS 선택자로 DOM 선택 (Sizzle 엔진)
// 브라우저가 지원 안 하는 CSS3 선택자도 다 됨!
$('#header') // ID 선택
$('.nav-item') // 클래스 선택
$('ul > li:first-child') // 자식 선택자
$('input[type="text"]') // 속성 선택자
$('tr:odd') // 홀수 행
$('div:has(p)') // p를 포함하는 div
$(':visible') // 보이는 요소만
$(':input') // 모든 입력 요소
// 2. 체이닝
$('#menu')
.find('.active')
.removeClass('active')
.end()
.find('.selected')
.addClass('active')
.css('color', 'red')
.slideDown(300);
// 한 줄에 여러 작업을 연결 — 코드가 물처럼 흐름
// 3. AJAX (크로스 브라우저 통합)
$.ajax({
url: '/api/users',
type: 'GET',
dataType: 'json',
success: function(data) {
// 성공
$.each(data, function(index, user) {
$('#user-list').append(
$('<li>').text(user.name)
);
});
},
error: function(xhr, status, error) {
// 실패
alert('에러: ' + error);
}
});
// 더 간단한 버전
$.get('/api/users', function(data) {
console.log(data);
});
$.post('/api/users', { name: 'Kim', age: 25 }, function(response) {
console.log('생성됨:', response);
});
// 4. 애니메이션
$('.box')
.animate({
left: '250px',
opacity: 0.5,
height: '150px',
width: '150px'
}, 1000, 'swing', function() {
// 완료 콜백
$(this).text('완료!');
});
// fadeIn, fadeOut, slideUp, slideDown — 내장 애니메이션
$('.notification').fadeIn(300).delay(2000).fadeOut(500);
// 5. 이벤트 위임
// DOM에 아직 없는 요소에도 이벤트 걸기
$(document).on('click', '.dynamic-button', function() {
// 나중에 추가된 .dynamic-button에도 동작!
// React의 이벤트 버블링과 같은 원리
});
jQuery의 API 디자인은 예술이었음
jQuery가 성공한 이유 중 하나는 API 디자인이 너무 좋았기 때문임.
$한 글자로 시작 (타이핑 최소화)- 메서드 이름이 직관적 (hide, show, fadeIn, slideUp)
- 체이닝으로 코드가 자연어처럼 읽힘
- getter/setter가 같은 메서드 (인자 유무로 구분)
- 에러가 나지 않고 조용히 무시 (빈 jQuery 객체에 메서드 호출해도 OK)
이 디자인 철학은 나중에 Lodash, D3.js 등 많은 라이브러리에 영향을 줌.
jQuery의 전성기
2010-2014년, jQuery는 프론트엔드의 표준이었음.
jQuery 플러그인 생태계
// jQuery 플러그인 만들기 — 표준 패턴
(function($) {
$.fn.tooltip = function(options) {
var settings = $.extend({
position: 'top',
delay: 200,
animation: true
}, options);
return this.each(function() {
var $el = $(this);
var $tip = $('<div class="tooltip">')
.text($el.attr('title'))
.appendTo('body');
$el.on('mouseenter', function() {
var pos = $el.offset();
$tip.css({
top: pos.top - $tip.outerHeight() - 10,
left: pos.left + ($el.outerWidth() - $tip.outerWidth()) / 2
});
if (settings.animation) {
$tip.fadeIn(settings.delay);
} else {
$tip.show();
}
});
$el.on('mouseleave', function() {
$tip.fadeOut(settings.delay);
});
});
};
})(jQuery);
// 사용
$('[title]').tooltip({ position: 'bottom', delay: 300 });
유명 jQuery 플러그인들:
이미지/미디어:
- jQuery Lightbox / Fancybox — 이미지 갤러리
- jQuery Cycle / Slick — 슬라이더/캐러셀
- jQuery File Upload — 파일 업로드
- Magnific Popup — 팝업/모달
UI:
- jQuery UI — 공식 UI 라이브러리 (Datepicker, Sortable, Draggable)
- Select2 — 검색 가능한 드롭다운
- DataTables — 테이블 정렬/필터/페이지네이션
- jQuery Validation — 폼 유효성 검사
레이아웃:
- Masonry — Pinterest 스타일 레이아웃
- Isotope — 필터링 + 정렬 레이아웃
기타:
- jQuery Migrate — 버전 호환성 레이어
- jQuery.scrollTo — 스크롤 제어
- jQuery Lazy Load — 이미지 지연 로딩
jQuery UI의 영향력
jQuery UI의 Datepicker, Autocomplete, Sortable, Draggable은 현대 UI 라이브러리(Radix UI, Headless UI 등)의 조상 격임. 접근성(a11y), 키보드 내비게이션, 포커스 관리 같은 개념을 jQuery UI가 처음 체계적으로 구현했음.
jQuery + Bootstrap = 웹 개발의 정석
<!-- 2012-2015년의 표준 웹 개발 스택 -->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">확인</h4>
</div>
<div class="modal-body">
<p>정말 삭제하시겠습니까?</p>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal">취소</button>
<button class="btn btn-danger" id="confirm-delete">삭제</button>
</div>
</div>
</div>
</div>
<script src="jquery.min.js"></script>
<script src="bootstrap.min.js"></script>
<script>
$('#confirm-delete').click(function() {
var itemId = $(this).data('item-id');
$.ajax({
url: '/api/items/' + itemId,
type: 'DELETE',
success: function() {
$('#item-' + itemId).fadeOut(300, function() {
$(this).remove();
});
$('#myModal').modal('hide');
}
});
});
</script>
</body>
</html>
이 조합이 2012-2015년 웹 개발의 "보일러플레이트"였음. 면접에서 "jQuery 할 줄 아시죠?" 하면 "당연하죠"가 정답이었던 시절.
jQuery의 쇠퇴: 네이티브 API의 역습
jQuery가 쇠퇴한 건 jQuery가 나빠져서가 아님. 브라우저가 좋아졌기 때문임.
jQuery가 했던 것들을 브라우저가 기본으로 하게 됨:
// ═══════════════════════════════════════════
// jQuery vs 네이티브 API 비교
// ═══════════════════════════════════════════
// --- DOM 선택 ---
// jQuery
$('.item')
$('#header')
$('ul > li:first-child')
// 네이티브 (IE8+)
document.querySelectorAll('.item')
document.querySelector('#header')
document.querySelector('ul > li:first-child')
// --- 클래스 조작 ---
// jQuery
$('.box').addClass('active').removeClass('hidden').toggleClass('open');
// 네이티브 (IE10+)
document.querySelector('.box').classList.add('active');
document.querySelector('.box').classList.remove('hidden');
document.querySelector('.box').classList.toggle('open');
// --- 이벤트 ---
// jQuery
$('#btn').on('click', function(e) { /* ... */ });
$(document).on('click', '.dynamic', function() { /* ... */ });
// 네이티브
document.querySelector('#btn').addEventListener('click', (e) => { /* ... */ });
// 이벤트 위임도 가능 (약간 더 복잡하지만)
document.addEventListener('click', (e) => {
if (e.target.matches('.dynamic')) { /* ... */ }
});
// --- AJAX ---
// jQuery
$.ajax({ url: '/api/data', type: 'GET', dataType: 'json' })
.done(function(data) { console.log(data); })
.fail(function(err) { console.error(err); });
// 네이티브 fetch (2015+)
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
// 또는 async/await (2017+)
const response = await fetch('/api/data');
const data = await response.json();
// --- 애니메이션 ---
// jQuery
$('.box').animate({ opacity: 0, left: '100px' }, 500);
// CSS Transition (2013+)
// .box { transition: opacity 0.5s, left 0.5s; }
// .box.hidden { opacity: 0; left: 100px; }
element.classList.add('hidden');
// Web Animations API (2016+)
element.animate([
{ opacity: 1, left: '0' },
{ opacity: 0, left: '100px' }
], { duration: 500 });
// --- 배열/객체 유틸리티 ---
// jQuery
$.each(array, function(i, item) { /* ... */ });
$.map(array, function(item) { return item * 2; });
$.grep(array, function(item) { return item > 5; });
$.extend({}, defaults, options);
// 네이티브 ES5+ (2009+)
array.forEach((item, i) => { /* ... */ });
array.map(item => item * 2);
array.filter(item => item > 5);
Object.assign({}, defaults, options); // 또는 { ...defaults, ...options }
jQuery의 존재 이유가 사라짐
jQuery는 브라우저간 차이를 메우는 접착제였음. 브라우저들이 표준을 잘 구현하면서 접착제가 필요 없어짐.
특히 IE가 사라진 게 결정적이었음:
- IE11 지원 종료 (2022년 6월)
- Edge가 Chromium 기반으로 전환 (2020년)
IE가 죽으니 jQuery도 필요 없어짐. jQuery는 IE 때문에 태어나서 IE와 함께 은퇴하는 셈.
프론트엔드 프레임워크의 등장
jQuery의 쇠퇴에 프레임워크가 기여한 것도 큼:
// jQuery 방식: 명령형 (Imperative)
// "이렇게 해라" 를 하나하나 지시
function addUser(user) {
var $row = $('<tr>')
.attr('data-id', user.id)
.append($('<td>').text(user.name))
.append($('<td>').text(user.email))
.append(
$('<td>').append(
$('<button>')
.text('삭제')
.addClass('btn btn-danger btn-sm')
.click(function() {
deleteUser(user.id);
})
)
);
$('#user-table tbody').append($row);
updateUserCount();
}
function deleteUser(id) {
$.ajax({
url: '/api/users/' + id,
type: 'DELETE',
success: function() {
$('[data-id="' + id + '"]').fadeOut(300, function() {
$(this).remove();
updateUserCount();
});
}
});
}
function updateUserCount() {
var count = $('#user-table tbody tr:visible').length;
$('#user-count').text(count + '명');
}
// 문제: 앱이 커지면 상태 관리가 불가능해짐
// - 데이터가 어디에 있는지 추적이 안 됨 (DOM에? 변수에? 서버에?)
// - UI 업데이트를 까먹으면 버그
// - 코드가 스파게티가 됨
// React 방식: 선언형 (Declarative)
// "이런 상태면 이렇게 보여라"
function UserTable() {
const [users, setUsers] = useState<User[]>([]);
const deleteUser = async (id: number) => {
await fetch(`/api/users/${id}`, { method: 'DELETE' });
setUsers(prev => prev.filter(u => u.id !== id));
// UI는 알아서 업데이트됨. 까먹을 수가 없음.
};
return (
<>
<p>{users.length}명</p>
<table>
<tbody>
{users.map(user => (
<tr key={user.id}>
<td>{user.name}</td>
<td>{user.email}</td>
<td>
<button onClick={() => deleteUser(user.id)}>
삭제
</button>
</td>
</tr>
))}
</tbody>
</table>
</>
);
}
패러다임의 전환
jQuery에서 React로의 전환은 단순한 "라이브러리 교체"가 아니었음. 명령형에서 선언형이라는 패러다임 전환이었음.
- jQuery: "DOM 노드를 만들어서 여기에 붙여라"
- React: "이 상태일 때 UI는 이렇게 생겼다"
이건 SQL과 비슷함:
- 명령형: "파일 열어서, 한 줄씩 읽어서, 조건 맞으면 결과에 넣어라"
- 선언형: "SELECT * FROM users WHERE age > 20"
선언형이 더 추상화 수준이 높고, 버그가 적음.
jQuery가 아직 필요한 곳들
jQuery가 "쇠퇴"했다고 했지 "죽었다"고는 안 했음. 아직 jQuery가 합리적인 선택인 경우가 있음:
// 1. WordPress 테마/플러그인 개발
// WordPress에 jQuery가 기본 탑재되어 있음
// 안 쓰는 게 오히려 비효율적
jQuery(document).ready(function($) {
// WordPress의 jQuery는 noConflict 모드
// $ 대신 jQuery를 쓰거나, 이렇게 래핑
$('.wp-block-gallery').slick({
dots: true,
autoplay: true
});
});
// 2. 간단한 정적 사이트에 인터랙션 추가
// React 세팅하기엔 과하고, 바닐라 JS로 하기엔 귀찮을 때
// CDN 한 줄이면 되니까
// 3. 레거시 시스템 유지보수
// 이미 jQuery로 만들어진 시스템을 굳이 React로 바꿀 이유가 없을 때
// "If it ain't broke, don't fix it"
// 4. jQuery 의존 라이브러리
// DataTables, Select2 같은 라이브러리가 아직 jQuery 의존
// 이것들의 대안이 있긴 하지만 기능 면에서 아직 안 따라가는 경우도 있음
jQuery 남용 경고
그렇다고 신규 프로젝트에 jQuery를 쓰라는 건 아님.
jQuery를 써야 할 때:
- WordPress 관련 작업
- 아주 간단한 인터랙션만 필요한 정적 사이트
- 이미 jQuery로 된 프로젝트 유지보수
jQuery를 쓰면 안 될 때:
- SPA (Single Page Application)
- 복잡한 상태 관리가 필요한 앱
- 팀이 React/Vue/Angular를 알고 있을 때
- 새로 시작하는 프로젝트 대부분
jQuery 없이 살기: You Might Not Need jQuery
// "You Might Not Need jQuery" — 이 사이트가 jQuery 쇠퇴를 가속화함
// youmightnotneedjquery.com
// ═══════════════════════════════════════════
// 자주 쓰는 패턴의 네이티브 대체
// ═══════════════════════════════════════════
// --- Document Ready ---
// jQuery
$(document).ready(function() { /* ... */ });
$(function() { /* ... */ });
// 네이티브
document.addEventListener('DOMContentLoaded', () => { /* ... */ });
// 또는 script를 body 끝에 놓으면 필요 없음
// 또는 script에 defer를 쓰면 필요 없음
// --- HTTP 요청 ---
// jQuery
$.getJSON('/api/users', function(users) { /* ... */ });
// 네이티브
const users = await fetch('/api/users').then(r => r.json());
// POST
// jQuery
$.post('/api/users', { name: 'Kim' }, function(res) { /* ... */ });
// 네이티브
const res = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Kim' })
}).then(r => r.json());
// --- DOM 생성 ---
// jQuery
$('<div>')
.addClass('card')
.attr('data-id', 123)
.text('카드 내용')
.appendTo('#container');
// 네이티브
const div = document.createElement('div');
div.classList.add('card');
div.dataset.id = '123';
div.textContent = '카드 내용';
document.querySelector('#container').append(div);
// --- 유틸리티 ---
// jQuery
$.isArray(x); // Array.isArray(x)
$.isFunction(x); // typeof x === 'function'
$.isNumeric(x); // !isNaN(parseFloat(x)) && isFinite(x)
$.trim(str); // str.trim()
$.parseJSON(str); // JSON.parse(str)
$.now(); // Date.now()
$.type(x); // typeof x (거의)
// 전부 네이티브로 대체 가능 ㅋㅋ
jQuery에서 태어난 현대 개념들
// 1. CSS 선택자 엔진 → querySelectorAll
// jQuery의 Sizzle 엔진이 너무 유용해서
// W3C가 Selectors API를 표준화함
// document.querySelectorAll()이 탄생한 이유
// 2. Promise 패턴 → ES6 Promise
// jQuery의 Deferred 객체
var deferred = $.Deferred();
deferred.promise()
.done(function(result) { /* 성공 */ })
.fail(function(error) { /* 실패 */ })
.always(function() { /* 항상 */ });
// → ES6 Promise
new Promise((resolve, reject) => { /* ... */ })
.then(result => { /* 성공 */ })
.catch(error => { /* 실패 */ })
.finally(() => { /* 항상 */ });
// 3. 체이닝 패턴 → 함수형 프로그래밍
// jQuery의 체이닝이 fluent interface 패턴을 대중화
$('.items')
.filter('.active')
.map(function() { return $(this).data('id'); })
.get();
// → 네이티브 배열 메서드 체이닝
[...document.querySelectorAll('.items')]
.filter(el => el.classList.contains('active'))
.map(el => el.dataset.id);
// 4. 이벤트 위임 → React의 이벤트 시스템
// jQuery가 처음 대중화한 이벤트 위임 패턴을
// React가 내부적으로 사용함 (루트에서 모든 이벤트 처리)
// 5. 플러그인 시스템 → npm 생태계
// $.fn.plugin = function() {} 패턴이
// npm 모듈 시스템의 문화적 선조
jQuery의 진짜 업적
jQuery는 단순한 라이브러리가 아니었음. 웹 개발 민주화의 도구였음.
jQuery 이전: 웹 개발 = IE 버그와 싸우는 전문가의 영역 jQuery 이후: 웹 개발 = 디자이너도 할 수 있는 것
jQuery가 있어서 수많은 비전공자가 웹 개발에 입문했고, 그 사람들이 지금 시니어 개발자가 되어 React, Vue를 쓰고 있음.
jQuery 4.0: 좀비의 반격?
// jQuery 4.0이 개발 중임 (2024년 기준)
// 주요 변경점:
// 1. IE 지원 완전 제거
// 이제 IE를 위한 코드가 전부 빠지니까 번들 사이즈가 작아짐
// 2. 최소 지원: ES2015+
// const, let, arrow functions, Promise 등 사용
// 3. 제거된 것들:
// - jQuery.type() → typeof + instanceof 사용
// - jQuery.isFunction() → typeof x === 'function'
// - jQuery.isWindow() → 제거
// - jQuery.camelCase() → 제거
// - 이벤트 alias (.click(), .focus() 등) → .on() 사용
// 4. FormData 지원 개선
$.ajax({
url: '/upload',
method: 'POST',
data: new FormData(document.querySelector('form')),
contentType: false,
processData: false
});
// 근데 솔직히...
// jQuery 4가 나와도 "우와 jQuery 4 쓰자!" 할 사람은 거의 없음 ㅋㅋ
Bootstrap 5의 배신
// Bootstrap 5 (2021) — jQuery 의존성 제거
// jQuery 최대의 동맹이 배신함
// Bootstrap 4: jQuery 필수
$('#myModal').modal('show');
$('[data-toggle="tooltip"]').tooltip();
// Bootstrap 5: 바닐라 JavaScript
const modal = new bootstrap.Modal(document.getElementById('myModal'));
modal.show();
const tooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]');
tooltips.forEach(el => new bootstrap.Tooltip(el));
// Bootstrap이 jQuery를 버린 이유:
// 1. 번들 사이즈 절감 (jQuery만 30KB gzipped)
// 2. React/Vue와의 호환성
// 3. 네이티브 API가 충분히 성숙
// 4. jQuery 의존 때문에 외면하는 개발자가 많아짐
jQuery를 버린 유명 프로젝트들
2018-2023년 사이 jQuery를 제거한 프로젝트들:
- GitHub (2018) — 자체 라이브러리로 대체
- Bootstrap 5 (2021) — 바닐라 JS로 전환
- WordPress (진행 중) — Gutenberg는 React 기반
- Gov.uk (2022) — 바닐라 JS로 전환
GitHub이 jQuery를 뺀 건 특히 상징적이었음. GitHub 엔지니어가 "어떻게 jQuery를 제거했나" 블로그를 올렸는데 해커뉴스에서 수천 업보트를 받음 ㅋㅋ
실무 마이그레이션: jQuery에서 벗어나기
// jQuery → 바닐라 JS 마이그레이션 실전 패턴
// 1단계: jQuery 사용 현황 파악
// package.json에서 jQuery 의존 플러그인 확인
// grep으로 $ 사용 현황 검색
// 2단계: 쉬운 것부터 교체
// $.ajax → fetch
// $.each → forEach
// $.extend → Object.assign / spread
// 3단계: DOM 조작 교체
// $() → querySelector/querySelectorAll
// .addClass/.removeClass → classList
// .attr() → getAttribute/setAttribute
// .css() → style 직접 조작
// 4단계: jQuery 플러그인 대체
// DataTables → AG Grid, TanStack Table
// Select2 → Choices.js, Tom Select
// jQuery Validation → native form validation + custom
// Slick → Swiper, Splide
// jQuery UI Datepicker → flatpickr, date-fns + custom
// 5단계: 이벤트 위임 패턴 교체
// $(document).on('click', '.selector', handler)
// → document.addEventListener + e.target.closest('.selector')
// 실전 유틸리티 함수 (jQuery 없이 사는 법)
function $(selector: string, context: Element | Document = document) {
return context.querySelector(selector);
}
function $$(selector: string, context: Element | Document = document) {
return [...context.querySelectorAll(selector)];
}
function on(
target: EventTarget,
event: string,
selector: string | null,
handler: (e: Event) => void
) {
if (selector) {
// 이벤트 위임
target.addEventListener(event, (e) => {
const el = (e.target as Element).closest(selector);
if (el) handler.call(el, e);
});
} else {
target.addEventListener(event, handler);
}
}
// jQuery스러운 사용법
on(document, 'click', '.delete-btn', function(e) {
const row = (e.target as Element).closest('tr');
row?.remove();
});
교훈
jQuery에서 배우는 것
1. 추상화 레이어의 가치 jQuery는 "브라우저 차이"라는 거대한 문제를 우아하게 추상화했음. 플랫폼의 결함을 라이브러리가 메울 수 있다는 걸 증명함. 근데 플랫폼이 개선되면 추상화 레이어는 필요 없어짐.
2. API 디자인의 중요성 jQuery의 인기는 성능이 아니라 DX(Developer Experience) 때문이었음. $, 체이닝, 직관적 메서드 이름, 관대한 에러 처리... 좋은 API는 기술 자체보다 중요할 수 있음.
3. 좀비가 되는 것도 유산임 jQuery는 "죽었는데 안 죽은" 상태로 남아있음. 이건 실패가 아니라 성공의 잔향임. 너무 많은 곳에서 쓰여서 제거하는 비용이 유지하는 비용보다 큰 거임.
4. 도구는 문제와 함께 사라짐 jQuery는 "IE 호환성"이라는 문제를 해결하기 위해 존재했음. IE가 사라지니 jQuery도 사라짐. 지금 쓰는 도구가 해결하는 문제가 뭔지 알면 언제 그 도구가 필요 없어질지 예측할 수 있음.
5. 진입 장벽 낮추기 = 생태계 확장 jQuery는 프로그래밍 초보자도 바로 쓸 수 있었음. 이 접근성이 거대한 플러그인 생태계를 만들었고, 웹 개발자 인구를 폭발적으로 늘렸음.
마무리
jQuery는 웹 개발의 민주화를 이끈 기술임.
IE 때문에 웹 개발이 고통스럽던 시절, jQuery가 그 고통을 대신 받아줬음. 덕분에 수백만 명이 웹 개발에 입문할 수 있었음.
지금은 쇠퇴하고 있지만, jQuery의 영향은 어디에나 있음:
document.querySelector()— jQuery의$()영향fetch()—$.ajax()영향- 배열 메서드 체이닝 — jQuery 체이닝 영향
- 컴포넌트 플러그인 생태계 — jQuery 플러그인 영향
jQuery는 죽지 않았음. 웹에 녹아들었을 뿐임.
╔════════════════════════════════════════════════════════════╗
║ ║
║ ⚘ jQuery — 아직 안 죽음 ⚘ ║
║ 2006 - 현재 (좀비 상태) ║
║ ║
║ "Write Less, Do More. ║
║ 브라우저가 내 일을 다 가져갔지만 ║
║ 77%의 웹사이트가 아직 날 기억하고 있음. ║
║ 아니 기억이 아니라 아직 깔려있는 거임." ║
║ ║
║ — $ 한 글자로 세상을 바꾼 라이브러리 ║
║ ║
╚════════════════════════════════════════════════════════════╝
다음 묘비는 CoffeeScript & Backbone.js임. ES6가 오기 전, JavaScript의 구세주를 자처한 기술들의 이야기.