Publicación
Este documento explica cómo publicar @lh-ui/vue3 en el registro público npm y cómo hospedarlo en un servidor privado (dos enfoques: enlace directo al tarball y metadatos de registry).
La publicación admite dos canales: manual y automático por CI: localmente se ejecutan los comandos de changeset, y una persona confirma el número de versión y las notas de cambios antes de publicar el paquete (apartado «Flujo de publicación» más abajo); al hacer push a main cuando hay cambios en .changeset/**, GitHub Actions ejecuta automáticamente version + publish (apartado «Publicación automática con GitHub Actions»).
Preparación
1. Cuenta npm y propiedad del scope
Registra una cuenta en npm y activa la verificación en dos pasos (2FA).
Confirma que tu cuenta tiene permiso de publicación en el scope
@lh-ui: los scopes se asignan por orden de llegada; la primera cuenta que publique un paquete@lh-ui/*se convierte en propietaria del scope.Inicia sesión localmente:
bashnpm whoami # Confirma la cuenta actualmente identificado npm login # Si no estás identificado, sigue las indicaciones para completar el login + 2FA
2. Confirmar que el registry apunta al repositorio público
El .npmrc de la raíz del repositorio solo configura shamefully-hoist = true, no fija el registry, de modo que por defecto se usa https://registry.npmjs.org/. El publishConfig de package.json también bloquea el repositorio público:
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
}No escribas una dirección de registry privado en el
.npmrcde la raíz del repositorio: eso desviaría también la publicación hacia el origen privado. Para cambiar el registry temporalmente, usa el.npmrcde nivel de usuario fuera del proyecto o un parámetro de línea de comandos.
3. Qué incluye una publicación
La lista blanca files solo publica los artefactos de compilación: es/ (ESM + tipos + estilos de componentes), lib/ (CJS) y dist/ (UMD + estilos completos). El código fuente, la documentación, las pruebas y los scripts se excluyen mediante .npmignore. Al ejecutar el comando de publicación, prepublishOnly ejecuta primero pnpm build automáticamente, de modo que no es necesario compilar a mano de antemano.
Flujo de publicación
Paso 1: escribir el changeset
Todo cambio visible para el usuario debería tener su changeset. Si este cambio ya lo tiene, salta al paso 2.
pnpm changesetSigue las indicaciones interactivas para elegir @lh-ui/vue3, el tipo de bump (major / minor / patch) y la descripción de los cambios.
Nota: los changesets de este repositorio son acumulativos. Actualmente hay decenas de changesets sin consumir acumulados en
.changeset/; al ejecutarchangeset versionen el paso 2 se consumirán todos de una sola vez y se fusionarán en una única versión. Si quieres publicar por lotes, primero debes usar ramas de git o mover manualmente parte de los archivos de changeset para controlar el ritmo.
Paso 2: subir el número de versión y generar el CHANGELOG
pnpm changeset:versionEste comando:
- Calcula el nuevo número de versión a partir del nivel de bump más alto de los changesets y lo escribe en
package.json - Agrega todos los changesets para generar
CHANGELOG.md - Elimina los
.changeset/*.mdconsumidos (enconfig.json,commit: false, no se confirma automáticamente)
Tras ejecutarlo, revisa manualmente:
git status # Confirma que los changesets se han consumido y que se ha generado el CHANGELOG
git diff package.json # Confirma que el número de versión es el esperadoPaso 3: publicar
pnpm changeset:publishInternamente ejecuta pnpm publish; el flujo es:
- Dispara
prepublishOnly→pnpm build(compilación completa: ESM / CJS / UMD / tipos / estilos) - Empaqueta según
publishConfigy lo publica en el registro público npm - Genera y envía la etiqueta de git (con el formato
@lh-ui/vue3@<version>)
Como publishConfig.access es public, los paquetes con scope también serán visibles públicamente, sin necesidad de añadir --access public.
Paso 4: enviar (lo ejecutas tú)
git push --follow-tagsAutocomprobación antes de publicar
Antes de publicar oficialmente, usa una ejecución dry-run para revisar el contenido real del paquete:
npm pack --dry-runConfirma que la salida:
- Solo contiene los tres directorios
es/,lib/ydist/ - No incluye
src/,packages/,docs/,tests/,scripts/,ai/ - El tamaño es razonable (el paquete UMD completo ocupa unos 600 KB y los estilos completos unos 700 KB, dentro del rango esperado)
Verificación después de publicar
# 1. La nueva versión es visible en npm
npm view @lh-ui/vue3
npm view @lh-ui/vue3 versions
# 2. Crea un proyecto aislado para probar los tres formatos de módulo
pnpm create vite verify-pkg --template vue-ts
cd verify-pkg && pnpm add @lh-ui/vue3En el proyecto aislado, verifica uno a uno:
| Elemento a verificar | Escritura |
|---|---|
| Importación completa (ESM) | import LhUiPlus from '@lh-ui/vue3' + import '@lh-ui/vue3/dist/index.css' |
| Importación a demanda de componentes | import { LhButton } from '@lh-ui/vue3' |
| Importación a demanda de estilos (requiere sass) | import '@lh-ui/vue3/style/button' |
| Importación a demanda de estilos (sin sass) | import '@lh-ui/vue3/style-css/button' |
| Utilidades de tema | import { getThemeVars } from '@lh-ui/vue3/theme' |
| CDN (tras unos minutos, actualiza) | https://unpkg.com/@lh-ui/vue3 |
Alojamiento en servidor propio (tarball estático)
El registro público npm es el canal de publicación principal; si necesitas un mirror autohospedado (uso en intranet, npm bloqueado o deseo de fijar una versión concreta), colocar el tarball en tu propio servidor es la solución más ligera, sin necesidad de montar un registry npm privado.
1. Empaquetar el tarball
pnpm build
npm packEl nombre del archivo generado es lh-ui-vue3-<version>.tgz: npm transforma el @lh-ui/ del scope en lh-ui-vue3- (la barra se convierte en guion). También puedes confirmar con npm pack --dry-run de antemano.
2. Subirlo al servidor
Siguiendo la convención de directorios del sitio nginx existente (el sitio de documentación se despliega en /home/webuser/nginx/lh-ui/vue3/), crea debajo un directorio packages/ y organiza los archivos por versión:
/home/webuser/nginx/lh-ui/vue3/
├── index.html # Sitio de documentación
└── packages/
├── 1.0.0/
│ └── lh-ui-vue3-1.0.0.tgz
├── 1.1.0/
│ └── lh-ui-vue3-1.1.0.tgz
└── latest # Enlace simbólico a la versión recomendada actual
└── lh-ui-vue3-1.1.0.tgzURL correspondiente:
https://www.lhgb.top/lhui/vue3/packages/1.0.0/lh-ui-vue3-1.0.0.tgzpackages/ es un directorio de archivos estáticos; basta con reutilizar la configuración nginx del sitio existente, sin añadir un nuevo location:
# El location ya existente del sitio de documentación cubre el prefijo /lhui/vue3/,
# de modo que packages/ es automáticamente accesible como subdirectorio; solo asegúrate
# de que el Content-Type del .tgz permite la descarga (el octet-stream por defecto de nginx sirve)
location /lhui/vue3/ {
alias /home/webuser/nginx/lh-ui/vue3/;
autoindex off;
}3. Instalar desde el servidor privado
Tres formas equivalentes, a elegir una:
# pnpm
pnpm add https://www.lhgb.top/lhui/vue3/packages/1.0.0/lh-ui-vue3-1.0.0.tgz
# npm
npm install https://www.lhgb.top/lhui/vue3/packages/1.0.0/lh-ui-vue3-1.0.0.tgz
# yarn
yarn add https://www.lhgb.top/lhui/vue3/packages/1.0.0/lh-ui-vue3-1.0.0.tgzO directamente en package.json:
{
"dependencies": {
"@lh-ui/vue3": "https://www.lhgb.top/lhui/vue3/packages/1.0.0/lh-ui-vue3-1.0.0.tgz"
}
}4. Consideraciones
- Omite la resolución de dependencias del registry: la instalación del tarball no consulta el registry; las dependencias proceden directamente de lo declarado dentro del tarball. Este paquete no tiene
dependenciesen tiempo de ejecución, únicamentepeerDependencies.vue, de modo que el proyecto de consumo puede instalarlo y ejecutarlo siempre que tenga Vue 3. - Sin metadatos de versión:
npm updateno funciona con dependencias de tarball; las actualizaciones deben hacer cambiando la URL manualmente (o modificando el enlace simbólicolatesty reinstalando). Adecuado como mirror de versión fijada, no para actualizaciones frecuentes. - https es obligatorio: pnpm / npm / yarn rechazan por defecto las direcciones tarball en http.
- En
pnpm-lock.yamlaparecerá la URL completa + hash de integridad: en el trabajo en equipo el archivo de bloqueo reproduce la instalación correctamente, sin necesidad de acceder a npm.
Alojamiento en servidor propio (metadatos de registry)
El enlace directo al tarball anterior funciona, pero npm update no surge efecto y el lockfile contiene una URL. Si prefieres que el lado de consumo pueda hacer pnpm add @lhgb/vue3 como un paquete normal, con resolución de versiones y dist-tags, puedes hacer que el directorio estático de Nginx sirva adicionalmente unos metadatos de registry npm falsificados, actuando como registry de solo lectura. Ambos enfoques pueden coexistir.
1. Empaquetar
pnpm build
node scripts/pack-private.mjsLo que hace el script: renombra los mismos artefactos de compilación como @lhgb/vue3 (únicamente difieren name y publishConfig), npm pack genera el tarball, calcula integrity (sha512) y shasum (sha1), monta el JSON de metadatos de registry y lo saca a private-registry/:
private-registry/
├── @lhgb/vue3 # JSON de metadatos (sin extensión)
└── tarballs/@lhgb/vue3/
└── lhgb-vue3-1.0.0.tgzParámetros habituales:
--dry-run: solo imprime la lista de archivos que se generarían y los metadatos, sin escribir a disco; sirve para revisar antes de publicar--incremental: lee los metadatos existentes y fusiona la nueva versión, evitando sobrescribir versiones históricas
2. Desplegar en el servidor
Sube el contenido de private-registry/ al directorio del servidor y aplica el location de scripts/nginx-private-registry.conf.example (el mismo Nginx que el sitio de documentación /lhui/vue3/, con un location independiente):
/home/webuser/nginx/registry/
├── @lhgb/vue3
└── tarballs/@lhgb/vue3/
└── lhgb-vue3-1.0.0.tgzLa clave de la configuración de Nginx es default_type application/json: los archivos de metadatos no tienen extensión y, si no se declara el tipo a la fuerza, el cliente los interpretará como texto plano y fallará. La configuración completa se encuentra en scripts/nginx-private-registry.conf.example (el .tgz debe colocarse solo en un location de expresión regular de nivel superior, no anidado dentro de ^~ /lhgb/, de lo contrario la coincidencia de prefijo saltaría la expresión regular):
location ^~ /lhgb/ {
alias /home/webuser/nginx/registry/;
default_type application/json;
autoindex off;
expires 5m;
}
location ~ ^/lhgb/(.+\.tgz)$ {
alias /home/webuser/nginx/registry/$1;
default_type application/octet-stream;
expires 1y;
add_header Cache-Control "public, immutable" always;
}3. Instalar desde el registry privado
Añade una línea al .npmrc de nivel de proyecto o de usuario:
@lhgb:registry=https://www.lhgb.top/lhgbLos tres gestores de paquetes son uniformes:
pnpm add @lhgb/vue3
# o
npm install @lhgb/vue3
# o
yarn add @lhgb/vue34. Relación con el paquete público
@lhgb/vue3 y @lh-ui/vue3 comparten origen y versión: los artefactos de compilación son exactamente iguales; únicamente difieren name y registry, y son intercambiables:
- Para escenarios de intranet / npm bloqueado / necesidad de fijar el origen de publicación, usa
@lhgb/vue3 - Para escenarios orientados al exterior, donde quieres que los CDN unpkg / jsdelivr puedan servirlo, usa
@lh-ui/vue3
5. Consideraciones
- Los metadatos deben actualizarse de forma incremental: tras cada publicación, fusiona la nueva versión con
--incremental; sobrescribir directamente perdería los metadatos de las versiones históricas y las versiones antiguas no podrían instalarse. - El tarball no se puede mover: la URL
tarballde los metadatos es una ruta absoluta; la ubicación del archivo y la URL deben corresponderse una a una. - https es igualmente obligatorio: pnpm / npm / yarn rechazan por defecto las direcciones http.
- No escribas el registry
@lhgben el.npmrcde la raíz del repositorio: el.npmrcraíz solo debe conservarshamefully-hoist = true; la dirección del registry privado va en el.npmrcde nivel de usuario~/.npmrc, para no contaminar la cadena de publicación.
Publicación automática con GitHub Actions
Además del flujo manual, .github/workflows/release.yml ofrece un canal de publicación automática:
- Condición de disparo: push a
maincon cambios en.changeset/**opackage.json; o disparo manual desde la página Actions del repositorio (workflow_dispatch). - Comportamiento: tras ejecutar
pnpm build+pnpm verify:dtsejecuta el version + publish de changesets/action; cuando no hay changesets pendientes de publicación no hace nada, de modo que mantenerlo enganchado al push es seguro. - Secreto necesario: configura
NPM_TOKENen los Settings del repositorio → Secrets and variables → Actions: genera un Granular Access Token en npm y marca el permiso de publish para la organización@lh-ui.
Los canales manual y automático pueden coexistir: pnpm changeset:publish local es adecuado para escenarios en los que se quiere confirmar manualmente cada publicación; el CI es adecuado para publicar de forma acumulativa una vez consolidados los changesets.
Rollback
# Marcar una versión como obsoleta (recomendado; no afecta a los usuarios que ya la tienen instalada)
npm deprecate @lh-ui/vue3@1.0.0 "Esta versión tiene un problema xx; actualiza a 1.0.1"
# Retirar definitivamente: solo es posible dentro de las 72 horas siguientes a la publicación y sin que otros paquetes dependan de ella
npm unpublish @lh-ui/vue3@1.0.0La caché de los CDN (unpkg / jsdelivr) caduca al cabo de unas horas o de un día; tras el rollback puedes verificar en un proyecto aislado, usando una URL con número de versión, que la versión antigua sigue siendo instalable.