Un rewrite solo de nombre
Tienes una página web que funciona. Renderiza, hace fetch, guarda un token, escucha el scroll. Para publicarla dentro de un runtime de mini-programas no la tiras: la remapeas. La lógica sobrevive en gran parte; cambia la superficie sobre la que corre. La trampa es asumir que el navegador sigue debajo. No está: no hay document, no hay window, no hay localStorage global y no hay <div> que puedas pinchar. Este es el mapa que mantiene la migración predecible.
Ciclo de vida: los eventos se vuelven callbacks
En la web dependes de DOMContentLoaded, load y visibilitychange. Una página de mini-programa es un objeto Page() cuyo ciclo de vida es un conjunto de callbacks con nombre:
Page({
onLoad(query) { /* una vez, al crear — lee params de ruta aquí */ },
onShow() { /* cada vez que aparece, incl. volver de hijo */ },
onReady() { /* primer render listo, seguro consultar layout */ },
onHide() { /* a segundo plano o navegó fuera */ },
onUnload() { /* destruida — limpia timers aquí */ },
})
La mayor diferencia de comportamiento: onShow se dispara al volver de una página hija, así que las listas que deben reflejar una mutación hecha aguas abajo se re-obtienen allí — no solo en onLoad. Los eventos a nivel app (onLaunch, onShow, onHide) viven en App(). No hay aviso beforeunload; si lo necesitas, intercepta la llamada de navegación.
Vista: HTML y CSS se vuelven WXML y WXSS
HTML se vuelve WXML — una plantilla con bindings {{ }} y sin DOM que recorrer. Nunca haces document.querySelector y mutas; llamas this.setData({ key: value }) y la capa de render hace el diff. Esta sola regla elimina toda una categoría de bugs de layout pero también mata cualquier código que asumiera poder alcanzar el árbol de nodos.
WXSS es CSS con dos cambios que muerden: una nueva unidad rpx donde 750rpx equivale al ancho de pantalla (diseño de 375px → 750rpx, auto-escalado por dispositivo), y un set de selectores reducido — sin selectores adyacentes ni de atributo, y muchas menos pseudo-clases (last-child desaparece). Mantén estilos planos y basados en clases.
Red: fetch se vuelve wx.request
Aquí es donde la mayoría de las migraciones se atoran. wx.request no es fetch:
| Aspecto | Web (fetch) | Mini-programa (wx.request) |
|---|---|---|
| Transporte | HTTP/HTTPS, cualquier host | Solo HTTPS/WSS, host debe estar en allowlist |
| Dominio | ninguno | Allowlist de dominio en consola; localhost/IP bloqueados |
| Concurrencia | límite del navegador | Máx 10 concurrentes para request/upload/download |
| Timeout | por llamada | Default y máx 60s; configurable en app.json |
| Referrer | lo pone el navegador | Formato fijo de plataforma, no customizable |
| Background | continúa | Si no termina en 5s tras background, fail interrupted |
La allowlist es el muro clásico: una request que funciona en DevTools con chequeo de dominio off falla en build de prueba y producción hasta que el dominio se registra y tiene ICP. Envuelve wx.request en una capa Promise para headers, inyección de token y manejo 401 — igual que harías con fetch, pero planifica la cola por el tope de 10 conexiones.
Almacenamiento y estado
localStorage se vuelve wx.setStorageSync / wx.getStorageSync, tope 10MB. sessionStorage no tiene gemelo directo — usa params de ruta o getApp().globalData global para lo efímero. No asumas que la persistencia tras cold start es instantánea; lee async donde la UI lo tolere.
Cuando las Web APIs no tienen gemelo
Algunas capacidades del navegador simplemente no están, y el plan de migración debe nombrarlas:
- Geolocalización —
navigator.geolocation→wx.getLocation(con autorización de scope). - Media / live — WebRTC no disponible; usa componentes nativos
<live-pusher>/<live-player>. - Mapas, cámara, video — componentes nativos
<map>,<camera>,<video>reemplazan los elementos HTML y se sitúan sobre la capa de render. - Cookies / same-origin — no hay cookie jar compartida con backend como en el navegador; la auth viaja como tokens en headers que tú inyectas.
- File system — sin FS arbitrario; usa
wx.getFileSystemManagerpara la sandbox que te dan.
Dónde encaja Cross Mini App
Cross Mini App te da un runtime que ya habla esta superficie — paridad wx.*, layout rpx, modelo de 10 conexiones y semántica de allowlist — así un H5 portado se vuelve una entrada del catálogo en lugar de un re-platforming. Conservas tu lógica de negocio, cambias los bordes de forma-navegador por bordes de forma-runtime, y publicas dentro de un host app que tus usuarios ya tienen. La migración es un mapa, no un acantilado.
Fuentes
- WeChat — Page(Object): callbacks de ciclo de vida onLoad/onShow/onReady/onHide/onUnload
- WeChat — Network: wx.request allowlist, tope 10 concurrentes, 60s timeout, solo HTTPS
- Tencent Cloud — WXSS, unidad rpx y set de selectores CSS reducido
- WeChat — Framework: binding WXML, sin DOM/BOM, modelo de render setData
- WeChat — Storage API: setStorageSync/getStorageSync, tope 10MB