ποΈ λΉλ λ°©μ
μ΄ λ¬Έμλ μ΄ νλ‘μ νΈμμ ν¨ν€μ§λ₯Ό μ΄λ»κ² λΉλνλμ§μ λν μ€λͺ μ μ 곡ν¨μΌλ‘μ, μ΄ νλ‘μ νΈμμ ν¨ν€μ§κ° μ΄λ»κ² λΉλλλμ§μ λν μ΄ν΄λ₯Ό λκΈ° μν΄ μμ±λμμ΅λλ€.
β‘ Vite κΈ°λ° λΉλ
μ΄ νλ‘μ νΈμμ μ 곡λλ ν¨ν€μ§λ€μ Viteλ₯Ό μ¬μ©νμ¬ λΉλλ©λλ€.
ν¨ν€μ§ | λΉλ λ°©μ |
---|---|
packages/browser-utils | Viteβ |
http-clients | Viteβ |
packages/node-utils | Viteβ |
packages/react-utils | Viteβ |
packages/react-ui | Viteβ |
eslint-plugin-sample
ν¨ν€μ§μ κ°μ ESLint νλ¬κ·ΈμΈ ν¨ν€μ§λ λ³λμ λΉλ κ³Όμ μ κ±°μΉμ§ μλλ‘ μ€κ³λμμ΅λλ€.
λμ , ESLint νλ¬κ·ΈμΈ ν¨ν€μ§λ lib
λλ ν 리μ μλ index.js
νμΌμ κ·Έλλ‘ μ¬μ©νλλ‘
package.json
μ files
, main
, exports
νλμ μ€μ λμ΄ μμ΅λλ€.
μ±ν μλ
Vite λ₯Ό μ¬μ©νμ¬ ν¨ν€μ§λ₯Ό λΉλνλ μ΄μ λ λ€μκ³Ό κ°μ΅λλ€:
βκ° ν¨ν€μ§λ€μ npm ν¨ν€μ§λ‘ λ°°ν¬ν κ²μ μ μ λ‘ νμ¬, Viteμ λΉλ κΈ°λ₯μ μ¬μ©νμ¬ κ° ν¨ν€μ§μ μμ€ μ½λλ₯Ό λ²λ€λ§νκ³ , μ΅μ νλ κ²°κ³Όλ¬Όμ μμ±νκΈ° μν¨μ λλ€.β
νΉμ§
μ΄ νλ‘μ νΈμμ μ 곡νλ ν¨ν€μ§λ€μ 곡ν΅μ μΌλ‘ λ€μκ³Ό κ°μ νΉμ§μ κ°λλ‘ μ€κ³λμ΄ μμ΅λλ€:
1) ESModule λ° CommonJS μμ€ν μ§μ
κ° ν¨ν€μ§λ ESModule(.es.js
)κ³Ό CommonJS(.cjs.js
) νμμΌλ‘ λΉλλμ΄, λ€μν νκ²½μμ μ¬μ©ν μ μλλ‘ μ§μν©λλ€.
μ΄λ Vite λΉλ μ€μ μμ λΌμ΄λΈλ¬λ¦¬ λͺ¨λλ₯Ό ν΅ν Rollup μ€μ μ νμ©νμ¬ κ΅¬νλμμ΅λλ€.
/// <reference types="vitest" />
// ... λ€λ₯Έ import λ¬Έλ€
// https://vitejs.dev/config/
export default defineConfig({
// ... λ€λ₯Έ μ€μ λ€ ...
build: {
// ... λ€λ₯Έ μ€μ λ€ ...
lib: {
// ... λ€λ₯Έ μ€μ λ€ ...
formats: ["es", "cjs"], // ESModuleκ³Ό CommonJS νμμΌλ‘ λΉλ
fileName: (format, entryName) => `${entryName}/index.${format}.js`,
},
},
});
2) νμ μ μΈ νμΌ μ 곡
κ° ν¨ν€μ§λ TypeScriptλ‘ μμ±λμ΄ μμΌλ©°, λΉλ μ νμ
μ μΈ νμΌ(.d.ts
)μ μλμΌλ‘ μμ±ν©λλ€.
μ΄λ vite-plugin-dts
νλ¬κ·ΈμΈμ μ¬μ©νμ¬ κ° μνΈλ¦¬λ³λ‘ νμ
μ μΈ νμΌμ μμ±νλλ‘ μ€μ ν¨μΌλ‘μ ꡬνλμμ΅λλ€.
/// <reference types="vitest" />
import { defineConfig } from "vite";
import dtsPlugin from "vite-plugin-dts";
// ... λ€λ₯Έ import λ¬Έλ€
// https://vitejs.dev/config/
export default defineConfig({
plugins: [dtsPlugin({ include: ["src"] }), tsConfigPaths()],
// ... λ€λ₯Έ μ€μ λ€ ...
});
3) νΈλ¦¬ μμ΄νΉ λ° μ½λ μ€ν리ν μ§μ
κ° ν¨ν€μ§λ Viteμ νΈλ¦¬ μμ΄νΉ λ° μ½λ μ€ν리ν κΈ°λ₯μ νμ©νμ¬, μ¬μ©νμ§ μλ μ½λλ λΉλ κ²°κ³Όλ¬Όμ ν¬ν¨λμ§ μλλ‘ μ΅μ νλμ΄ μμ΅λλ€.
μ΄λ κ° ν¨ν€μ§λ€μ package.json
μμ exports
νλλ₯Ό ν΅ν΄ κ° κΈ°λ₯ λ¨μλ€μ μλΈ λͺ¨λλ‘ λΆλ¦¬ν¨κ³Ό λμμ,
{
"exports": {
"./dom": {
"types": "./dist/dom/index.d.ts",
"import": "./dist/dom/index.es.js",
"require": "./dist/dom/index.cjs.js"
},
"./msw": {
"types": "./dist/msw/index.d.ts",
"import": "./dist/msw/index.es.js",
"require": "./dist/msw/index.cjs.js"
},
"./string": {
"types": "./dist/string/index.d.ts",
"import": "./dist/string/index.es.js",
"require": "./dist/string/index.cjs.js"
}
},
// ... λ€λ₯Έ μ€μ λ€ ...
}
μ΄λ€μ ꡬμ±νλ μμ€ μ½λ νμΌλ€ κ°κ°μ΄ μ λ§λ€ μνΈλ¦¬ ν¬μΈνΈλ‘μ λ²λ€λ§λλλ‘ μ€μ ν¨μΌλ‘μ ꡬνλμμ΅λλ€.
/// <reference types="vitest" />
// ... λ€λ₯Έ import λ¬Έλ€
import { runWithGlob } from "@repo/helpers/runWithGlob";
// https://vitejs.dev/config/
export default defineConfig({
// ... λ€λ₯Έ μ€μ λ€ ...
build: {
lib: {
// ... λ€λ₯Έ μ€μ λ€ ...
entry: Object.fromEntries(
runWithGlob(
"src/**/*.{ts,tsx}",
(file) => [
// μνΈλ¦¬ μ΄λ¦
file.replace(/^src\//, "").replace(/index\.(ts|tsx)$/, ""),
// μ λ κ²½λ‘
resolve(__dirname, file),
],
["src/**/*.{d,spec}.ts"],
),
),
fileName: (format, entryName) => `${entryName}/index.${format}.js`,
},
},
});
4) κ°λ° νΈμμ± μ 곡
κ° ν¨ν€μ§λ κ°λ° νκ²½μμμ νΈλ¦¬ν μ¬μ©μ μν΄, λ€μκ³Ό κ°μ κΈ°λ₯λ€μ μ 곡ν©λλ€:
pnpm dev
λͺ λ Ήμ΄λ₯Ό ν΅ν HMR κΈ°λ₯μ μ§μν©λλ€.- TypeScript κ²μ¬ λ° Linter κ²μ¬λ₯Ό μν μ€ν¬λ¦½νΈκ° μ 곡λ©λλ€.
- TypeScript κ²½λ‘ λ³μΉμ μ§μνμ¬, μν¬μ€νμ΄μ€ λ΄ μ½λλ₯Ό
import
ν λ νΈλ¦¬ν λͺ¨λ κ²½λ‘ μ¬μ©μ΄ κ°λ₯ν©λλ€. - Vitest κΈ°λ°μ Test μ€νμ μν κΈ°λ³Έμ μΈ νκ²½κ³Ό μ€ν¬λ¦½νΈκ° μ 곡λ©λλ€.
- λΈλΌμ°μ DOM λ° React κ΄λ ¨ ν¨ν€μ§μ κ²½μ°,
@testing-library/react
λ°@testing-library/jest-dom
ν¨ν€μ§λ₯Ό μ¬μ©νμ¬ ν μ€νΈ νκ²½μ ꡬμ±ν©λλ€.
- λΈλΌμ°μ DOM λ° React κ΄λ ¨ ν¨ν€μ§μ κ²½μ°,
λ€λ₯Έ ν¨ν€μ§ λ° μ΄ν리μΌμ΄μ μμμ μ¬μ©
μ΄ νλ‘μ νΈμ ν¨ν€μ§λ€μ μμ‘΄μ±μΌλ‘ κ°λ λ€λ₯Έ ν¨ν€μ§ λ° μ΄ν리μΌμ΄μ
μμλ ν¨ν€μ§μ λΉλλ κ²°κ³Όλ¬Ό(dist
)μ μ¬μ©νλλ‘ μ€μ λμ΄ μμ΅λλ€.
μ΄λ¬ν μ€μ μ κ° ν¨ν€μ§λ§λ€ package.json
μ files
, exports
νλμ μ μλμ΄ μμ΅λλ€.
μμλ‘, react-utils
ν¨ν€μ§μ package.json
νμΌμ μ΄ν΄λ³΄λ©΄ λ€μκ³Ό κ°μ΄ μ€μ λμ΄ μμ΅λλ€:
μ΄λ¬ν μ€μ μ μν΄ pnpm
μ react-utils
ν¨ν€μ§λ₯Ό μμ‘΄μ±μΌλ‘ κ°λ λ€λ₯Έ ν¨ν€μ§λ μ΄ν리μΌμ΄μ
μμ
react-utils
ν¨ν€μ§λ₯Ό μ€μΉν λ, λΉλλ κ²°κ³Όλ¬Ό(dist
)μ μ¬μ©νκ² λ©λλ€.
μ¦, react-utils
ν¨ν€μ§λ₯Ό μ¬μ©νλ λ€λ₯Έ ν¨ν€μ§λ μ΄ν리μΌμ΄μ
μ node_modules/@repo/react-utils
λλ ν 리μλ
λΉλλ κ²°κ³Όλ¬Ό(dist
)μ΄ ν¬ν¨λμ΄ μκ² λ©λλ€.
{
// ...existing code...
"files": [
"dist"
],
"exports": {
"./hooks": {
"types": "./dist/hooks/index.d.ts",
"import": "./dist/hooks/index.es.js",
"require": "./dist/hooks/index.cjs.js"
},
"./hocs": {
"types": "./dist/hocs/index.d.ts",
"import": "./dist/hocs/index.es.js",
"require": "./dist/hocs/index.cjs.js"
},
"./providers": {
"types": "./dist/providers/index.d.ts",
"import": "./dist/providers/index.es.js",
"require": "./dist/providers/index.cjs.js"
}
},
// ...existing code...
}
κ°λ° νκ²½(pnpm dev
)μμμ HMR μ§μ
μμ μ€λͺ
ν λ°μ κ°μ΄, μ΄ νλ‘μ νΈμ ν¨ν€μ§λ€μ μμ‘΄μ±μΌλ‘ κ°λ λ€λ₯Έ ν¨ν€μ§λ μ΄ν리μΌμ΄μ
μμλ
ν΄λΉ ν¨ν€μ§μ μ€μ λΉλλ κ²°κ³Όλ¬Ό(dist
)μ μ¬μ©νλλ‘ μ€κ³λμ΄ μμ΅λλ€.
λ°λΌμ, κ°λ° νκ²½μμ pnpm dev
λͺ
λ Ήμ΄λ₯Ό μ€ννμ λμλ,
κ° ν¨ν€μ§μ λΉλλ κ²°κ³Όλ¬Ό(dist
)μ μ¬μ©νμ¬ κ°λ° μλ²κ° μ€νλ©λλ€.
μ΄ λ, κ°λ° μ€μΈ ν¨ν€μ§μ λ³κ²½ μ¬νμ μ€μκ°μΌλ‘ λ°μν μ μμ΄μΌ νλ―λ‘,
Viteμ HMR(Hot Module Replacement) κΈ°λ₯μ μ¬μ©νμ¬
κ° ν¨ν€μ§μ dev
μ€ν¬λ¦½νΈκ° λ€μκ³Ό κ°μ΄ μ€μ λμ΄ μμ΅λλ€.
{
// ...existing code...
"scripts": {
"dev": "tsc -b && vite build --watch",
// ...other scripts...
},
// ...existing code...
}
Linter κ²μ¬ λ° TypeScript κ²μ¬
μ΄ νλ‘μ νΈμ ν¨ν€μ§λ€μ μμ‘΄μ±μΌλ‘ κ°λ λ€λ₯Έ ν¨ν€μ§λ μ΄ν리μΌμ΄μ
μμλ
ν΄λΉ ν¨ν€μ§μ μ€μ λΉλλ κ²°κ³Όλ¬Ό(dist
)μ μ¬μ©νλλ‘ μ€κ³λμ΄ μκΈ° λλ¬Έμ,
λ§μ½ κ° ν¨ν€μ§λ₯Ό μ¬μ©νλ λ€λ₯Έ ν¨ν€μ§λ μ΄ν리μΌμ΄μ
μμ Linter κ²μ¬(pnpm run lint
) λ° TypeScript κ²μ¬(pnpm run check-types
)λ₯Ό μ€ννλ μμ μμ
dist
λλ ν λ¦¬κ° μ‘΄μ¬νμ§ μλλ€λ©΄, μ€λ₯κ° λ°μν μ μμ΅λλ€.
λ°λΌμ, Linter κ²μ¬ λ° TypeScript κ²μ¬λ₯Ό μ€ννκΈ° μ μ λͺ¨λ ν¨ν€μ§λ€μ λν dist
λλ ν λ¦¬κ° μμ±λμ΄ μλ€λ κ²μ 보μ₯ν νμκ° μμ΅λλ€.
μ΄λ₯Ό μν΄, Turborepo νμ€ν¬ μ€ lint
λ° check-types
μ λν΄μλ
λΉλ μμ
(build
)μ μμ‘΄νλλ‘ λ€μκ³Ό κ°μ΄ μ€μ λμ΄ μμ΅λλ€.
{
// ...existing code...
"tasks": {
// ...other tasks...
"lint": {
"dependsOn": ["build", "^lint"]
},
"check-types": {
"dependsOn": ["build", "^check-types"]
},
// ...other tasks...
},
// ...existing code...
}
π μ°Έκ³
μ΄ νλ‘μ νΈμμ μ±νν λΉλ λ°©μμ λν μμΈν λ΄μ©μ λ€μ λ¬Έμλ₯Ό μ°Έκ³ νμΈμ:
- Turborepo 곡μ λ¬Έμ > publishing-librariesβ
- Turborepo 곡μ λ¬Έμ > creating-an-internal-packageβ