yarn workspaces는 루트 경로의 package.json이 하위 폴더의 package.json에 정의된 종속성을 yarn install로 한번에 설치한다.
설치하는 과정에서 하위 폴더의 package.json의 종속성의 중복을 제거한 후 루트 경로의 node_modules로 호이스팅하여 설치한다.
yarn init -y
package.json
packages 폴더 내의 모든 폴더가 workspace가 되도록 하려면 다음과 같이 설정한다.
{
"name": "Dana",
"private": true,
"version": "0.1.0",
"license": "MIT",
"workspaces": {
"packages": [
"packages/**"
]
}
}
mkdir packages packages/sfp packages/wms
cd packages/sfp
yarn init -y
cd ../wms
yarn init -y
sfp Package 추가
yarn workspace sfp add {Package Name}
sfp Package 삭제
yarn workspace sfp remove {Package Name}
wms Package 추가
yarn workspace wms add {Package Name}
yarn workspace wms remove {Package Name}
루트 디렉토리에 패키지 추가
yarn add {Package Name} -W
각 프로젝트 별로 React 추가
yarn workspace sfp add react
yarn workspace wms add react
nohoist 항목 추가
{
"name": "dana",
"private": true,
"version": "0.1.0",
"license": "MIT",
"workspaces": {
"packages": [
"packages/**"
],
"nohoist": [
"**/react-router-dom",
"**/react-router-dom/**"
]
}
}
sfp 프로젝트에 react-router-dom 추가
yarn workspace sfp add react-router-dom
yarn workspace run wms
yarn workspace wms run start
의존성 확인
yarn workspaces info모노레포스
프로젝트를 여러 패키지로 분할해 본 사람들은 한 번에 여러 패키지를 변경하는 것이 얼마나 어려운지 알고 있습니다. 프로세스를 더 쉽게 만들기 위해 일부 대규모 프로젝트에서는 단일 저장소 접근 방식, 즉 다중 패키지 리포지토리를 채택하여 패키지 전체에 코드를 작성하는 부담을 줄였습니다.
JavaScript 개발자가 매일 사용하는 여러 프로젝트는 Babel , React , Jest , Vue , Angular 등 단일 저장소로 관리됩니다 .
그러나 프로젝트 조각을 자체 폴더로 분리하는 것만으로는 충분하지 않은 경우가 있습니다. 테스트, 종속성 관리 및 여러 패키지 게시는 빠르게 복잡해지며 이러한 많은 프로젝트에서는 Lerna 와 같은 도구를 채택하여 단일 저장소 작업을 더 쉽게 만듭니다.
레르나
Lerna는 git 및 npm을 사용하여 다중 패키지 저장소 관리에 대한 작업 흐름을 최적화하는 도구입니다. 내부적으로는 Yarn 또는 npm CLI를 사용하여 프로젝트를 부트스트랩(즉, 각 패키지에 대한 모든 타사 종속 항목 설치)합니다. 간단히 말해서 Lerna는 yarn/npm install프로젝트 내의 각 패키지를 호출한 다음 서로를 참조하는 패키지 간에 심볼릭 링크를 만듭니다.
패키지 관리자의 래퍼이기 때문에 Lerna는 node_modules의 내용을 효율적으로 조작할 수 없습니다.
- Lerna는 각 패키지가 독립적인 것으로 간주되고 서로 종속성을 공유할 수 없기 yarn install때문에 오버헤드를 생성하는 각 패키지에 대해 여러 번 호출합니다. package.json이로 인해 동일한 타사 패키지를 자주 사용하는 각 node_modules 폴더에 대해 많은 중복이 발생합니다.
- Lerna는 설치가 완료된 후 서로를 참조하는 패키지 간의 링크를 수동으로 만듭니다. 이로 인해 패키지 관리자가 인식할 수 없는 node_modules 내부의 불일치가 발생하므로 yarn install패키지 내에서 실행하면 Lerna가 관리하는 메타 구조가 손상될 수 있습니다.
이러한 문제로 인해 우리는 패키지 관리자 개발자로서 Yarn에서 직접 다중 패키지 저장소를 지원해야 한다고 확신했습니다. Yarn 0.28 부터 Workspaces 기능에서 이러한 리포지토리를 지원한다는 소식을 공유하게 되어 기쁘게 생각합니다 .
Yarn 작업공간 소개
Yarn 작업 영역은 사용자가 단일 루트 package.json 파일의 하위 폴더에 있는 여러 package.json 파일의 종속성을 한 번에 설치할 수 있는 기능입니다.
Workspace를 Yarn의 기본으로 만들면 Workspace 전체에서 패키지 중복을 방지하여 더 빠르고 쉽게 설치할 수 있습니다. Yarn은 서로 의존하는 작업공간 간에 심볼릭 링크를 생성할 수도 있으며 모든 디렉터리의 일관성과 정확성을 보장합니다.
작업공간 설정
Yarn 1.0 시작 작업공간은 기본적으로 활성화되어 있으며 아래 구성을 설정할 필요가 없을 수도 있습니다. 다음 위치 https://yarnpkg.com/lang/en/docs/workspaces/에서 업데이트된 단계를 참조하세요.
시작하려면 사용자는 다음 명령을 실행하여 Yarn에서 작업공간을 활성화해야 합니다.
yarn config set workspaces-experimental true
OS 홈 폴더의 파일 workspaces-experimental true에 추가됩니다 . .yarnrc커뮤니티로부터 피드백을 수집하는 동안 Yarn Workspaces는 여전히 실험적인 것으로 간주됩니다.
Jest 를 예로 들어 해당 구조에 대해 Yarn 작업 공간을 설정해 보겠습니다. 사실, 이는 이미 PR에서 수행 되었으며 Jest는 한동안 Yarn을 사용하여 패키지를 부트스트랩해 왔습니다.
Jest의 프로젝트 구조는 오픈 소스 JavaScript 모노레포의 전형적인 구조입니다.
| jest/
| ---- package.json
| ---- packages/
| -------- jest-matcher-utils/
| ------------ package.json
| -------- jest-diff/
| ------------ package.json
...
최상위 수준은 package.json프로젝트의 루트를 정의하고 다른 package.json 파일이 있는 폴더는 작업공간입니다. 작업공간은 일반적으로 npm과 같은 레지스트리에 게시됩니다. 루트는 패키지로 사용되어서는 안 되지만 일반적으로 다른 프로젝트와 공유하는 데 유용하지 않은 글루 코드나 비즈니스 관련 코드를 포함하므로 "비공개"로 표시합니다.
다음 예는 package.json프로젝트에 대한 작업공간을 활성화하고 프로젝트 빌드 및 테스트 환경에 필요한 타사 패키지를 정의하는 단순화된 루트입니다.
{
"private": true,
"name": "jest",
"devDependencies": {
"chalk": "^2.0.1"
},
"workspaces": [
"packages/*"
]
}
작업을 단순하게 유지하기 위해 두 개의 작은 Workspaces 패키지를 설명하겠습니다.
- jest-matcher-utils 작업공간:
-
{ "name": "jest-matcher-utils", "description": "...", "version": "20.0.3", "license": "...", "main": "...", "browser": "...", "dependencies": { "chalk": "^1.1.3", "pretty-format": "^20.0.3" } }
- jest-matcher-utils에 의존하는 jest-diff 작업공간:
-
{ "name": "jest-diff", "version": "20.0.3", "license": "...", "main": "...", "browser": "...", "dependencies": { "chalk": "^1.1.3", "diff": "^3.2.0", "jest-matcher-utils": "^20.0.3", "pretty-format": "^20.0.3" } }
Lerna와 같은 래퍼는 먼저 yarn install각각에 대해 package.json개별적으로 실행된 다음 yarn link서로 의존하는 패키지에 대해 실행됩니다.
해당 접근 방식을 사용하면 다음과 같은 폴더 구조를 얻게 됩니다.
| jest/
| ---- node_modules/
| -------- chalk/
| ---- package.json
| ---- packages/
| -------- jest-matcher-utils/
| ------------ node_modules/
| ---------------- chalk/
| ---------------- pretty-format/
| ------------ package.json
| -------- jest-diff/
| ------------ node_modules/
| ---------------- chalk/
| ---------------- diff/
| ---------------- jest-matcher-utils/ (symlink) -> ../jest-matcher-utils
| ---------------- pretty-format/
| ------------ package.json
...
보시다시피 타사 종속성이 중복되어 있습니다.
Workspaces를 활성화하면 Yarn은 훨씬 더 최적화된 종속성 구조를 생성할 수 있으며 프로젝트의 어느 곳에서나 일반적인 작업을 실행하면 yarn install다음 node_modules를 얻게 됩니다.
| jest/
| ---- node_modules/
| -------- chalk/
| -------- diff/
| -------- pretty-format/
| -------- jest-matcher-utils/ (symlink) -> ../packages/jest-matcher-utils
| ---- package.json
| ---- packages/
| -------- jest-matcher-utils/
| ------------ node_modules/
| ---------------- chalk/
| ------------ package.json
| -------- jest-diff/
| ------------ node_modules/
| ---------------- chalk/
| ------------ package.json
...
, 같은 패키지 diff와 pretty-format심볼릭 링크가 jest-matcher-utils루트 node_modules 디렉터리에 끌어올려져 설치가 더 빠르고 작아졌습니다. chalk그러나 루트가 이미 다른 호환되지 않는 버전에 의존하고 있기 때문에 패키지를 루트로 이동할 수 없습니다 chalk.
위의 두 구조는 모두 호환되지만 Node.js 모듈 확인 논리와 관련하여 여전히 정확하면서 후자가 더 최적입니다.
열렬한 Lerna 사용자의 경우 이는 플래그를 통한 코드 부트스트래핑과 유사합니다 --hoist.
작업공간 내에서 코드를 실행하면 jest-diff모든 종속성을 해결할 수 있습니다.
- require('chalk')는 다음과 같이 해결됩니다../node_modules/chalk
- require('diff')는 다음으로 해결됩니다.../../node_modules/diff
- require('pretty-format')은 다음과 같이 해결됩니다.../../node_modules/pretty-format
- require('jest-matcher-utils') 는 ../../node_modules/jest-matcher-utils다음에 대한 심볼릭 링크 로 확인됩니다.../packages/jest-matcher-utils
작업공간의 종속성 관리
작업공간의 종속성을 수정하려면 작업공간 폴더 내에서 적절한 명령을 실행하면 됩니다.
$ cd packages/jest-matcher-utils/
$ yarn add left-pad
✨ Done in 1.77s.
$ git status
modified: package.json
modified: ../../yarn.lock
작업공간에는 자체적인 Yarn.lock 파일이 없으며 루트 Yarn.lock에는 모든 작업공간에 대한 모든 종속성이 포함되어 있습니다. 작업공간 내부의 종속성을 변경하려는 경우 작업공간의 package.json뿐만 아니라 루트 Yarn.lock도 변경됩니다.
Lerna와 통합
Yarn 작업 공간으로 인해 Lerna가 쓸모없게 되나요?
별말씀을요. Yarn 작업 공간은 Lerna와 쉽게 통합됩니다.
Lerna는 단지 프로젝트를 부트스트래핑하는 것 이상의 기능을 제공하며 필요에 따라 Lerna를 미세 조정한 사용자 커뮤니티가 있습니다.
Lerna 2.0.0부터 --use-workspacesLerna 명령을 실행할 때 플래그를 전달하면 Yarn을 사용하여 프로젝트를 package.json/workspaces부트 스트랩하고 lerna.json/packages.
Jest를 위해 Lerna를 구성하는 방법은 다음과 같습니다.
{
"lerna": "2.0.0",
"npmClient": "yarn",
"useWorkspaces": true
}
Jest는 Yarn을 사용하여 프로젝트를 부트스트랩하고 Lerna를 사용하여 게시 명령을 실행합니다.
중복성을 줄이기 위해 대부분의 패키지 관리자는 일종의 호이스팅 방식을 사용하여 모든 종속 모듈을 최대한 중앙 위치로 추출하고 평면화합니다. 독립형 프로젝트에서는 종속성 트리를 다음과 같이 줄일 수 있습니다.
호이스트를 사용하면 버전 변형(B@2.0)을 유지하고 동일한 루트를 유지하면서 중복된 "A@1.0" 및 "B@1.0"을 제거할 수 있었습니다 package-1/node_modules. 대부분의 모듈 크롤러/로더/번들러는 프로젝트 루트에서 "node_modules" 트리를 탐색하여 매우 효율적으로 모듈을 찾을 수 있습니다.
그런 다음 "node_modules"로 연결될 필요가 없는 새로운 계층 구조를 도입한 모노레포 프로젝트가 등장했습니다. 이러한 프로젝트에서는 모듈이 여러 위치에 분산될 수 있습니다.
Yarn 작업공간은 모듈을 상위 프로젝트의 node_modules: 까지 끌어올려 하위 프로젝트/패키지 간에 모듈을 공유할 수 있습니다 monorepo/node_modules. 이러한 패키지가 서로 의존할 가능성이 가장 높다는 점(단일 저장소를 갖는 주된 이유), 즉 더 높은 수준의 중복성을 고려할 때 이러한 최적화는 더욱 두드러집니다.
모듈을 찾을 수 없습니다!!
프로젝트의 루트 node_modules에서 모든 모듈에 액세스할 수 있는 것처럼 보일 수 있지만, 로컬 프로젝트에서 각 패키지를 빌드하는 경우가 많습니다. 여기서 모듈은 자체 node_modules 아래에 표시되지 않을 수 있습니다. 또한 모든 크롤러가 심볼릭 링크를 통과하는 것은 아닙니다 .
결과적으로 작업 영역 개발자는 하위 프로젝트에서 빌드할 때 "모듈을 찾을 수 없음" 관련 오류를 자주 목격합니다.
- 프로젝트 루트 "monorepo"에서 "B@2.0" 모듈을 찾을 수 없습니다(symlink를 따라갈 수 없음).
- "package-1"에서 "A@1.0" 모듈을 찾을 수 없습니다("monorepo"에서 위의 모듈 트리를 인식하지 못함).
이 모노레포 프로젝트가 어디에서나 모듈을 안정적으로 찾으려면 각 node_modules 트리("monorepo/node_modules" 및 "monorepo/packages/package-1/node_modules")를 순회해야 합니다.
왜 고칠 수 없나요?
실제로 라이브러리 소유자가 이러한 문제를 해결할 수 있는 방법은 다중 루트, 사용자 정의 모듈 맵, 영리한 순회 구성표 등 여러 가지가 있습니다… 그러나
- 모든 타사 라이브러리에 모노레포 환경에 적응할 수 있는 리소스가 있는 것은 아닙니다.
- 가장 약한 링크 문제: 대규모 타사 라이브러리 덕분에 자바스크립트가 훌륭합니다. 그러나 이는 복잡한 도구 체인이 가장 약한 링크만큼만 강력하다는 의미이기도 합니다. 도구 체인 깊숙한 곳에 적응되지 않은 단일 패키지가 있으면 전체 도구를 쓸모 없게 만들 수 있습니다.
- 부트스트랩 문제: 예를 들어, React-Native는 rn-cli.config.js. 그러나 앱이 생성/설치되기 전에는 이러한 도구에 액세스할 수 없는 react-native init또는 같은 부트스트랩 프로세스에는 도움이 되지 않습니다 .create-react-native-app
독립형 프로젝트에서 작동하는 솔루션이 모노레포 환경에서만 부족하면 실망스럽습니다. 이상적인 솔루션은 기본 라이브러리를 해결하는 데 있지만 현실은 완벽하지 않으며 프로젝트가 더 이상 기다릴 수 없다는 것을 우리 모두 알고 있습니다…
"노호이스트"란 무엇입니까?
이러한 호환되지 않는 라이브러리가 모노레포 환경에서 작동하도록 할 수 있는 간단하면서도 보편적인 메커니즘이 있습니까?
lerna 와 같은 다른 모노레포 도구에서도 시연된 바 있는 “nohoist” 라는 것이 편리하게 알려져 있습니다 .
"nohoist"를 사용하면 작업 공간에서 아직 호이스팅 체계와 호환되지 않는 타사 라이브러리를 사용할 수 있습니다. 아이디어는 선택한 모듈이 프로젝트 루트로 끌어올려지는 것을 비활성화하는 것입니다. 작업공간이 아닌 독립 실행형 프로젝트와 마찬가지로 실제(하위) 프로젝트에 배치되었습니다.
대부분의 타사 라이브러리는 이미 독립 실행형 프로젝트에서 작동했기 때문에 작업 공간 내에서 이러한 환경을 시뮬레이션하는 기능을 통해 알려진 많은 호환성 문제를 해결할 수 있습니다.
주의 사항
nohoist는 유용하지만 단점도 있습니다. 가장 분명한 것은 nohoist 모듈이 여러 위치에 복제될 수 있어 위에서 언급한 hoisting의 이점을 거부할 수 있다는 것입니다. 따라서 프로젝트에서 nohoist 범위를 가능한 한 작고 명시적으로 유지하는 것이 좋습니다.
언제부터 이용 가능합니까?
1.4.2 와 함께 배포될 예정입니다.
사용 방법?
nohoist를 사용하는 것은 매우 간단합니다. package.json에 정의된 nohoist 규칙에 따라 구동됩니다. 1.4.2부터 Yarn은 (선택 사항) nohoist 설정을 포함하기 위해 새로운 작업 공간 구성 형식을 채택합니다.
// flow type definition:
export type WorkspacesConfig = {
packages?: Array<string>,
nohoist?: Array<string>,
};
예를 들어:
- nohoist가 있는 개인 프로젝트 루트에서:
"workspaces": { "packages": ["packages/*"], "nohoist": ["**/react-native", "**/react-native/**"] }
- nohoist 없이 개인 프로젝트 루트에서:
"workspaces": { "packages": ["packages/*"], }
- nohoist가 있는 개인 하위 프로젝트에서:
"workspaces": { "nohoist": ["react-native", "react-native/**"] }
참고: nohoist가 필요하지 않은 사용자를 위해 이전 작업 공간 형식이 계속 지원됩니다.
nohoist 규칙은 종속성 트리의 모듈 경로와 일치하는 데 사용되는 glob 패턴 모음일 뿐입니다 . 모듈 경로는 실제 파일 경로가 아닌 종속성 트리의 가상 경로이므로 nohoist 패턴에서 "node_modules" 또는 "packages"를 지정할 필요가 없습니다.
삽화
nohoist를 사용하여 모노레포 프로젝트 “monorepo”에서 반응 네이티브가 호이스팅되는 것을 방지하는 방법을 설명하기 위해 단순화된 의사 예제를 살펴보겠습니다. "monorepo"에는 A, B, C의 3개 패키지가 있습니다.
이전의 파일 시스템 yarn install:
프로젝트 루트 “monorepo”의 package.json 파일:
// monorepo's package.json
...
"name": "monorepo",
"private": true,
"workspaces": {
"packages": ["packages/*"],
"nohoist": ["**/react-native", "**/react-native/**"]
}
...
구성을 자세히 살펴보겠습니다.
범위: 비공개
작업공간은 비공개 패키지에만 사용할 수 있으므로 nohoist는 비공개 패키지에만 사용할 수 있습니다.
글로브 패턴 일치
내부적으로 Yarn은 "원래"(호이스팅 전) 패키지 종속성을 기반으로 각 모듈에 대한 가상 모듈 경로를 구성합니다. 이 경로가 제공된 nohoist 패턴과 일치하면 대신 가장 가까운 하위 프로젝트/패키지로 끌어올려집니다.
모듈 경로
ㅏ
- 모노레포/A
- 모노레포/A/반응 네이티브
- 모노레포/A/반응 네이티브/메트로
- 모노레포/A/Y
비
- 모노레포/B
- 모노레포/B/X
- 모노레포/B/X/반응 네이티브
- 모노레포/B/X/반응 네이티브/메트로
씨
- 모노레포/C
- 모노레포/C/Y
노호이스트 패턴
" **/react-native ": 원사가 어디에 있든 상관없이 반응 네이티브 패키지 자체를 끌어올리지 않도록 지시합니다. (얕은)
- globstar “**”를 사용하면 반응 네이티브 이전의 0에서 n 요소와 일치합니다. 즉, 경로의 어디에 나타나든 모든 반응 네이티브 발생과 일치한다는 의미입니다.
- 패턴이 "react-native"로 끝나는 것은 "react-native/metro"와 같은 반응 네이티브의 종속성이 이 패턴과 일치하지 않음을 의미하므로 용어는 "얕다"입니다.
" **/react-native/** ": 이는 Yarn이 React-Native의 종속 라이브러리 및 해당 종속 라이브러리를 끌어올리지 않도록 지시합니다. (깊은)
- 패턴은 "**"로 끝납니다. 위에서 언급한 접두사 globstar와 달리 접미사 globstar는 React-Native 다음에 오는 1~n 요소와 일치합니다. 즉, React-Native의 종속성만 이 패턴과 일치하지만 React-Native 자체는 일치하지 않는다는 의미입니다.
- 반응 네이티브의 직접적인 종속성이 이 패턴과 일치할 뿐만 아니라 해당 종속성 등도 일치하므로 "깊은"이라는 용어가 사용됩니다.
이 두 가지 패턴(얕은 패턴과 깊은 패턴)을 결합하여 원사에 반응 네이티브와 모든 종속 항목을 끌어올리지 않도록 지시합니다.
몇 가지 패턴을 더 시도해 보겠습니다.
- 패키지 A에만 반응 네이티브 nohoist를 적용하고 싶다면 어떻게 해야 할까요?
"nohoist": ["A/react-native", "A/react-native/**"]
- 반응 네이티브 앱을 빌드할 때 패키지 A에도 패키지 C가 포함되어야 한다면 어떻게 될까요?
"nohoist": ["A/react-native", "A/react-native/**", "A/C"]
호이스트 후 파일 구조
이후 yarn install파일 구조는 다음과 같습니다.
"monorepo/A/Y", "monorepo/B/X" 및 "monorepo/C/Y"가 nohoist 패턴과 일치하지 않기 때문에 모듈 X와 Y가 루트로 끌어올려졌습니다. "monorepo/B/X/react-native"가 nohoist 패턴과 일치하더라도 "monorepo/B/X"는 그렇지 않습니다. 따라서 반응 네이티브 모듈은 원래 부모 "X"가 루트로 끌어올려지는 동안 패키지 "B"에 남아 있게 됩니다.
React-Native와 Metro는 React-Native Nohoist 패턴과 일치하기 때문에 각각 패키지 A와 B 아래에 배치되었습니다. B가 반응 네이티브에 직접적으로 의존하지 않더라도 독립형 프로젝트에서와 마찬가지로 여전히 "B"로 끌어올려진다는 점에 유의하세요.
nohoist 어떻게 끄나요?
nohoist는 기본적으로 켜져 있습니다. Yarn이 개인 package.json에서 nohoist 구성을 보면 이를 사용합니다.
nohoist를 끄려면 package.json에서 nohoist 구성을 제거하거나 .yarnrc workspaces-nohoist-experimental false또는 yarn config set workspaces-nohoist-experimental false.
실제 사례
이제 노호이스트가 어떻게 작동하는지에 대한 기본 아이디어를 얻었습니다. 이제 실제 작업을 수행해 볼 시간입니다.
다음은 nohoist 개발 시 사용한 테스트 프로젝트입니다. 이제 Yarn-nohoist-examples 에서 사용할 수 있습니다 .
- 원사 작업 공간 내에서 반응 네이티브 생성: => 독립 실행형 환경에서와 같이 반응 네이티브 가이드를 거의 따를 수 있는지 확인
- 반응 및 반응 네이티브를 모두 포함하는 보다 현실적인 모노레포 프로젝트를 만듭니다. => nohoist가 이 명령 및 고급 사용 사례에 작동하는지 확인하세요.
이는 작업 예제입니다. 즉, 해당 지침에 따라 복제하고 실행할 수 있습니다. 그렇지 않은 경우 알려 주시기 바랍니다.
조사하다
일이 예상대로 일어나지 않으면 어떻게 되나요? 로컬 node_modules에 모듈이 몇 개 있는지, 아니면 전혀 없는지 놀랐나요? Yarn 에는 호이스팅 이유를 보고하여 호기심을 조사하고 만족시킬 수 있는 강력한 " 왜 " 명령이 있습니다.
이는 아마도 실제 예를 통해 가장 잘 설명될 것입니다.
결론
nohoist는 새롭기 때문에 몇 차례의 연마가 필요할 가능성이 높습니다. 문제가 있는 것 같으면 알려주시기 바랍니다. 이는 이미 작업 공간을 훨씬 더 쉽게 만들어 주었으며 여러분에게도 동일한 효과가 있기를 바랍니다.
우리는 또한 라이브러리 소유자에게 귀하의 라이브러리를 모노레포 환경에 맞게 조정하여 언젠가 nohoist를 은퇴하고 모든 공유 가능한 모듈을 올바른 위치로 끌어올릴 수 있도록 요청하고 싶습니다.
참고자료
- nohoist 원래 제안: RFC #86
- 노호이스트 PR: #4979
- 작업공간 소개: Yarn의 작업공간
'실전 단아 개발 가이드' 카테고리의 다른 글
오프라인 캐시 (0) | 2024.01.18 |
---|---|
React ref 사용, DOM 접근 방법 (0) | 2024.01.18 |
ReactJs 교재 Github :: ebook (0) | 2024.01.17 |
무료 React JS 전자서적, 다운로드 가능 (0) | 2024.01.17 |
도전! React 업그레이드하기 (0) | 2024.01.12 |