yarn version 2 ๋ถํฐ ๋์จ Plug'n'Play ์ ๋ต์ npm์ node_modules
ํ์์ด ์๋ pnp
ํ์ผ์ ๋ช
์์ ์ผ๋ก ์์น๋ฅผ ์
๋ ฅํ์ฌ ํจ์จ์ ์ผ๋ก ์์กด์ฑ ๋ชจ๋์ ๊ฒ์ํ ์์๊ณ , npm ๊ฐ์ด ์ค์น ํ์ง ์์ ํจํค์ง ๋ชจ๋์ด ์ค์น๋ ํจํค์ง ๋ชจ๋ ์๋์ ์๋ค๋ฉด import
ํด์ ์ฌ์ฉํ ์ ์๋ ์ ๋ น ์์กด์ฑ
์ ์ ๊ฑฐํ์ฌ ํผ๋์ ์์ด๋ค.
["react", [\
["npm:18.2.0", {\
"packageLocation": "./.yarn/cache/react-npm-18.2.0-1eae08fee2-88e38092da.zip/node_modules/react/",\ <- ์์กด์ฑ ์์น ๋ช
์
"packageDependencies": [\
["react", "npm:18.2.0"],\
["loose-envify", "npm:1.4.0"]\
],\
"linkType": "HARD"\
}]\
]],\
yarn v2 pnp ์ ๋ต์ ์ฌ์ฉํ๋ฉด .yarn/cache/~.zip ์์น์ zip
ํ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์์กด์ฑ๋ค์ ๊ธฐ์กด๋ณด๋ค ์์ ์ฉ๋์ผ๋ก ๊ฐ์ง๊ณ ์์ ์ ์์ด github
๊ฐ์ ์ ์ฅ์์ ์์กด์ฑ์ ๊ฐ์ด ์ฌ๋ ค๋์ด ๋ฐฐํฌ์ ์์กด์ฑ ์ค์น๋ฅผ ์๋ตํ์ฌ ๋ฐฐํฌ์๊ฐ์ ์ค์ผ์ ์๋ค.
vscode๋ก ์ฝ๋๋ฅผ ์์ฑ์ zip ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์์ด ์์กด์ฑ์ ์ฝ์์ ์๋๋ก ZipFS extension์ ์ค์น ํ yarn dlx @yarnpkg/sdks vscode
์
๋ ฅํ๋ฉด .vscode
ํ์ผ์ด ์ค์น๋๋ฉฐ ์์กด์ฑ ์ธ์์ ํ ์ ์๋ค.
๋ชจ๋
ธ๋ ํฌ๋ ํ๋์ ์ ์ฅ์์ ์ฌ๋ฌ ์๋น์ค๋ค์ ๊ด๋ฆฌํ๊ณ ์์กด์ฑ์ ๊ณต์ ํ์ฌ ๊ฐ๋ฐํ๋ ์ ๋ต์
๋๋ค. yarn v2 workspace๋ฅผ ํ์ฉํ๋ค๋ฉด ๋ ํ์งํ ๋ฆฌ๋ฅผ ํด๋ก ํ์์ ๊ฒฝ์ฐ ์์กด์ฑ ์ค์น๋ฅผ ์๋ตํ ์ ์๋ zeroInstall ์ ๋ต์ ์ฌ์ฉํ ์ ์๋ค.
๋ฟ๋ง์๋๋ผ ๋ชจ๋
ธ๋ ํฌ๋ฅผ ํ์ฉํ๋ค๋ฉด ๊ณตํต ํญ๋ชฉ(์ปดํฌ๋ํธ, ์คํ์ผ, ์ธํ
)
์ ๊ณต์ ํ์ฌ ์ข๋ ์ฒด๊ณ์ ์ธ ๊ฐ๋ฐ์ ํ ์ ์๋ค.
// yarn workspace-tool ์ค์น
yarn plugin import workspace-tools
workspace-tools ํ๋ฌ๊ทธ์ธ์ ์ค์นํ๋ ์ด์ ๋ foreach
๋ผ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํด์ ์ค์น๋ฅผ ํ์๋ค. ์ด ๊ธฐ๋ฅ์ ์๋ฐ์คํฌ๋ฆฝํธ์ foreach
๊ฐ์ ๊ฐ๋
์ผ๋ก ์ค์ ํ workspace์ ๋ํด ๋ช
๋ น์ด๋ฅผ ์คํ์ํ๊ฒ ํด์ฃผ๊ณ , --since
๋ผ๋ ์ต์
์ผ๋ก ์ฐธ์กฐ ๋ธ๋์น ๊ธฐ์ค ๋ณ๊ฒฝ๋ ์ฝ๋๊ฐ ์๋ workspace๋ง
๋ช
๋ น์ด๋ฅผ ์คํํ๊ฒ ํ ์ ์๋ค.
์ฃผ์โ๏ธ - foreach์ --since ์ต์ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ git-flow ์ ๋ต์ ๋ฌด์๋ณด๋ค ์ ์ด์ฉํด์ผํ๋ค.
์นํฉ5 ๋ถํฐ ๋ด์ฅ๊ธฐ๋ฅ์ผ๋ก ์ถ๊ฐ๋ federation ๊ธฐ์ ์ ์ง๊ธ ๊ตฌํํ ๋ง์ดํฌ๋ก ํ๋ก ํธ ํ๋ก์ ํธ์์ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ
์ด๋ค. Federation์ runtime
์ ๊ณต์ ํ ์๋น์ค๋ก ๋ถํฐ ์ฝ๋(chunk file)์ ์ข
์์ฑ(dependency)์ ๋์ ์ผ๋ก ์ฌ์ฉํ๊ฑฐ๋ ๋ค์ ๊ณต์ ํ ์ ์๋ค.
- name : service ์ด๋ฆ
- filename : ๋ด๋ณด๋ผ ํ์ผ ์ด๋ฆ
- exposes : ๊ณต์ ํ ์์
- remotes : ๊ณต์ ๋ฐ์ ์๋น์ค ์ฃผ์
- shared : ๊ณต์ ํ ์์์ด ์์ ๊ฒฝ์ฐ! ์ข ์์ฑ ๊ณต์
shared options
- singleton : ์ฌ๋ฌ ํจํค์ง ๋ฒ์ ์ด ๊ณต์ ๊ฐ ๋์ด์๋ค๋ฉด ํ๋์ ๋ฒ์ ์์๋ง ๋ก๋๊ฐ ๋๋ค, ์ฆ ์ค์ ํ ๋ฒ์ ์์๋ง ๋ก๋๊ฐ ๋๋ค
- requiredVersion : ์๋น์ค์์ ์ฌ์ฉํ๋ ์ข ์์ฑ ํจํค์ง ๋ฒ์ ์ ๋ํ๋ธ๋ค.
- eager : true๋ก ์ฌ์ฉํ๋ฉด load๊ฐ ๋์ง ์์๋๋ ํญ์ ๋ด๋ ค๋ฐ๊ฒ ๋๋ค.
exposes ์ต์
์ ์๋น์ค์ component, style, assets
๋ฑ... ์๋น์ค ์์? ์ ๊ณต์ ํ๊ธฐ ์ํ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ์ด๋ค.
// service1/webpack.config.js
const { ModuleFederationPlugin } = require("webpack").container;
const deps = require("./package.json").dependencies;
plugins: [
new ModuleFederationPlugin({
name: "service1",
filename: "remoteEntry.js",
exposes: {
"./App": "./src/App.tsx",
},
shared: {
...deps,
react: {
eager: true,
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
eager: true,
singleton: true,
requiredVersion: deps["react-dom"],
},
}
})
]
remotes ์ต์ ์ ๊ณต์ ํ ์๋น์ค์ ์ฐ๊ฒฐ์ ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
// container/webpack.config.js
plugins: [
new ModuleFederationPlugin({
name: "container",
remotes: {
remote_service1: "service1@http://localhost:port/remoteEntry.js",
},
})
]
// container/src/App.tsx
import React from 'react'
const ServiceApp = React.lazy(()=> import('remote_service1/App'))
function App() {
return (
<div>
{
<React.Suspense fallback={<div>๋ก๋ฉ์ค</div>}>
<ServiceApp />
</React.Suspense>
}
</div>
)
}
export default App
์ง๊ธ ๋ฐฐํฌ ๋ฐฉ๋ฒ์ ๊ฐ์ธ์ ์ธ ์๊ฐ์ ๋ด์ ๋ฐฐํฌ ๋ฐฉ๋ฒ์ด๋ค.
๐ yarn pnp ์ ๋ต์ ์ฌ์ฉํ๋ฉด ๋ ํ์งํ ๋ฆฌ์ ๋ชจ๋ ์ข ์์ฑ๋ค์ ๊ฐ์ง๊ณ ์์ด, docker container์์ build๋ฅผ ์งํํ๋
docker multi stage build
๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ง ์๊ณ , ํ๋ก์ ํธ์์ build ํ dist ํด๋๋ฅผVOLUMES
๋ก ๊ณต์ ํ๋ค๋ฉด, ์ฝ๋์ ๋ณ๊ฒฝ์ด ์๋๋ผ๋ ์ด๋ฏธ์ง๋ฅผ ๋ค์ ๋ง๋ค์ง ์๊ณ ๋ฐ๋ก ์คํํ ์ ์์ด ์๊ฐ ๋ญ๋น๋ฅผ ์ต์ํ ํ ์ ์๋ค.