Design System en React + TypeScript + BEM.
Este repo incluye un paquete de librería y un proyecto example/ para probarlo en desarrollo.
.
├─ src/ # código del DS
├─ dist/ # build (generado por tsup)
├─ example/ # app Vite React para probar el DS
├─ tsup.config.ts
├─ package.json
└─ README.md
La idea es compilar el DS en watch y enlazarlo al example/ para ver cambios al instante (HMR).
# en la raíz del repo
npm i# en la raíz del repo
npm run devEsto ejecuta
tsup --watchy recompiladist/cuando cambias archivos ensrc/.
En otra terminal (también en la raíz del repo):
npm linkEsto registra el paquete local como instalable globalmente en tu máquina.
cd example
npm link @ralorotech/rl-design-systemAhora
example/usa el DS mediante un symlink (no copia), por lo que verá los cambios del build.
cd example
npm i react@19.1.1 react-dom@19.1.1Crea/edita example/vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
resolve: {
// evita React duplicado entre DS y example
dedupe: ["react", "react-dom"],
// si notas comportamientos raros con symlinks, puedes probar:
// preserveSymlinks: true,
},
server: {
// permite acceder a archivos fuera de /example (tu DS)
fs: { allow: [".."] },
},
optimizeDeps: {
// evita que Vite pre-empaque el DS; así lo trata como "source" y hace HMR
exclude: ["@ralorotech/rl-design-system"],
},
});cd example
npm run devEdita src/components/Button/Button.tsx en el DS → se recompila → Vite detecta el cambio → HMR en example/.
Si generas un dist/styles.css a partir de múltiples CSS, añade un watcher simple:
package.json (raíz)
{
"scripts": {
"build": "tsup",
"build:css": "mkdir -p dist && (cat src/styles/tokens.css 2>/dev/null || true) > dist/styles.css && find src/components -name '*.css' -exec cat {} + >> dist/styles.css",
"dev": "tsup --watch",
"dev:css": "npx chokidar 'src/**/*.css' 'src/styles/*.css' -c 'npm run build:css'",
"dev:all": "npx npm-run-all -p dev dev:css"
}
}Usa:
# en la raíz (recomendado si quieres ver cambios de CSS en caliente)
npm run dev:allRequiere
npx(trae binarios al vuelo). Si prefieres, instalachokidar-cliynpm-run-allcomo devDeps.
En example/src/App.tsx:
import { Button } from "@ralorotech/rl-design-system";
import "@ralorotech/rl-design-system/styles.css";
export default function App() {
return <Button variant="primary">Hola desde DS</Button>;
}tsup.config.ts (raíz):
import { defineConfig } from "tsup";
export default defineConfig({
entry: ["src/index.ts"],
dts: true,
format: ["esm", "cjs"],
sourcemap: true,
clean: true,
target: "es2019",
external: ["react", "react-dom"]
});src/index.ts:
import "./styles/tokens.css"; // opcional
export { Button } from "./components/Button/Button";
export type { ButtonProps, ButtonVariant, ButtonSize } from "./components/Button/Button";- Asegúrate de exportar explícitamente en
src/index.ts. - Reconstruye el DS:
npm run build. - Reinstala/enlaza en
examplesi hiciste cambios de estructura.
- Verifica que
reactyreact-domestén en peerDependencies del DS. - Instala
reactyreact-domenexample. - Usa
dedupe: ["react", "react-dom"]envite.config.ts.
- Si concatenas CSS a
dist/styles.css, usanpm run dev:css(odev:all) para reconstruirlo al cambiar estilos.
- Asegúrate de tener
server.fs.allow = [".."]envite.config.ts.
# en example/
npm unlink @ralorotech/rl-design-system
npm i # reinstala deps para limpiar el árbol
# en la raíz del DS
npm unlinknpm run build && npm run build:css
npm publish --access publicConsumir:
npm i @ralorotech/rl-design-systemimport { Button } from "@ralorotech/rl-design-system";
import "@ralorotech/rl-design-system/styles.css";