JavaScript์์ ๋์ ๋ชจ๋ ๊ฒ์ฆ์ ๋ง์คํฐํ์ธ์. ํ๋ฌ๊ทธ์ธ ๋ฐ ๋ง์ดํฌ๋ก ํ๋ก ํธ์๋์ ์ ํฉํ ๊ฐ๋ ฅํ๊ณ ํ๋ ฅ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ชจ๋ ํํ์ ํ์ ๊ฒ์ฌ๊ธฐ๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ์ธ์.
JavaScript ๋ชจ๋ ํํ์ ํ์ ๊ฒ์ฌ๊ธฐ: ๋์ ๋ชจ๋ ๊ฒ์ฆ ์ฌ์ธต ๋ถ์
๋์์์ด ์งํํ๋ ํ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ ํ๊ฒฝ์์ JavaScript๋ ํต์ฌ ๊ธฐ์ ๋ก ์๋ฆฌ ์ก๊ณ ์์ต๋๋ค. ํนํ ES ๋ชจ๋(ESM)๊ณผ ๊ฐ์ ๋ชจ๋ ์์คํ ์ ์์กด์ฑ ๊ด๋ฆฌ์ ํผ๋์ ์ง์๋ฅผ ๊ฐ์ ธ์์ต๋๋ค. TypeScript ๋ฐ ESLint์ ๊ฐ์ ๋๊ตฌ๋ ๊ฐ๋ ฅํ ์ ์ ๋ถ์ ๊ณ์ธต์ ์ ๊ณตํ์ฌ ์ฝ๋๊ฐ ์ฌ์ฉ์์๊ฒ ๋๋ฌํ๊ธฐ ์ ์ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์กฐ ์์ฒด๊ฐ ๋์ ์ธ ๊ฒฝ์ฐ์๋ ์ด๋ป๊ฒ ๋ ๊น์? ์ ์ ์๋ ์์ค์์ ๋ฐํ์์ ๋ก๋๋๊ฑฐ๋ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ๊ธฐ๋ฐํ ๋ชจ๋์ ์ด๋ป์ต๋๊น? ์ฌ๊ธฐ์์ ์ ์ ๋ถ์์ด ํ๊ณ์ ๋๋ฌํ๊ณ ์๋ก์ด ๋ฐฉ์ด ๊ณ์ธต์ด ํ์ํฉ๋๋ค. ๋ฐ๋ก ๋์ ๋ชจ๋ ๊ฒ์ฆ์ ๋๋ค.
์ด ๊ธฐ์ฌ์์๋ "๋ชจ๋ ํํ์ ํ์ ๊ฒ์ฌ๊ธฐ"๋ผ๊ณ ๋ถ๋ฅด๋ ๊ฐ๋ ฅํ ํจํด์ ์๊ฐํฉ๋๋ค. ์ด๋ ๋ฐํ์์ ๋์ ์ผ๋ก ๊ฐ์ ธ์จ JavaScript ๋ชจ๋์ ๋ชจ์, ์ ํ ๋ฐ ๊ณ์ฝ์ ๊ฒ์ฆํ๋ ์ ๋ต์ ๋๋ค. ์ ์ฐํ ํ๋ฌ๊ทธ์ธ ์ํคํ ์ฒ๋ฅผ ๊ตฌ์ถํ๋ , ๋ง์ดํฌ๋ก ํ๋ก ํธ์๋ ์์คํ ์ ๊ตฌ์ฑํ๋ , ๋จ์ํ ์์ฒญ ์ ๊ตฌ์ฑ ์์๋ฅผ ๋ก๋ํ๋ , ์ด ํจํด์ ์ ์ ํ์ดํ์ ์์ ์ฑ๊ณผ ์์ธก ๊ฐ๋ฅ์ฑ์ ๋์ ์ด๊ณ ์์ธกํ ์ ์๋ ๋ฐํ์ ์คํ ์ธ๊ณ๋ก ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
๋ค์์ ์ดํด๋ด ๋๋ค.
- ๋์ ๋ชจ๋ ํ๊ฒฝ์์ ์ ์ ๋ถ์์ ํ๊ณ.
- ๋ชจ๋ ํํ์ ํ์ ๊ฒ์ฌ๊ธฐ ํจํด์ ํต์ฌ ์๋ฆฌ.
- ์ฒ์๋ถํฐ ์์ ์ ๊ฒ์ฌ๊ธฐ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ์ค์ฉ์ ์ธ ๋จ๊ณ๋ณ ๊ฐ์ด๋.
- ๊ธ๋ก๋ฒ ๊ฐ๋ฐ ํ์ ์ ์ฉ ๊ฐ๋ฅํ ๊ณ ๊ธ ๊ฒ์ฆ ์๋๋ฆฌ์ค ๋ฐ ์ค์ ์ฌ์ฉ ์ฌ๋ก.
- ๊ตฌํ์ ์ํ ์ฑ๋ฅ ๊ณ ๋ ค ์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก.
์งํํ๋ JavaScript ๋ชจ๋ ํ๊ฒฝ๊ณผ ๋์ ๋๋ ๋ง
๋ฐํ์ ๊ฒ์ฆ์ ํ์์ฑ์ ์ดํดํ๋ ค๋ฉด ๋จผ์ ์ฐ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ์ฌ๊ธฐ์ ์๋์ง ์ดํดํด์ผ ํฉ๋๋ค. JavaScript ๋ชจ๋์ ์ฌ์ ์ ์ ์ ๋ ์ ๊ตํด์ง๋ ์ฌ์ ์ด์์ต๋๋ค.
๊ธ๋ก๋ฒ ์ํ์์ ๊ตฌ์กฐํ๋ ์ํฌํธ๋ก
์ด๊ธฐ JavaScript ๊ฐ๋ฐ์ ์ข
์ข
<script> ํ๊ทธ๋ฅผ ๊ด๋ฆฌํ๋ ๋ถ์์ ํ ์์
์ด์์ต๋๋ค. ์ด๋ก ์ธํด ๋ณ์๊ฐ ์ถฉ๋ํ ์ ์๋ ์ค์ผ๋ ์ ์ญ ๋ฒ์๊ฐ ๋ฐ์ํ๊ณ , ์์กด์ฑ ์์๋ ๊นจ์ง๊ธฐ ์ฌ์ด ์๋ ํ๋ก์ธ์ค์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ปค๋ฎค๋ํฐ๋ CommonJS(Node.js์์ ๋์คํ๋จ) ๋ฐ AMD(๋น๋๊ธฐ ๋ชจ๋ ์ ์)์ ๊ฐ์ ํ์ค์ ๋ง๋ค์์ต๋๋ค. ์ด๊ฒ๋ค์ ์ค์ํ์ง๋ง ์ธ์ด ์์ฒด์๋ ๊ธฐ๋ณธ ์๋ฃจ์
์ด ์์์ต๋๋ค.
ES ๋ชจ๋(ESM)์ ์
๋ ฅํฉ๋๋ค. ECMAScript 2015(ES6)์ ์ผ๋ถ๋ก ํ์คํ๋ ESM์ import ๋ฐ export ๋ฌธ๊ณผ ํจ๊ป ํตํฉ๋ ์ ์ ๋ชจ๋ ๊ตฌ์กฐ๋ฅผ ์ธ์ด์ ๋์
ํ์ต๋๋ค. ์ฌ๊ธฐ์ ํต์ฌ ๋จ์ด๋ ์ ์ ์
๋๋ค. ์ด๋ค ๋ชจ๋์ด ์ด๋ค ๋ชจ๋์ ์์กดํ๋์ง ๋ชจ๋ ๊ทธ๋ํ๋ ์ฝ๋๋ฅผ ์คํํ์ง ์๊ณ ๋ ํ์ธํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด Webpack ๋ฐ Rollup๊ณผ ๊ฐ์ ๋ฒ๋ค๋ฌ๊ฐ ํธ๋ฆฌ ์์ดํน์ ์ํํ ์ ์๋๋ก ํ๊ณ TypeScript๊ฐ ํ์ผ ์ ์ฒด์์ ์ ํ ์ ์๋ฅผ ๋ฐ๋ฅผ ์ ์๋๋ก ํ๋ ๊ฒ์
๋๋ค.
๋์ import()์ ๋ถ์
์ ์ ๊ทธ๋ํ๋ ์ต์ ํ์ ์ข์ง๋ง ์ต์ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํด ์ญ๋์ฑ์ ์๊ตฌํฉ๋๋ค. ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ํ์ํ๊ธฐ ์ํด ์ ์ฒด ๋ฉํฐ ๋ฉ๊ฐ๋ฐ์ดํธ ์ ํ๋ฆฌ์ผ์ด์
๋ฒ๋ค์ ๋ก๋ํ๊ณ ์ถ์ง ์์ต๋๋ค. ์ด๋ก ์ธํด ๋์ import() ํํ์์ด ๋์
๋์์ต๋๋ค.
์ ์ counterpart์ ๋ฌ๋ฆฌ import()๋ Promise๋ฅผ ๋ฐํํ๋ ํจ์์ ๊ฐ์ ๊ตฌ์ฑ์
๋๋ค. ์์ฒญ ์ ๋ชจ๋์ ๋ก๋ํ ์ ์์ต๋๋ค.
// ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ ๋๋ง ๋ฌด๊ฑฐ์ด ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ก๋
const showReportButton = document.getElementById('show-report');
showReportButton.addEventListener('click', async () => {
try {
const ChartingLibrary = await import('./heavy-charting-library.js');
ChartingLibrary.renderChart();
} catch (error) {
console.error("์ฐจํธ ๋ชจ๋์ ๋ก๋ํ์ง ๋ชปํ์ต๋๋ค.", error);
}
});
์ด ๊ธฐ๋ฅ์ ์ฝ๋ ๋ถํ ๋ฐ ์ง์ฐ ๋ก๋ฉ๊ณผ ๊ฐ์ ์ต์ ์ฑ๋ฅ ํจํด์ ๊ทผ๊ฐ์
๋๋ค. ๊ทธ๋ฌ๋ ๊ทผ๋ณธ์ ์ธ ๋ถํ์ค์ฑ์ ๋์
ํฉ๋๋ค. ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ ์๊ฐ ์ฐ๋ฆฌ๋ './heavy-charting-library.js'๊ฐ ๊ฒฐ๊ตญ ๋ก๋๋ ๋ ํน์ ๋ชจ์, ์ฆ ์ด ๊ฒฝ์ฐ renderChart๋ผ๋ ์ด๋ฆ์ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ๊ฐ๋๋ค๋ ๊ฐ์ ์ ํฉ๋๋ค. ์ ์ ๋ถ์ ๋๊ตฌ๋ ๋ชจ๋์ด ์์ฒด ํ๋ก์ ํธ ๋ด์ ์๋ ๊ฒฝ์ฐ ์ข
์ข
์ด๋ฅผ ์ถ๋ก ํ ์ ์์ง๋ง ๋ชจ๋ ๊ฒฝ๋ก๊ฐ ๋์ ์ผ๋ก ๊ตฌ์ฑ๋๊ฑฐ๋ ๋ชจ๋์ด ์ธ๋ถ์ ์ ๋ขฐํ ์ ์๋ ์์ค์์ ์ ๊ณต๋๋ ๊ฒฝ์ฐ์๋ ๋ฌด๋ ฅํฉ๋๋ค.
์ ์ ๋ ๋์ ๊ฒ์ฆ: ๊ฐ๊ทน ํด์
ํจํด์ ์ดํดํ๋ ค๋ฉด ๋ ๊ฐ์ง ๊ฒ์ฆ ์ฒ ํ์ ๊ตฌ๋ณํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ ์ ๋ถ์: ์ปดํ์ผ ์๊ฐ ๊ฐ๋์ธ
TypeScript, Flow ๋ฐ ESLint์ ๊ฐ์ ๋๊ตฌ๋ ์ ์ ๋ถ์์ ์ํํฉ๋๋ค. ์ฝ๋๋ฅผ ์คํํ์ง ์๊ณ ์ฝ๊ณ ์ ์ธ๋ ์ ์(.d.ts ํ์ผ, JSDoc ์ฃผ์ ๋๋ ์ธ๋ผ์ธ ์ ํ)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์กฐ์ ์ ํ์ ๋ถ์ํฉ๋๋ค.
- ์ฅ์ : ๊ฐ๋ฐ ์ฃผ๊ธฐ ์ด๊ธฐ์ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ , ๋ฐ์ด๋ ์๋ ์์ฑ ๋ฐ IDE ํตํฉ์ ์ ๊ณตํ๋ฉฐ, ๋ฐํ์ ์ฑ๋ฅ ๋น์ฉ์ด ์์ต๋๋ค.
- ๋จ์ : ๋ฐํ์์๋ง ์๋ ค์ง ๋ฐ์ดํฐ ๋๋ ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ๊ฒ์ฆํ ์ ์์ต๋๋ค. ๋ฐํ์ ํ์ค์ด ์ ์ ๊ฐ์ ๊ณผ ์ผ์นํ๋ค๊ณ ๋ฏฟ์ต๋๋ค. ์ฌ๊ธฐ์๋ API ์๋ต, ์ฌ์ฉ์ ์ ๋ ฅ ๋ฐ ๋์ ์ผ๋ก ๋ก๋๋ ๋ชจ๋์ ๋ด์ฉ์ด ํฌํจ๋ฉ๋๋ค.
๋์ ๊ฒ์ฆ: ๋ฐํ์ ๊ฒ์ดํธํคํผ
๋์ ๊ฒ์ฆ์ ์ฝ๋๊ฐ ์คํ๋๋ ๋์ ๋ฐ์ํฉ๋๋ค. ๋ฐ์ดํฐ์ ์์กด์ฑ์ด ์์๋๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์๋์ง ๋ช ์์ ์ผ๋ก ํ์ธํ๋ ๋ฐฉ์ด์ ํ๋ก๊ทธ๋๋ฐ์ ํ ํํ์ ๋๋ค.
- ์ฅ์ : ์์ค์ ๊ด๊ณ์์ด ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆํ ์ ์์ต๋๋ค. ์๊ธฐ์น ์์ ๋ฐํ์ ๋ณ๊ฒฝ์ ๋ํ ๊ฐ๋ ฅํ ์์ ๋ง์ ์ ๊ณตํ๊ณ ์ค๋ฅ๊ฐ ์์คํ ์ ์ฒด์ ์ ํ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
- ๋จ์ : ๋ฐํ์ ์ฑ๋ฅ ๋น์ฉ์ด ๋ฐ์ํ๊ณ ์ฝ๋์ ์ฅํฉํจ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ค๋ฅ๋ ์ปดํ์ผ์ด ์๋ ์คํ ์ค์ ์๋ช ์ฃผ๊ธฐ ํ๋ฐ์ ํฌ์ฐฉ๋ฉ๋๋ค.
๋ชจ๋ ํํ์ ํ์ ๊ฒ์ฌ๊ธฐ๋ ES ๋ชจ๋์ ๋ง๊ฒ ํน๋ณํ ์กฐ์ ๋ ๋์ ๊ฒ์ฆ์ ํ ํํ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ ์ธ๊ณ๊ฐ ๋ฐํ์ ๋ชจ๋์ ๋ถํ์คํ ์ธ๊ณ๋ฅผ ๋ง๋๋ ๋์ ๊ฒฝ๊ณ์์ ๊ณ์ฝ์ ์ํํ๋ ๋ธ๋ฆฌ์ง ์ญํ ์ ํฉ๋๋ค.
๋ชจ๋ ํํ์ ํ์ ๊ฒ์ฌ๊ธฐ ํจํด ์๊ฐ
ํต์ฌ์ ์ผ๋ก ํจํด์ ๋๋ผ์ธ ์ ๋๋ก ๊ฐ๋จํฉ๋๋ค. ์ธ ๊ฐ์ง ์ฃผ์ ๊ตฌ์ฑ ์์๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
- ๋ชจ๋ ์คํค๋ง: ๋ชจ๋์ ์์๋๋ "๋ชจ์" ๋๋ "๊ณ์ฝ"์ ์ ์ํ๋ ์ ์ธ์ ๊ฐ์ฒด์ ๋๋ค. ์ด ์คํค๋ง๋ ์ด๋ค ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์กด์ฌํด์ผ ํ๋์ง, ํด๋น ์ ํ์ด ๋ฌด์์ธ์ง, ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ์ ์์ ์ ํ์ ์ง์ ํฉ๋๋ค.
- ๊ฒ์ฆ๊ธฐ ํจ์: ์ค์ ๋ชจ๋ ๊ฐ์ฒด(
import()Promise์์ ํ์ธ๋จ)์ ์คํค๋ง๋ฅผ ๊ฐ์ ธ์์ ๋์ ๋น๊ตํ๋ ํจ์์ ๋๋ค. ๋ชจ๋์ด ์คํค๋ง์ ์ ์๋ ๊ณ์ฝ์ ์ถฉ์กฑํ๋ฉด ํจ์๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋ฐํ๋ฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ค๋ช ์ ์ธ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. - ํตํฉ ์ง์ : ๋์
import()ํธ์ถ ์งํ์ ๊ฒ์ฆ๊ธฐ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋กasyncํจ์ ๋ด์์ ์ฌ์ฉ๋๊ณtry...catch๋ธ๋ก์ผ๋ก ๋๋ฌ์ธ์ฌ ๋ก๋ฉ ๋ฐ ๊ฒ์ฆ ์คํจ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
์ด๋ก ์์ ์ค์ต์ผ๋ก ์ด๋ํ์ฌ ์์ฒด ๊ฒ์ฌ๊ธฐ๋ฅผ ๊ตฌ์ถํด ๋ณด๊ฒ ์ต๋๋ค.
์ฒ์๋ถํฐ ๋ชจ๋ ํํ์ ๊ฒ์ฌ๊ธฐ ๊ตฌ์ถ
๊ฐ๋จํ๋ฉด์๋ ํจ๊ณผ์ ์ธ ๋ชจ๋ ๊ฒ์ฆ๊ธฐ๋ฅผ ๋ง๋ค ๊ฒ์ ๋๋ค. ๋ค์ํ ์์ ฏ ํ๋ฌ๊ทธ์ธ์ ๋์ ์ผ๋ก ๋ก๋ํ ์ ์๋ ๋์๋ณด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ค๊ณ ์์ํด ๋ณด์ญ์์ค.
1๋จ๊ณ: ์์ ํ๋ฌ๊ทธ์ธ ๋ชจ๋
๋จผ์ ์ ํจํ ํ๋ฌ๊ทธ์ธ ๋ชจ๋์ ์ ์ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ๋ชจ๋์ ๊ตฌ์ฑ ๊ฐ์ฒด, ๋ ๋๋ง ํจ์ ๋ฐ ์์ ฏ ์์ฒด์ ๋ํ ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ๋ด๋ณด๋ด์ผ ํฉ๋๋ค.
ํ์ผ: /plugins/weather-widget.js
๋ก๋ ์ค...export const version = '1.0.0';
export const config = {
requiresApiKey: true,
updateInterval: 300000 // 5 ๋ถ
};
export function render(element) {
element.innerHTML = '๋ ์จ ์์ ฏ
2๋จ๊ณ: ์คํค๋ง ์ ์
๋ค์์ผ๋ก ํ๋ฌ๊ทธ์ธ ๋ชจ๋์ด ์ค์ํด์ผ ํ๋ ๊ณ์ฝ์ ์ค๋ช ํ๋ ์คํค๋ง ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค. ์คํค๋ง๋ ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ ๋ฐ ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ์ ๋ํ ๊ธฐ๋๋ฅผ ์ ์ํฉ๋๋ค.
const WIDGET_MODULE_SCHEMA = {
exports: {
// ํน์ ์ ํ์ ๋ช
๋ช
๋ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์์ํฉ๋๋ค.
named: {
version: 'string',
config: 'object',
render: 'function'
},
// ํด๋์ค์ ๋ํ ํจ์์ธ ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์์ํฉ๋๋ค.
default: 'function'
}
};
์ด ์คํค๋ง๋ ์ ์ธ์ ์ด๊ณ ์ฝ๊ธฐ ์ฝ์ต๋๋ค. "์์ ฏ"์ด ๋๊ธฐ ์ํ ๋ชจ๋ ๋ชจ๋์ ๋ํ API ๊ณ์ฝ์ ๋ช ํํ๊ฒ ์ ๋ฌํฉ๋๋ค.
3๋จ๊ณ: ๊ฒ์ฆ๊ธฐ ํจ์ ๋ง๋ค๊ธฐ
์ด์ ํต์ฌ ๋ ผ๋ฆฌ๋ฅผ ์ํด. `validateModule` ํจ์๋ ์คํค๋ง๋ฅผ ๋ฐ๋ณตํ๊ณ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ํ์ธํฉ๋๋ค.
/**
* ์คํค๋ง์ ๋ํด ๋์ ์ผ๋ก ๊ฐ์ ธ์จ ๋ชจ๋์ ๊ฒ์ฆํฉ๋๋ค.
* @param {object} module - import() ํธ์ถ์ ๋ชจ๋ ๊ฐ์ฒด์
๋๋ค.
* @param {object} schema - ์์๋๋ ๋ชจ๋ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๋ ์คํค๋ง์
๋๋ค.
* @param {string} moduleName - ๋ ๋์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ํ ๋ชจ๋ ์๋ณ์์
๋๋ค.
* @throws {Error} ๊ฒ์ฆ์ ์คํจํ๋ฉด.
*/
function validateModule(module, schema, moduleName = '์ ์ ์๋ ๋ชจ๋') {
// ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ ํ์ธ
if (schema.exports.default) {
if (!('default' in module)) {
throw new Error(`[${moduleName}] ๊ฒ์ฆ ์ค๋ฅ: ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์์ต๋๋ค.`);
}
const defaultExportType = typeof module.default;
if (defaultExportType !== schema.exports.default) {
throw new Error(
`[${moduleName}] ๊ฒ์ฆ ์ค๋ฅ: ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ ์ ํ์ด ์๋ชป๋์์ต๋๋ค. ์์๋๋ ์ ํ์ '${schema.exports.default}'์ด๊ณ , ๊ฐ์ ธ์จ ์ ํ์ '${defaultExportType}'์
๋๋ค.`
);
}
}
// ๋ช
๋ช
๋ ๋ด๋ณด๋ด๊ธฐ ํ์ธ
if (schema.exports.named) {
for (const exportName in schema.exports.named) {
if (!(exportName in module)) {
throw new Error(`[${moduleName}] ๊ฒ์ฆ ์ค๋ฅ: ๋ช
๋ช
๋ ๋ด๋ณด๋ด๊ธฐ '${exportName}'๊ฐ ์์ต๋๋ค.`);
}
const expectedType = schema.exports.named[exportName];
const actualType = typeof module[exportName];
if (actualType !== expectedType) {
throw new Error(
`[${moduleName}] ๊ฒ์ฆ ์ค๋ฅ: ๋ช
๋ช
๋ ๋ด๋ณด๋ด๊ธฐ '${exportName}' ์ ํ์ด ์๋ชป๋์์ต๋๋ค. ์์๋๋ ์ ํ์ '${expectedType}'์ด๊ณ , ๊ฐ์ ธ์จ ์ ํ์ '${actualType}'์
๋๋ค.`
);
}
}
}
console.log(`[${moduleName}] ๋ชจ๋์ด ์ฑ๊ณต์ ์ผ๋ก ๊ฒ์ฆ๋์์ต๋๋ค.`);
}
์ด ํจ์๋ ํน์ ํ๊ณ ์คํ ๊ฐ๋ฅํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ฉฐ, ์ด๋ ํ์ฌ ๋๋ ๋์ ์ผ๋ก ์์ฑ๋ ๋ชจ๋์ ๋ฌธ์ ๋ฅผ ๋๋ฒ๊น ํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
4๋จ๊ณ: ๋ชจ๋ ํจ๊ป ๋ฃ๊ธฐ
๋ง์ง๋ง์ผ๋ก ํ๋ฌ๊ทธ์ธ์ ๋ก๋ํ๊ณ ๊ฒ์ฆํ๋ ํจ์๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. ์ด ํจ์๋ ๋์ ๋ก๋ฉ ์์คํ ์ ๊ธฐ๋ณธ ์ง์ ์ ์ด ๋ฉ๋๋ค.
async function loadWidgetPlugin(path) {
try {
console.log(`๋ค์ ์์น์์ ์์ ฏ์ ๋ก๋ํ๋ ค๊ณ ์๋ํฉ๋๋ค: ${path}`);
const widgetModule = await import(path);
// ์ค์ํ ๊ฒ์ฆ ๋จ๊ณ!
validateModule(widgetModule, WIDGET_MODULE_SCHEMA, path);
// ๊ฒ์ฆ์ ํต๊ณผํ๋ฉด ๋ชจ๋์ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์์ ํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
const container = document.getElementById('widget-container');
widgetModule.render(container);
const widgetInstance = new widgetModule.default('YOUR_API_KEY');
const data = await widgetInstance.fetchData();
console.log('์์ ฏ ๋ฐ์ดํฐ:', data);
return widgetModule;
} catch (error) {
console.error(`๋ค์ ์์น์์ ์์ ฏ์ ๋ก๋ํ๊ฑฐ๋ ๊ฒ์ฆํ์ง ๋ชปํ์ต๋๋ค: '${path}'.`);
console.error(error);
// ์ ์ฌ์ ์ผ๋ก ์ฌ์ฉ์์๊ฒ ๋์ฒด UI๋ฅผ ํ์ํฉ๋๋ค.
return null;
}
}
// ์ฌ์ฉ ์:
loadWidgetPlugin('/plugins/weather-widget.js');
์ด์ ๊ท์ ์ ์ค์ํ์ง ์๋ ๋ชจ๋์ ๋ก๋ํ๋ ค๊ณ ํ๋ฉด ์ด๋ป๊ฒ ๋๋์ง ์ดํด๋ด ์๋ค.
ํ์ผ: /plugins/faulty-widget.js
// 'version' ๋ด๋ณด๋ด๊ธฐ๊ฐ ๋๋ฝ๋์์ต๋๋ค.
// 'render'๋ ํจ์๊ฐ ์๋ ๊ฐ์ฒด์
๋๋ค.
export const config = { requiresApiKey: false };
export const render = { message: 'ํจ์์ฌ์ผ ํฉ๋๋ค!' };
export default () => {
console.log("์ ๋ ํด๋์ค๊ฐ ์๋ ๊ธฐ๋ณธ ํจ์์
๋๋ค.");
};
loadWidgetPlugin('/plugins/faulty-widget.js')๋ฅผ ํธ์ถํ๋ฉด `validateModule` ํจ์๊ฐ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ ๋ฐ์์์ผ `widgetModule.render๊ฐ ํจ์๊ฐ ์๋` ๋๋ ์ ์ฌํ ๋ฐํ์ ์ค๋ฅ๋ก ์ธํด ์ ํ๋ฆฌ์ผ์ด์
์ด ์ถฉ๋ํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. ๋์ ์ฝ์์ ๋ช
ํํ ๋ก๊ทธ๊ฐ ํ์๋ฉ๋๋ค.
๋ค์ ์์น์์ ์์ ฏ์ ๋ก๋ํ๊ฑฐ๋ ๊ฒ์ฆํ์ง ๋ชปํ์ต๋๋ค: '/plugins/faulty-widget.js'.
์ค๋ฅ: [/plugins/faulty-widget.js] ๊ฒ์ฆ ์ค๋ฅ: ๋ช
๋ช
๋ ๋ด๋ณด๋ด๊ธฐ 'version'์ด ์์ต๋๋ค.
`catch` ๋ธ๋ก์ ์ด๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์ ์ผ๋ก ์ ์ง๋ฉ๋๋ค.
๊ณ ๊ธ ๊ฒ์ฆ ์๋๋ฆฌ์ค
๊ธฐ๋ณธ `typeof` ํ์ธ์ ๊ฐ๋ ฅํ์ง๋ง ํจํด์ ํ์ฅํ์ฌ ๋ ๋ณต์กํ ๊ณ์ฝ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ฌ์ธต ๊ฐ์ฒด ๋ฐ ๋ฐฐ์ด ๊ฒ์ฆ
๋ด๋ณด๋ธ `config` ๊ฐ์ฒด๊ฐ ํน์ ๋ชจ์์ ๊ฐ๋๋ก ํด์ผ ํ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? 'object'์ ๋ํ ๊ฐ๋จํ `typeof` ํ์ธ์ผ๋ก๋ ์ถฉ๋ถํ์ง ์์ต๋๋ค. ์ด๊ฒ์ ์ ์ฉ ์คํค๋ง ๊ฒ์ฆ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํฉํ๊ธฐ์ ์๋ฒฝํ ์ฅ์์ ๋๋ค. Zod, Yup ๋๋ Joi์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด์ ํ์ํฉ๋๋ค.
Zod๋ฅผ ์ฌ์ฉํ์ฌ ๋ณด๋ค ํํ๋ ฅ ์๋ ์คํค๋ง๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ดํด๋ด ์๋ค.
// 1. ๋จผ์ Zod๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค.
// import { z } from 'zod';
// 2. Zod๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๊ฐ๋ ฅํ ์คํค๋ง๋ฅผ ์ ์ํฉ๋๋ค.
const ZOD_WIDGET_SCHEMA = z.object({
version: z.string(),
config: z.object({
requiresApiKey: z.boolean(),
updateInterval: z.number().positive().optional()
}),
render: z.function().args(z.instanceof(HTMLElement)).returns(z.void()),
default: z.function() // Zod๋ ํด๋์ค ์์ฑ์๋ฅผ ์ฝ๊ฒ ๊ฒ์ฆํ ์ ์์ง๋ง 'function'์ ์ข์ ์์์
๋๋ค.
});
// 3. ๊ฒ์ฆ ๋
ผ๋ฆฌ ์
๋ฐ์ดํธ
async function loadAndValidateWithZod(path) {
try {
const widgetModule = await import(path);
// Zod์ parse ๋ฉ์๋๋ ์คํจ ์ ๊ฒ์ฆํ๊ณ ๋ฐ์์ํต๋๋ค.
ZOD_WIDGET_SCHEMA.parse(widgetModule);
console.log(`[${path}] ๋ชจ๋์ด Zod๋ก ์ฑ๊ณต์ ์ผ๋ก ๊ฒ์ฆ๋์์ต๋๋ค.`);
return widgetModule;
} catch (error) {
console.error(`๋ค์ ์์น์์ ๊ฒ์ฆ์ ์คํจํ์ต๋๋ค: ${path}:`, error.errors);
return null;
}
}
Zod์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ค์ฒฉ๋ ๊ฐ์ฒด, ๋ฐฐ์ด, ์ด๊ฑฐํ ๋ฐ ๊ธฐํ ๋ณต์กํ ์ ํ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ์ฌ ์คํค๋ง๋ฅผ ๋์ฑ ๊ฐ๋ ฅํ๊ณ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
ํจ์ ์๊ทธ๋์ฒ ๊ฒ์ฆ
ํจ์์ ์ ํํ ์๊ทธ๋์ฒ(์ธ์ ์ ํ ๋ฐ ๋ฐํ ์ ํ)๋ฅผ ๊ฒ์ฆํ๋ ๊ฒ์ ์ผ๋ฐ JavaScript์์๋ ์ ๋ช ๋์ต๋๋ค. Zod์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด๋ ์ ๋ ๋์์ด ๋์ง๋ง ์ค์ฉ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ํด๋น ์ ์์ ์ ์ธ๋ ์์ ์ธ์ ์๋ฅผ ๋ํ๋ด๋ ํจ์์ `length` ์์ฑ์ ํ์ธํ๋ ๊ฒ์ ๋๋ค.
// ๊ฒ์ฆ๊ธฐ์์ ํจ์ ๋ด๋ณด๋ด๊ธฐ์ ๊ฒฝ์ฐ:
const expectedArgCount = 1;
if (module.render.length !== expectedArgCount) {
throw new Error(`๊ฒ์ฆ ์ค๋ฅ: 'render' ํจ์๋ ${expectedArgCount}๊ฐ์ ์ธ์๋ฅผ ์์ํ์ง๋ง ${module.render.length}๊ฐ๋ฅผ ์ ์ธํฉ๋๋ค.`);
}
์ฐธ๊ณ : ์ด๊ฒ์ ์๋ฒฝํ์ง ์์ต๋๋ค. ๋๋จธ์ง ๋งค๊ฐ๋ณ์, ๊ธฐ๋ณธ ๋งค๊ฐ๋ณ์ ๋๋ ๊ตฌ์กฐํ๋ ์ธ์๋ฅผ ๊ณ ๋ คํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ์ฉํ๊ณ ๊ฐ๋จํ ๊ฑด์ ์ฑ ๊ฒ์ฌ ์ญํ ์ ํฉ๋๋ค.
๊ธ๋ก๋ฒ ์ปจํ ์คํธ์์์ ์ค์ ์ฌ์ฉ ์ฌ๋ก
์ด ํจํด์ ๋จ์ํ ์ด๋ก ์ ์ด๋์ด ์๋๋๋ค. ์ ์ธ๊ณ ๊ฐ๋ฐ ํ์ด ์ง๋ฉดํ ์ค์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
1. ํ๋ฌ๊ทธ์ธ ์ํคํ ์ฒ
์ด๊ฒ์ ๊ณ ์ ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค. IDE(VS Code), CMS(WordPress) ๋๋ ๋์์ธ ๋๊ตฌ(Figma)์ ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ฌ ํ๋ฌ๊ทธ์ธ์ ์์กดํฉ๋๋ค. ๋ชจ๋ ๊ฒ์ฆ๊ธฐ๋ ํต์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ํ๋ฌ๊ทธ์ธ์ ๋ก๋ํ๋ ๊ฒฝ๊ณ์์ ํ์์ ์ ๋๋ค. ํ๋ฌ๊ทธ์ธ์ด ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ถฉ๋์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ฌ๋ฐ๋ฅด๊ฒ ํตํฉํ๊ธฐ ์ํด ํ์ํ ํจ์(์: `ํ์ฑํ`, `๋นํ์ฑํ`) ๋ฐ ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋์ง ํ์ธํฉ๋๋ค.
2. ๋ง์ดํฌ๋ก ํ๋ก ํธ์๋
๋ง์ดํฌ๋ก ํ๋ก ํธ์๋ ์ํคํ ์ฒ์์ ์ข ์ข ๋ค๋ฅธ ์ง๋ฆฌ์ ์์น์ ์๋ ๋ค๋ฅธ ํ์ ๋ ํฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ผ๋ถ๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฐ๋ฐํฉ๋๋ค. ๊ธฐ๋ณธ ์ ํ๋ฆฌ์ผ์ด์ ์ ธ์ ์ด๋ฌํ ๋ง์ดํฌ๋ก ํ๋ก ํธ์๋๋ฅผ ๋์ ์ผ๋ก ๋ก๋ํฉ๋๋ค. ๋ชจ๋ ํํ์ ๊ฒ์ฌ๊ธฐ๋ ํตํฉ ์ง์ ์์ "API ๊ณ์ฝ ์ํ์" ์ญํ ์ ํ์ฌ ๋ง์ดํฌ๋ก ํ๋ก ํธ์๋๊ฐ ๋ ๋๋ง์ ์๋ํ๊ธฐ ์ ์ ์์๋๋ ๋ง์ดํ ํจ์ ๋๋ ๊ตฌ์ฑ ์์๋ฅผ ๋ ธ์ถํ๋์ง ํ์ธํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํ์ด ๋ถ๋ฆฌ๋๊ณ ๋ฐฐํฌ ์คํจ๊ฐ ์์คํ ์ ์ฒด์ ๊ณ๋จ์์ผ๋ก ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
3. ๋์ ๊ตฌ์ฑ ์์ ํ ๋ง ๋๋ ๋ฒ์ ๊ด๋ฆฌ
์ฌ์ฉ์์ ๊ตญ๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฒฐ์ ์ฒ๋ฆฌ ๊ตฌ์ฑ ์์๋ฅผ ๋ก๋ํด์ผ ํ๋ ๊ตญ์ ์ ์ ์๊ฑฐ๋ ์ฌ์ดํธ๋ฅผ ์์ํด ๋ณด์ญ์์ค. ๊ฐ ๊ตฌ์ฑ ์์๋ ์์ฒด ๋ชจ๋์ ์์ ์ ์์ต๋๋ค.
const userCountry = 'DE'; // ๋
์ผ
const paymentModulePath = `/components/payment/${userCountry}.js`;
// ๊ฒ์ฆ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตญ๊ฐ๋ณ ๋ชจ๋์ด
// ์์๋๋ 'PaymentProcessor' ํด๋์ค ๋ฐ 'getFees' ํจ์๋ฅผ ๋
ธ์ถํ๋์ง ํ์ธํฉ๋๋ค.
const paymentModule = await loadAndValidate(paymentModulePath, PAYMENT_SCHEMA);
if (paymentModule) {
// ๊ฒฐ์ ํ๋ฆ์ ์งํํฉ๋๋ค.
}
์ด๋ฅผ ํตํด ๋ชจ๋ ๊ตญ๊ฐ๋ณ ๊ตฌํ์ด ํต์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ ์ธํฐํ์ด์ค๋ฅผ ์ค์ํ๋๋ก ๋ณด์ฅํฉ๋๋ค.
4. A/B ํ ์คํธ ๋ฐ ๊ธฐ๋ฅ ํ๋๊ทธ
A/B ํ ์คํธ๋ฅผ ์คํํ ๋ ํ ์ฌ์ฉ์ ๊ทธ๋ฃน์ ๋ํด `component-variant-A.js`๋ฅผ ๋์ ์ผ๋ก ๋ก๋ํ๊ณ ๋ค๋ฅธ ์ฌ์ฉ์ ๊ทธ๋ฃน์ ๋ํด `component-variant-B.js`๋ฅผ ๋ก๋ํ ์ ์์ต๋๋ค. ๊ฒ์ฆ๊ธฐ๋ ๋ด๋ถ ์ฐจ์ด์๋ ๋ถ๊ตฌํ๊ณ ๋ ๋ณํ์ด ๋์ผํ ๊ณต์ฉ API๋ฅผ ๋ ธ์ถํ๋ฏ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋จธ์ง ๋ถ๋ถ์ด ์๋ก ์ํธ ๊ตํ์ ์ผ๋ก ์ํธ ์์ฉํ ์ ์๋๋ก ํฉ๋๋ค.
์ฑ๋ฅ ๊ณ ๋ ค ์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
๋ฐํ์ ๊ฒ์ฆ์ ๋ฌด๋ฃ๊ฐ ์๋๋๋ค. CPU ์ฃผ๊ธฐ๋ฅผ ์๋นํ๊ณ ๋ชจ๋ ๋ก๋ฉ์ ์ฝ๊ฐ์ ์ง์ฐ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ํฅ์ ์ํํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๊ฐ๋ฐ ์ ์ฌ์ฉ, ํ๋ก๋์ ์ ๊ธฐ๋ก: ์ฑ๋ฅ์ ์ค์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ ๊ฐ๋ฐ ๋ฐ ์คํ ์ด์ง ํ๊ฒฝ์์ ์ ์ฒด์ ์ด๊ณ ์๊ฒฉํ ๊ฒ์ฆ(์ค๋ฅ ๋ฐ์)์ ์คํํ๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์์ต๋๋ค. ํ๋ก๋์ ์์๋ ๊ฒ์ฆ ์คํจ๊ฐ ์คํ์ ์ค๋จํ์ง ์๊ณ ๋์ ์ค๋ฅ ์ถ์ ์๋น์ค์ ๋ณด๊ณ ๋๋ "๋ก๊น ๋ชจ๋"๋ก ์ ํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฌ์ฉ์ ๊ฒฝํ์ ์ํฅ์ ์ฃผ์ง ์๊ณ ๊ฐ์์ฑ์ ํ๋ณดํ ์ ์์ต๋๋ค.
- ๊ฒฝ๊ณ์์ ๊ฒ์ฆ: ๋ชจ๋ ๋์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๊ฒ์ฆํ ํ์๋ ์์ต๋๋ค. ํ์ฌ ์ฝ๋๊ฐ ๋ก๋๋๋ ์์คํ ์ ์ค์ํ ๊ฒฝ๊ณ, ๋ง์ดํฌ๋ก ํ๋ก ํธ์๋๊ฐ ์ฐ๊ฒฐ๋๋ ์์น ๋๋ ๋ค๋ฅธ ํ์ ๋ชจ๋์ด ํตํฉ๋๋ ์์น์ ์ง์คํ์ญ์์ค.
- ๊ฒ์ฆ ๊ฒฐ๊ณผ ์บ์: ๋์ผํ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ์ฌ๋ฌ ๋ฒ ๋ก๋ํ๋ ๊ฒฝ์ฐ ๋ค์ ๊ฒ์ฆํ ํ์๊ฐ ์์ต๋๋ค. ๊ฒ์ฆ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ ์ ์์ต๋๋ค. ๊ฐ๋จํ `Map`์ ์ฌ์ฉํ์ฌ ๊ฐ ๋ชจ๋ ๊ฒฝ๋ก์ ๊ฒ์ฆ ์ํ๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค.
const validationCache = new Map();
async function loadAndValidateCached(path, schema) {
if (validationCache.get(path) === 'valid') {
return import(path);
}
if (validationCache.get(path) === 'invalid') {
throw new Error(`๋ชจ๋ ${path}๊ฐ ์ ํจํ์ง ์์ ๊ฒ์ผ๋ก ์๋ ค์ ธ ์์ต๋๋ค.`);
}
try {
const module = await import(path);
validateModule(module, schema, path);
validationCache.set(path, 'valid');
return module;
} catch (error) {
validationCache.set(path, 'invalid');
throw error;
}
}
๊ฒฐ๋ก : ๋ณด๋ค ํ๋ ฅ์ ์ธ ์์คํ ๊ตฌ์ถ
์ ์ ๋ถ์์ JavaScript ๊ฐ๋ฐ์ ์ ๋ขฐ์ฑ์ ๊ทผ๋ณธ์ ์ผ๋ก ๊ฐ์ ํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ๋์ฑ ๋์ ์ด๊ณ ๋ถ์ฐ๋จ์ ๋ฐ๋ผ ์์ํ๊ฒ ์ ์ ์ ๊ทผ ๋ฐฉ์์ ํ๊ณ๋ฅผ ์ธ์ํด์ผ ํฉ๋๋ค. ๋์ import()๋ก ๋์
๋ ๋ถํ์ค์ฑ์ ๊ฒฐํจ์ด ์๋๋ผ ๊ฐ๋ ฅํ ์ํคํ
์ฒ ํจํด์ ๊ฐ๋ฅํ๊ฒ ํ๋ ๊ธฐ๋ฅ์
๋๋ค.
๋ชจ๋ ํํ์ ํ์ ๊ฒ์ฌ๊ธฐ ํจํด์ ์ด๋ฌํ ์ญ๋์ฑ์ ์์ ์๊ฒ ์์ฉํ๋ ๋ฐ ํ์ํ ๋ฐํ์ ์์ ๋ง์ ์ ๊ณตํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์ ๊ฒฝ๊ณ์์ ๊ณ์ฝ์ ๋ช ์์ ์ผ๋ก ์ ์ํ๊ณ ์ํํจ์ผ๋ก์จ ๋์ฑ ํ๋ ฅ์ ์ด๊ณ ๋๋ฒ๊น ํ๊ธฐ ์ฌ์ฐ๋ฉฐ ์๊ธฐ์น ์์ ๋ณ๊ฒฝ์ ๋ํด ๋์ฑ ๊ฐ๋ ฅํ ์์คํ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
์ง์ฐ ๋ก๋๋ ๊ตฌ์ฑ ์์๊ฐ ์๋ ์๊ท๋ชจ ํ๋ก์ ํธ์์ ์์ ํ๋ , ๋๊ท๋ชจ์ ์ ์ญ์ ์ผ๋ก ๋ถ์ฐ๋ ๋ง์ดํฌ๋ก ํ๋ก ํธ์๋ ์์คํ ์์ ์์ ํ๋ , ๋์ ๋ชจ๋ ๊ฒ์ฆ์ ๋ํ ์์ ํฌ์๊ฐ ์์ ์ฑ ๋ฐ ์ ์ง ๊ด๋ฆฌ ์ธก๋ฉด์์ ํฐ ๋ฐฐ๋น๊ธ์ ์ง๋ถํ ์ ์๋ ์์น๋ฅผ ๊ณ ๋ คํ์ญ์์ค. ์ด์์ ์ธ ์กฐ๊ฑด์์๋ง ์๋ํ๋ ๊ฒ์ด ์๋๋ผ ๋ฐํ์ ํ์ค์ ์ง๋ฉดํ์ฌ ๊ฐ๋ ฅํ๊ฒ ์ ์ง๋๋ ์ํํธ์จ์ด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ฌ์ ์๋ฐฉ์ ๋จ๊ณ์ ๋๋ค.