[{"data":1,"prerenderedAt":684},["ShallowReactive",2],{"navigation_docs_ko":3,"-ko-note-tooling-package-manager-package-lock":195,"-ko-note-tooling-package-manager-package-lock-surround":679},[4,124,181],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":27},"Note (개발 지식)","emojione-v1:note-pad","\u002Fko\u002Fnote","ko\u002F1.note",[10,28,42,68,78,88,104,114],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":27},"Spring","logos:spring-icon","\u002Fko\u002Fnote\u002Fspring","ko\u002F1.note\u002F0.spring",[16],{"title":17,"icon":18,"path":19,"stem":20,"children":21,"page":27},"Spring Ai","custom:ai","\u002Fko\u002Fnote\u002Fspring\u002Fspring-ai","ko\u002F1.note\u002F0.spring\u002F1.spring-ai",[22],{"title":23,"path":24,"stem":25,"icon":26},"Spring AI 핵심 개념과 LLM 애플리케이션 구조 이해","\u002Fko\u002Fnote\u002Fspring\u002Fspring-ai\u002Fspring-ai","ko\u002F1.note\u002F0.spring\u002F1.spring-ai\u002F1.spring-ai","lucide:file-text",false,{"title":29,"icon":30,"path":31,"stem":32,"children":33,"page":27},"Javascript","skill-icons:javascript","\u002Fko\u002Fnote\u002Fjavascript","ko\u002F1.note\u002F1.javascript",[34,38],{"title":35,"path":36,"stem":37,"icon":26},"Promise.all과 구조 분해 할당을 활용한 데이터 처리 패턴","\u002Fko\u002Fnote\u002Fjavascript\u002Fdestructuring","ko\u002F1.note\u002F1.javascript\u002F1.destructuring",{"title":39,"path":40,"stem":41,"icon":26},"JavaScript 배열 고차 함수와 데이터 처리 패턴 이해","\u002Fko\u002Fnote\u002Fjavascript\u002Ffilter","ko\u002F1.note\u002F1.javascript\u002F2.filter",{"title":43,"icon":44,"path":45,"stem":46,"children":47,"page":27},"Nuxt4","logos:nuxt-icon","\u002Fko\u002Fnote\u002Fnuxt4","ko\u002F1.note\u002F2.nuxt4",[48,52,56,60,64],{"title":49,"path":50,"stem":51,"icon":26},"Nuxt 4를 선택한 이유와 아키텍처 및 실무 가이드","\u002Fko\u002Fnote\u002Fnuxt4\u002Fnuxt-info","ko\u002F1.note\u002F2.nuxt4\u002F1.nuxt-info",{"title":53,"path":54,"stem":55,"icon":26},"Nuxt useAsyncData 동작 원리와 SSR 데이터 페칭 최적화","\u002Fko\u002Fnote\u002Fnuxt4\u002Fnuxt-use_async_data","ko\u002F1.note\u002F2.nuxt4\u002F2.nuxt-use_async_data",{"title":57,"path":58,"stem":59,"icon":26},"Nuxt Content v3 데이터 모델과 Query 시스템 이해","\u002Fko\u002Fnote\u002Fnuxt4\u002Fnuxt-content-v3","ko\u002F1.note\u002F2.nuxt4\u002F3.nuxt-content-v3",{"title":61,"path":62,"stem":63,"icon":26},"Nuxt Auto-imports 내부 동작과 컴파일 과정 분석","\u002Fko\u002Fnote\u002Fnuxt4\u002Fnuxt-auto-import","ko\u002F1.note\u002F2.nuxt4\u002F4.nuxt-auto-import",{"title":65,"path":66,"stem":67,"icon":26},"Nuxt 렌더링 방식 이해: SSR, SSG, ISR, CSR 구현 방법","\u002Fko\u002Fnote\u002Fnuxt4\u002Fnuxt-rendering-strategy","ko\u002F1.note\u002F2.nuxt4\u002F5.nuxt-rendering-strategy",{"title":69,"icon":70,"path":71,"stem":72,"children":73,"page":27},"Nitro","unjs:nitro","\u002Fko\u002Fnote\u002Fnitro","ko\u002F1.note\u002F3.nitro",[74],{"title":75,"path":76,"stem":77,"icon":26},"Nitro 아키텍처와 서버 엔진 구조","\u002Fko\u002Fnote\u002Fnitro\u002Fnitro","ko\u002F1.note\u002F3.nitro\u002Fnitro",{"title":79,"icon":80,"path":81,"stem":82,"children":83,"page":27},"Devops","vscode-icons:file-type-pipeline","\u002Fko\u002Fnote\u002Fdevops","ko\u002F1.note\u002F4.devops",[84],{"title":85,"path":86,"stem":87,"icon":26},"서버사이드 WebAssembly(Wasm)와 차세대 실행 환경","\u002Fko\u002Fnote\u002Fdevops\u002Fwebassembly","ko\u002F1.note\u002F4.devops\u002F1.webAssembly",{"title":89,"icon":90,"path":91,"stem":92,"children":93,"page":27},"Tooling","lucide:wrench","\u002Fko\u002Fnote\u002Ftooling","ko\u002F1.note\u002F4.tooling",[94],{"title":95,"icon":96,"path":97,"stem":98,"children":99,"page":27},"Package Manager","devicon:npm","\u002Fko\u002Fnote\u002Ftooling\u002Fpackage-manager","ko\u002F1.note\u002F4.tooling\u002F1.package-manager",[100],{"title":101,"path":102,"stem":103,"icon":26},"Package Lock 파일의 역할과 의존성 관리 원리","\u002Fko\u002Fnote\u002Ftooling\u002Fpackage-manager\u002Fpackage-lock","ko\u002F1.note\u002F4.tooling\u002F1.package-manager\u002F1.package-lock",{"title":105,"icon":106,"path":107,"stem":108,"children":109,"page":27},"Web","streamline-plump:web","\u002Fko\u002Fnote\u002Fweb","ko\u002F1.note\u002F4.web",[110],{"title":111,"path":112,"stem":113,"icon":26},"웹 애플리케이션 렌더링 아키텍처 이해","\u002Fko\u002Fnote\u002Fweb\u002Frendering-modes","ko\u002F1.note\u002F4.web\u002F2.rendering-modes",{"title":115,"icon":116,"path":117,"stem":118,"children":119,"page":27},"SEO","icon-park-solid:seo","\u002Fko\u002Fnote\u002Fseo","ko\u002F1.note\u002F6.seo",[120],{"title":121,"path":122,"stem":123,"icon":26},"[SEO] 개발 블로그 검색 노출을 위한 robots.txt와 SEO 설정 가이드","\u002Fko\u002Fnote\u002Fseo\u002Fseo","ko\u002F1.note\u002F6.seo\u002F1.seo",{"title":125,"icon":126,"path":127,"stem":128,"children":129,"page":27},"Project (개발일지)","icon-park-solid:branch-two","\u002Fko\u002Fproject","ko\u002F2.project",[130],{"title":131,"icon":132,"path":133,"stem":134,"children":135,"page":27},"Brolog","custom:symbol","\u002Fko\u002Fproject\u002Fbrolog","ko\u002F2.project\u002F1.brolog",[136,140,144,148,152,156,160,164,168,173,177],{"title":137,"path":138,"stem":139,"icon":26},"Brolog 프로젝트 개요","\u002Fko\u002Fproject\u002Fbrolog\u002Foutline","ko\u002F2.project\u002F1.brolog\u002F1.outline",{"title":141,"path":142,"stem":143,"icon":26},"[Brolog] Nuxt Multi Layer 프로젝트 Vercel 배포 (3) - Runtime 기능 문제 분석과 AI Assistant 전환","\u002Fko\u002Fproject\u002Fbrolog\u002Fvercel-deploy3-ai-integration","ko\u002F2.project\u002F1.brolog\u002F10.vercel-deploy3-ai-integration",{"title":145,"path":146,"stem":147,"icon":26},"[Brolog] AI Assistant 적용 과정 - Agent 구조와 API 사용량 관리 시 고려사항","\u002Fko\u002Fproject\u002Fbrolog\u002Fai-assistant-application-process","ko\u002F2.project\u002F1.brolog\u002F11.ai-assistant-application-process",{"title":149,"path":150,"stem":151,"icon":26},"[Brolog] 검색 엔진 노출을 위한 SEO 적용 과정","\u002Fko\u002Fproject\u002Fbrolog\u002Fbrolog-seo","ko\u002F2.project\u002F1.brolog\u002F12.brolog-seo",{"title":153,"path":154,"stem":155,"icon":26},"Brolog 프로젝트 구조","\u002Fko\u002Fproject\u002Fbrolog\u002Fstructure","ko\u002F2.project\u002F1.brolog\u002F2.structure",{"title":157,"path":158,"stem":159,"icon":26},"[Nuxt Content] 네비게이션 아이콘 커스텀 빌드","\u002Fko\u002Fproject\u002Fbrolog\u002Fcustom-icon","ko\u002F2.project\u002F1.brolog\u002F3.custom-icon",{"title":161,"path":162,"stem":163,"icon":26},"[Nuxt 4] Auto-imports 동작 원리와 자동 import 시스템 이해","\u002Fko\u002Fproject\u002Fbrolog\u002Fnuxt-auto-import","ko\u002F2.project\u002F1.brolog\u002F4.nuxt-auto-import",{"title":165,"path":166,"stem":167,"icon":26},"[Brolog] 개발 블로그 메인 페이지 구현","\u002Fko\u002Fproject\u002Fbrolog\u002Fdevelop-main","ko\u002F2.project\u002F1.brolog\u002F5.develop-main",{"title":169,"path":170,"stem":171,"icon":172},"[Brolog] 브랜드 아이덴티티 적용 - Custom 404 페이지와 Default No Image 구현","\u002Fko\u002Fproject\u002Fbrolog\u002Fcustom-error-and-default-thumbnail","ko\u002F2.project\u002F1.brolog\u002F6.custom-error-and-default-thumbnail","lucide:image",{"title":174,"path":175,"stem":176,"icon":26},"[Brolog] Nuxt Multi Layer 프로젝트 Vercel 배포 (1)","\u002Fko\u002Fproject\u002Fbrolog\u002Fvercel-deploy1","ko\u002F2.project\u002F1.brolog\u002F8.vercel-deploy1",{"title":178,"path":179,"stem":180,"icon":26},"[Brolog] Nuxt Multi Layer 프로젝트 Vercel 배포 (2) - Build Pipeline 오류 분석과 Nuxt 실행 구조 이해","\u002Fko\u002Fproject\u002Fbrolog\u002Fvercel-deploy2-error-analyze","ko\u002F2.project\u002F1.brolog\u002F9.vercel-deploy2-error-analyze",{"title":182,"icon":183,"path":184,"stem":185,"children":186,"page":27},"Error (트러블슈팅)","emojione:stop-sign","\u002Fko\u002Ftrouble-shooting","ko\u002F3.trouble-shooting",[187],{"title":131,"icon":132,"path":188,"stem":189,"children":190,"page":27},"\u002Fko\u002Ftrouble-shooting\u002Fbrolog","ko\u002F3.trouble-shooting\u002F1.brolog",[191],{"title":192,"path":193,"stem":194,"icon":26},"[Nuxt Content] Nuxt Icon 오류 해결과 Custom Collection 기반 오프라인 아이콘 구성","\u002Fko\u002Ftrouble-shooting\u002Fbrolog\u002Fnuxt-icon-restricted-network-troubleshooting","ko\u002F3.trouble-shooting\u002F1.brolog\u002F1.nuxt-icon-restricted-network-troubleshooting",{"id":196,"title":101,"body":197,"date":665,"description":666,"extension":667,"links":668,"meta":669,"navigation":674,"path":102,"seo":675,"stem":103,"__hash__":678},"docs_ko\u002Fko\u002F1.note\u002F4.tooling\u002F1.package-manager\u002F1.package-lock.md",{"type":198,"value":199,"toc":651},"minimark",[200,647],[201,202,204,209,225,233,240,243,250,255,264,267,340,351,359,366,369,371,375,378,384,387,393,399,405,407,411,414,417,423,426,428,432,435,441,444,447,449,453,456,503,506,522,528,530,534,541,544,547,550,564,571,573,577,617,624,637,640],"u-page-card",{":spotlight":203},"true",[205,206,208],"h2",{"id":207},"_1-lock-파일은-왜-존재할까","1. Lock 파일은 왜 존재할까?",[210,211,212,213,217,218,217,221,224],"p",{},"Node.js 생태계에서 프로젝트를 생성하거나 패키지를 설치하면 ",[214,215,216],"code",{},"package-lock.json",", ",[214,219,220],{},"yarn.lock",[214,222,223],{},"pnpm-lock.yaml","과 같은 Lock 파일이 자동으로 생성된다.",[210,226,227,228,232],{},"처음에는 단순히 패키지 설치 과정에서 생성되는 부수적인 파일처럼 보이지만, 실제로는 ",[229,230,231],"strong",{},"프로젝트의 의존성(Dependency)을 항상 동일한 상태로 재현하기 위한 핵심 메커니즘","이다.",[210,234,235,236,239],{},"특히 여러 명의 개발자가 협업하거나 CI\u002FCD 환경에서 프로젝트를 빌드할 경우, Lock 파일이 없다면 동일한 ",[214,237,238],{},"package.json","을 사용하더라도 서로 다른 버전의 패키지가 설치되어 예상하지 못한 오류가 발생할 수 있다.",[241,242],"hr",{},[205,244,246,247,249],{"id":245},"_2-packagejson만으로는-충분하지-않은-이유","2. ",[214,248,238],{},"만으로는 충분하지 않은 이유",[251,252,254],"h3",{"id":253},"semver시맨틱-버저닝의-특성","① SemVer(시맨틱 버저닝)의 특성",[210,256,257,259,260,263],{},[214,258,238],{},"은 프로젝트가 필요로 하는 패키지 목록과 ",[229,261,262],{},"허용 가능한 버전 범위","를 정의하는 파일이다.",[210,265,266],{},"예를 들어 다음과 같은 의존성이 있다고 가정해보자.",[268,269,274],"pre",{"className":270,"code":271,"language":272,"meta":273,"style":273},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"dependencies\": {\n    \"vue\": \"^3.5.0\"\n  }\n}\n","json","",[214,275,276,285,304,328,334],{"__ignoreMap":273},[277,278,281],"span",{"class":279,"line":280},"line",1,[277,282,284],{"class":283},"sMK4o","{\n",[277,286,288,291,295,298,301],{"class":279,"line":287},2,[277,289,290],{"class":283},"  \"",[277,292,294],{"class":293},"spNyl","dependencies",[277,296,297],{"class":283},"\"",[277,299,300],{"class":283},":",[277,302,303],{"class":283}," {\n",[277,305,307,310,314,316,318,321,325],{"class":279,"line":306},3,[277,308,309],{"class":283},"    \"",[277,311,313],{"class":312},"sBMFI","vue",[277,315,297],{"class":283},[277,317,300],{"class":283},[277,319,320],{"class":283}," \"",[277,322,324],{"class":323},"sfazB","^3.5.0",[277,326,327],{"class":283},"\"\n",[277,329,331],{"class":279,"line":330},4,[277,332,333],{"class":283},"  }\n",[277,335,337],{"class":279,"line":336},5,[277,338,339],{"class":283},"}\n",[210,341,342,343,346,347,350],{},"여기서 ",[214,344,345],{},"^"," 기호는 정확히 ",[214,348,349],{},"3.5.0","만 의미하는 것이 아니다.",[268,352,357],{"className":353,"code":355,"language":356,"meta":273},[354],"language-text","^3.5.0\n│\n├── 3.5.1\n├── 3.5.4\n├── 3.6.0\n└── 3.x.x\n","text",[214,358,355],{"__ignoreMap":273},[210,360,361,362,365],{},"즉, ",[214,363,364],{},"3.x.x"," 범위 내에서 최신 버전을 설치할 수 있도록 허용한다.",[210,367,368],{},"이러한 방식은 항상 최신 패치와 기능 개선을 받을 수 있다는 장점이 있지만, 시간이 지날수록 설치되는 버전이 달라질 수 있다는 문제도 함께 발생한다.",[241,370],{},[251,372,374],{"id":373},"동일한-프로젝트인데-결과가-달라지는-이유","② 동일한 프로젝트인데 결과가 달라지는 이유",[210,376,377],{},"예를 들어 오늘 프로젝트를 생성했다면 다음과 같이 설치될 수 있다.",[268,379,382],{"className":380,"code":381,"language":356,"meta":273},[354],"Vue 3.5.2\n",[214,383,381],{"__ignoreMap":273},[210,385,386],{},"하지만 한 달 뒤 동일한 프로젝트를 새로 설치하면 Registry에는 새로운 버전이 등록되어 있을 수 있다.",[268,388,391],{"className":389,"code":390,"language":356,"meta":273},[354],"Vue 3.6.1\n",[214,392,390],{"__ignoreMap":273},[210,394,395,396,398],{},"개발자는 같은 ",[214,397,238],{},"을 사용했지만 실제 설치 결과는 달라진다.",[210,400,401,402],{},"이처럼 ",[229,403,404],{},"버전 범위만으로는 항상 동일한 개발 환경을 보장할 수 없다.",[241,406],{},[205,408,410],{"id":409},"_3-lock-파일이-해결하는-문제","3. Lock 파일이 해결하는 문제",[210,412,413],{},"Lock 파일은 실제 설치된 패키지의 정확한 버전과 다운로드 위치, 그리고 하위 의존성까지 모두 기록한다.",[210,415,416],{},"즉,",[268,418,421],{"className":419,"code":420,"language":356,"meta":273},[354],"package.json\n        ↓\n허용 가능한 버전 범위\n\npackage-lock.json\n        ↓\n실제로 설치된 정확한 버전\n",[214,422,420],{"__ignoreMap":273},[210,424,425],{},"이러한 정보를 저장하기 때문에 이후에는 Registry에 새로운 버전이 공개되더라도 Lock 파일을 기준으로 동일한 패키지가 다시 설치된다.",[241,427],{},[251,429,431],{"id":430},"의존성-해결dependency-resolution-과정","의존성 해결(Dependency Resolution) 과정",[210,433,434],{},"패키지를 설치하면 Package Manager는 다음과 같은 순서로 동작한다.",[268,436,439],{"className":437,"code":438,"language":356,"meta":273},[354],"package.json\n      │\n      ▼\n버전 범위(SemVer) 확인\n      │\n      ▼\n패키지 Registry 조회\n      │\n      ▼\n최적의 버전 선택\n      │\n      ▼\n하위 Dependency 분석\n      │\n      ▼\nLock 파일 생성\n      │\n      ▼\nnode_modules 구성\n",[214,440,438],{"__ignoreMap":273},[210,442,443],{},"한 번 생성된 Lock 파일은 이후 설치 과정에서 기준 정보로 사용된다.",[210,445,446],{},"따라서 Package Manager는 다시 버전을 계산하지 않고 Lock 파일을 그대로 참고하여 동일한 의존성 트리를 복원한다.",[241,448],{},[205,450,452],{"id":451},"_4-npm-yarn-pnpm은-각각-어떤-lock-파일을-사용할까","4. npm, Yarn, pnpm은 각각 어떤 Lock 파일을 사용할까?",[210,454,455],{},"Node.js 생태계에는 대표적으로 세 가지 Package Manager가 존재하며 각각 서로 다른 Lock 파일을 사용한다.",[457,458,459,472],"table",{},[460,461,462],"thead",{},[463,464,465,469],"tr",{},[466,467,95],"th",{"align":468},"left",[466,470,471],{"align":468},"Lock 파일",[473,474,475,485,494],"tbody",{},[463,476,477,481],{},[478,479,480],"td",{"align":468},"npm",[478,482,483],{"align":468},[214,484,216],{},[463,486,487,490],{},[478,488,489],{"align":468},"Yarn",[478,491,492],{"align":468},[214,493,220],{},[463,495,496,499],{},[478,497,498],{"align":468},"pnpm",[478,500,501],{"align":468},[214,502,223],{},[210,504,505],{},"파일 형식은 다르지만 목적은 모두 동일하다.",[507,508,509,513,516,519],"ul",{},[510,511,512],"li",{},"설치된 패키지 버전 고정",[510,514,515],{},"의존성 트리 저장",[510,517,518],{},"동일한 개발 환경 재현",[510,520,521],{},"CI\u002FCD 환경의 일관성 유지",[210,523,361,524,527],{},[229,525,526],{},"파일 형식만 다를 뿐 모두 동일한 역할을 수행하는 파일","이라고 이해하면 된다.",[241,529],{},[205,531,533],{"id":532},"_5-lock-파일을-git에-포함해야-하는-이유","5. Lock 파일을 Git에 포함해야 하는 이유",[210,535,536,537,540],{},"Lock 파일은 자동 생성되는 파일이지만 ",[229,538,539],{},"일반적으로 Git 저장소에 함께 커밋","한다.",[210,542,543],{},"그 이유는 프로젝트에 참여하는 모든 개발자가 동일한 의존성 환경을 사용할 수 있도록 하기 위해서다.",[210,545,546],{},"만약 Lock 파일을 제외한 채 저장소를 공유하면 각 개발자의 설치 시점에 따라 서로 다른 버전의 라이브러리가 설치될 수 있다.",[210,548,549],{},"반대로 Lock 파일이 존재하면 다음과 같은 환경에서도 항상 동일한 결과를 얻을 수 있다.",[507,551,552,555,558,561],{},[510,553,554],{},"새로운 개발자가 프로젝트를 처음 설치할 때",[510,556,557],{},"CI\u002FCD 서버에서 자동 빌드를 수행할 때",[510,559,560],{},"운영 서버에서 프로젝트를 배포할 때",[510,562,563],{},"오랜 시간이 지난 뒤 프로젝트를 다시 실행할 때",[210,565,566,567,570],{},"결국 Lock 파일은 ",[229,568,569],{},"프로젝트의 개발 환경을 재현하기 위한 기준 문서"," 역할을 한다.",[241,572],{},[205,574,576],{"id":575},"_7-결론-및-핵심-정리","7. 결론 및 핵심 정리",[457,578,579,589],{},[460,580,581],{},[463,582,583,586],{},[466,584,585],{"align":468},"구분",[466,587,588],{"align":468},"역할",[473,590,591,600,607],{},[463,592,593,597],{},[478,594,595],{"align":468},[214,596,238],{},[478,598,599],{"align":468},"필요한 패키지와 허용 버전 정의",[463,601,602,604],{},[478,603,471],{"align":468},[478,605,606],{"align":468},"실제 설치된 정확한 버전 기록",[463,608,609,614],{},[478,610,611],{"align":468},[214,612,613],{},"node_modules",[478,615,616],{"align":468},"실제 패키지 파일이 저장되는 디렉터리",[210,618,619,620,623],{},"Lock 파일은 단순히 자동 생성되는 파일이 아니라 ",[229,621,622],{},"의존성 관리의 기준점(Single Source of Truth)"," 역할을 수행한다.",[210,625,626,628,629,632,633,636],{},[214,627,238],{},"이 프로젝트가 ",[229,630,631],{},"무엇을 필요로 하는지","를 정의하는 문서라면, Lock 파일은 ",[229,634,635],{},"실제로 무엇이 설치되었는지","를 기록하는 문서라고 볼 수 있다.",[210,638,639],{},"프로젝트 규모가 커질수록 의존성의 수는 기하급수적으로 증가하며, 각 패키지는 다시 수많은 하위 의존성을 포함한다. 이러한 환경에서 Lock 파일은 모든 의존성 트리를 고정하여 누구나 동일한 개발 환경에서 작업할 수 있도록 보장한다.",[210,641,642,643,646],{},"Node.js 생태계에서 ",[229,644,645],{},"재현 가능한 빌드(Reproducible Build)"," 와 안정적인 협업이 가능한 이유 역시 바로 이러한 Lock 파일 메커니즘 덕분이라고 할 수 있다.",[648,649,650],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":273,"searchDepth":287,"depth":287,"links":652},[653,654,659,662,663,664],{"id":207,"depth":287,"text":208},{"id":245,"depth":287,"text":655,"children":656},"2. package.json만으로는 충분하지 않은 이유",[657,658],{"id":253,"depth":306,"text":254},{"id":373,"depth":306,"text":374},{"id":409,"depth":287,"text":410,"children":660},[661],{"id":430,"depth":306,"text":431},{"id":451,"depth":287,"text":452},{"id":532,"depth":287,"text":533},{"id":575,"depth":287,"text":576},"2026-07-16","npm, yarn, pnpm의 Lock 파일이 생성되는 이유와 재현 가능한 의존성 관리 메커니즘 분석","md",null,{"tags":670,"image":673},[95,480,498,671,672],"yarn","Node.js","\u002Fimages\u002FpackageManager-thumbnail.png",{"icon":26},{"title":676,"description":677},"package-lock.json, yarn.lock, pnpm-lock.yaml 역할과 차이점 이해","package-lock.json, yarn.lock, pnpm-lock.yaml이 필요한 이유와 의존성 해결(Dependency Resolution), SemVer, 재현 가능한 빌드 원리를 알아봅니다.","jqWS66lVP5y8rS3QyHU3CvoWqBX5J0FHwVR7tdOeAy0",[680,682],{"title":85,"path":86,"stem":87,"description":681,"icon":26,"children":-1},"WebAssembly와 WASI가 서버 환경으로 확장되는 과정과 Docker 컨테이너 기반 아키텍처와의 차이점, 엣지 환경에서의 활용 사례 분석",{"title":111,"path":112,"stem":113,"description":683,"icon":26,"children":-1},"SSR, CSR, SSG, ISR 등 현대 웹 애플리케이션의 주요 렌더링 방식의 동작 원리와 특징, 상황별 선택 기준 정리",1785305906284]