[번역] 30일간 프레임워크를 끊었더니, 비로소 JavaScript가 보이기 시작했습니다
Soshy·

원문: I Stopped Using Frameworks for 30 Days — And My JavaScript Skills Finally Clicked
3년간 React 개발을 해왔지만, JavaScript 클로저가 실제로 어떻게 동작하는지 설명하지 못했습니다.
훅을 사용하는 방법은 알았습니다.
전역 상태를 관리하는 방법도 알았습니다.
프로덕션 기능을 배포하는 방법도 알았습니다.
그런데 클로저나 이벤트 루프 내부에서 실제로 무슨 일이 일어나는지 물어보면… 말문이 막혔습니다.
그래서 어느 주말, 저는 과감한 결정을 내렸습니다.
node_modules 폴더를 삭제하고, 순수 JavaScript로 포트폴리오 사이트를 다시 만들기 시작했습니다.
React도 없이.
Vue도 없이.
어떤 프레임워크도 없이.
그리고 2주 만에, 신기한 일이 일어났습니다.
JavaScript가 마침내 이해되기 시작했습니다.
JavaScript를 이해하지 못하고 있었다는 걸 깨달은 순간
프레임워크는 놀라운 생산성 도구입니다.
하지만 동시에, 매우 편안한 추상화 계층이 되기도 합니다.
수년간 저의 개발 프로세스는 이런 모습이었습니다.
npx create-react-app
npm install
import useState
import useEffect
그다음 모든 것이 작동할 때까지 기능을 만들어 나갔습니다.
그러던 중 기술 면접에서 이런 질문을 받았습니다.
"클로저가 무엇인지, 그리고 React 훅이 왜 클로저에 의존하는지 설명해 주실 수 있나요?"
머릿속이 하얘졌습니다.
훅을 어떻게 쓰는지는 알았지만, 왜 동작하는지는 몰랐습니다.
그 순간, 불편한 진실을 깨달았습니다.
저는 React는 배웠지만… JavaScript는 배우지 않았던 것입니다.
그리고 이 공백을 한번 인식하고 나면, 더 이상 외면할 수 없게 됩니다.
프레임워크의 착각
프레임워크는 실제 문제를 해결해 줍니다.
하지만 동시에 중요한 동작 원리를 숨기기도 합니다.
항상 추상화 안에서만 작업하다 보면, 그 아래에서 무슨 일이 일어나는지 놓치기 쉽습니다.
예를 들어, DOM 업데이트처럼 단순한 것을 생각해 봅시다.
React에서는 너무 쉽습니다.
setCount(count + 1)
React가 마법처럼 UI를 업데이트해 줍니다.
하지만 실제로는 어떤 일이 일어나는 걸까요?
순수 JavaScript로 다시 구현하면서, 모든 것을 직접 처리해야 했습니다.
let count = 0;
const button = document.querySelector("#increment");
const display = document.querySelector("#count");
button.addEventListener("click", () => {
count++;
display.textContent = count; // DOM 직접 업데이트
});
이 작은 예제 하나가 기본기를 직면하게 만들었습니다.
- DOM 선택
- 이벤트 리스너
- 상태 관리
- 렌더링 로직
프레임워크는 이 과정들을 자동화해 줍니다.
하지만 이것들을 직접 이해하면, 프레임워크 안에서 코드를 작성하는 방식 자체가 바뀝니다.
추상화는 그 안에 무엇이 숨겨져 있는지 이해할 때 비로소 강력해집니다.
순수 JavaScript로 포트폴리오 다시 만들기
저는 단순한 규칙 하나로 시작했습니다.
순수 JavaScript로 할 수 있다면, 그렇게 한다.
즉, 프레임워크의 일반적인 기능들을 직접 구현한다는 의미였습니다.
상태 관리
React 상태 대신:
const [count, setCount] = useState(0);
단순한 상태 객체를 사용했습니다.
const state = {
count: 0
};
function render() {
document.querySelector("#count").textContent = state.count;
}
document.querySelector("#increment").addEventListener("click", () => {
state.count++;
render(); // 수동 리렌더링
});
그 순간, 중요한 사실을 깨달았습니다.
상태란 데이터 + 렌더 함수일 뿐이라는 것입니다.
프레임워크가 내부적으로 하는 일이 바로 그것입니다.
그리고 이것을 깨닫는 순간, 생각보다 훨씬 큰 자신감이 생겼습니다.
클로저 이해하기 (수년간 외면해온 것)
클로저는 늘 마법처럼 느껴졌습니다.
그런데 프레임워크를 사용하지 않으면서, 클로저를 필요로 하는 패턴을 직접 작성하기 시작했습니다.
간단한 예시입니다.
function createCounter() {
let count = 0;
return function () {
count++;
console.log(count);
};
}
const counter = createCounter();
counter(); // 1
counter(); // 2
여기서 무슨 일이 일어나는 걸까요?
createCounter가 실행을 마친 이후에도, 내부 함수가 변수 count를 기억하고 있습니다.
이것이 클로저입니다.
React 같은 프레임워크는 클로저에 크게 의존합니다.
훅은 함수가 자신의 렉시컬 스코프에 있는 변수에 계속 접근할 수 있기 때문에 동작합니다.
클로저를 제대로 이해하고 나자, 훅이 마법이 아닌 당연한 것으로 보이기 시작했습니다.
클로저는 고급 JavaScript가 아닙니다. 바로 기초입니다.
드디어 이해된 이벤트 루프
이번 실험에서 또 하나 명확해진 것은 JavaScript 이벤트 루프였습니다.
프레임워크는 이것을 가려줍니다.
하지만 비동기 코드를 직접 작성하기 시작하면, 어디서든 이벤트 루프를 마주치게 됩니다.
예시:
console.log("Start");
setTimeout(() => {
console.log("Timeout");
}, 0);
Promise.resolve().then(() => {
console.log("Promise");
});
console.log("End");
출력:
Start
End
Promise
Timeout
왜 이런 순서일까요?
- 동기 코드가 먼저 실행됩니다
- 마이크로태스크(
Promise)가 다음으로 실행됩니다 - 매크로태스크(
setTimeout)가 마지막에 실행됩니다
이것을 이해하면 수많은 이상한 버그들이 설명됩니다.
이벤트 루프를 모르면, 비동기 코드가 무작위로 동작하는 것처럼 느껴집니다.
이것이 이해된 순간부터, 디버깅이 훨씬 수월해졌습니다.
프레임워크 vs 순수 JavaScript
이번 실험은 프레임워크를 바라보는 시각 자체를 바꿔주었습니다.
더 나쁘게 본 게 아닙니다.
그냥, 다르게 보게 되었습니다.
프레임워크가 최적화하는 것들
- 개발 속도
- 컴포넌트 구조
- 상태 동기화
- 대규모 애플리케이션
순수 JavaScript가 최적화하는 것들
- 깊은 이해
- 성능 인식
- 단순한 멘탈 모델
- 완전한 제어
핵심 깨달음은 이것입니다.
프레임워크는 도구이지, 기반이 아닙니다.
기반을 먼저 배우면, 모든 것이 달라집니다.
개발자들이 흔히 저지르는 실수들
이 과정을 겪으면서, 개발자들의 성장을 막는 몇 가지 패턴을 발견했습니다.
1. JavaScript보다 프레임워크를 먼저 배우는 것
많은 개발자들이 React나 Vue로 바로 뛰어듭니다.
하지만 프레임워크는 이미 이것들을 이해하고 있다고 가정합니다.
- 클로저
- 비동기 동작
- 스코프
- DOM
기본기를 건너뛰면, 지식이 불안정해집니다.
2. 복사-붙여넣기 개발
누구나 해본 적 있을 겁니다.
Stack Overflow에서 답변을 찾고 → 붙여넣고 → 작동하면 → 넘어가는 방식.
하지만 동작 원리를 이해하지 못한 채로는, 지식 부채가 쌓일 뿐입니다.
결국 언젠가는 발목을 잡게 됩니다.
3. 단순한 문제를 과도하게 복잡하게 만드는 것
프레임워크는 아키텍처를 장려합니다.
하지만 모든 것에 이런 것들이 필요하지는 않습니다.
- 전역 상태
- 리듀서
- 복잡한 추상화
때로는 단순한 함수와 이벤트 리스너면 충분합니다.
4. 브라우저를 무시하는 것
프론트엔드 개발자들이 종종 간과하는 사실이 있습니다.
브라우저는 이미 강력한 API를 제공하고 있다는 것입니다.
예시:
fetchlocalStorageIntersectionObserverMutationObserver
라이브러리가 항상 필요하지는 않습니다.
JavaScript 실력을 키우기 위한 실전 팁
저와 같은 깨달음의 순간을 경험하고 싶다면, 다음 방법들을 시도해 보시길 권합니다.
1. 프레임워크 없이 프로젝트 하나 만들어보기
예시:
- 투두 앱
- 작은 게임
- 마크다운 에디터
- 블로그
사용 가능한 것만 쓰도록 제한해 보세요.
- HTML
- CSS
- JavaScript
프레임워크로 몇 달을 공부하는 것보다 2주 안에 더 많이 배우게 될 것입니다.
2. 프레임워크의 소스 코드 읽어보기
React는 오픈소스입니다.
Vue도 마찬가지입니다.
전부 이해할 필요는 없습니다.
하지만 일부를 읽는 것만으로도 놀라운 인사이트를 얻을 수 있습니다.
다음과 같은 패턴들이 눈에 들어오기 시작할 것입니다.
- 클로저
- 함수 합성
- 불변 상태
3. 브라우저 API 배우기
현대 브라우저는 매우 강력합니다.
다음을 집중적으로 익혀보세요.
- Fetch API
- Web Storage
- Web Components
- 이벤트 위임
이 도구들만으로도 많은 라이브러리가 필요 없어집니다.
4. 프레임워크의 간단한 기능들 직접 구현해보기
다음을 미니 버전으로 직접 구현해 보세요.
- 상태 관리
- 템플릿
- 반응형 업데이트
50줄짜리 미니 프레임워크 하나가, 어떤 튜토리얼보다 많은 것을 가르쳐 줄 것입니다.
5. DevTools를 파워 유저처럼 활용하기
Chrome DevTools는 그 자체로 초능력입니다.
다음 기능들을 익히세요.
- 브레이크포인트
- 콜 스택 검사
- 성능 프로파일링
디버깅 능력이야말로 좋은 개발자와 훌륭한 개발자를 가르는 기준입니다.
프레임워크로 돌아왔을 때 달라진 것들
한 달 후, 저는 React로 돌아왔습니다.
하지만 무언가가 달라져 있었습니다.
한때 불가사의하게 느껴지던 코드들이, 이제는 당연하게 보이기 시작했습니다.
훅? 클로저일 뿐입니다.
상태 업데이트? 데이터 + 렌더링일 뿐입니다.
이펙트? 라이프사이클 + 비동기 동작일 뿐입니다.
프레임워크가 더 이상 마법처럼 느껴지지 않았습니다.
예측 가능하게 느껴지기 시작했습니다.
그리고 예측 가능한 시스템은 디버깅하기가 훨씬 쉽습니다.
핵심 요약
- 프레임워크는 추상화이지, 기본기가 아닙니다. JavaScript를 먼저 배우세요.
- 클로저, 스코프, 이벤트 루프는 반드시 알아야 할 지식입니다.
- 프레임워크 없이 프로젝트 하나를 만드는 것이 학습을 극적으로 가속화합니다.
- DOM과 브라우저 API를 이해하면 진정한 능력이 생깁니다.
- 프레임워크 지식은 탄탄한 JavaScript 기초 위에 쌓일 때 비로소 강해집니다.
마지막으로
프레임워크를 영원히 포기할 필요는 없습니다.
프레임워크가 존재하는 데는 분명한 이유가 있습니다.
하지만 수년간 개발을 해왔는데도 JavaScript가 여전히 혼란스럽게 느껴진다면, 이 실험을 한번 해보시기를 권합니다.
프레임워크 없이 무언가를 만들어 보세요.
의존성도 없이.
스캐폴딩도 없이.
오직 당신과 언어만으로.
그 과정 어딘가에서…
JavaScript가 비로소 이해될 것입니다.