Visualizador de markdown con vite y vue en OpenBSD/adJ

El ejemplo de visualizador de markdown disponible en https://medium.com/chingu/markdown-previewer-using-vuejs-c4ea88457061 es para una versión anterior de Vue con webpacker, en este artículo lo presentamos actualizado para Vue 3, con el eficiente vite 5.2.8 y desarrollándolo desde OpenBSD/adJ 7.4.

Note que OpenBSD/adJ 7.4 viene con node pre-instalado:

% node -v
v18.18.0
% npm -v
10.5.2

1. Iniciar una aplicación con la plantilla de vue para vite

Instalamos pnpm con

% doas npm install -g pnpm`

Iniciamos la aplicación markdown-aprender con la plantilla para vite de vue con:

% pnpm create vite markdown-aprender --template vue
% cd markdown-aprender

Como rollup aún no tiene binarios para OpenBSD/adJ puede configurarse su versión WASM y usarla de manera predeterminada editando package.json y agregando:

"pnpm": {
    "overrides": {
      "rollup": "npm:@rollup/wasm-node"
    }
  }

E instalar paquetes con:

% pnpm install

Si está desarrollando en su computador personal ya podría iniciar en modo desarrollo corriendo en localhost por el puerto 5713 con:

% pnpm run dev

Pero si está desarrollando en un servidor remoto (via ssh) puede configurar la IP y el puerto que prefiera para el desarrollo editando vite.config.js y agregando algo como:

  server: {
    port: 4300,
    host: "http://192.168.177.47",
  },

E iniciar la aplicación con:

% pnpm run dev --host

para verla e interactuar (presionando el botón para incrementar la cuenta) desde su navegador. Notará que la carga en caliente (hot reloading) opera, al editar las fuentes y ver al instante el cambio en el navegador.

2. Componentes

Cree un componentes para el encabezado src/components/Encabezado.vue con:

<template>
  <header class="encabezado-pagina">
    Ejemplo de previsualización markdown
  </header>
</template>

Y uno para el pie de página src/componentes/Piedepagaina.vue con:

<template>
  <footer>
    Dominio público. 2024.
  </footer>
<template>
<style>
footer {
    position: fixed;
    bottom: 0;
    width: 100%;
    padding: 1%;
    background-color: #bcd;
    text-align: center;
}
</style>

Y modifique src/App.vue para ir quitando lo del ejemplo original y agregando los nuevos componentes:

<script setup>
import Encabezado from './components/Encabezado.vue'
import Piedepagina from './components/Piedepagina.vue'
</script>

<template>
  <Encabezado></Encabezado>
  <Piedepagina></Piedepagina>
</template>

3. Funcionalidad de previsualizar markdown

Para generar HTML a partir de markdown se empleará el paquete marked que puede agregar con:

% pnpm add marked

Como se explica en el artículo original en un área de texto se espera que el usuario digite markdown y a medida que lo hace en un div se va presentando el HTML generado.

El archivo src/App.vue queda con:

<script setup>
import { ref, computed } from 'vue'
import Encabezado from './components/Encabezado.vue'
import Piedepagina from './components/Piedepagina.vue'
import { marked } from "marked"

const textoMd = ref("")

const htmlGen = computed(() => marked(textoMd.value))
</script>

<template>
  <Encabezado/>
  <div class="editor">
    <div class="texto-md">
      <h2>Digite un texto Markdown</h2>
      <textarea style="height:auto" 
                rows="16" 
                class='area-de-texto' 
                v-model='textoMd'>
      </textarea>
    </div>
    <div class="html-gen">
      <h2>Previsualización</h2>
      <div v-html='htmlGen' ></div>
    </div>
  </div>
  <Piedepagina/>
</template>

<style>
.editor {
  height: 100vh;
  width: 100%;
  display: flex;
}

.html-gen {
  width: 50%;
  padding: 1rem;
}

.area-de-texto {
  width: 100%
}

.texto-md {
  box-sizing: border-box;
  height: 100%;
  width: 50%;
  border: none;
  border-right: 1px solid #ccc;
  background-color: #f6f6f6;
  font-size: 14px;
  font-family: 'Monaco', courier, monospace;
  padding: 20px;
}

body {
  margin: 0;
  min-width: 320px;
  min-height: 100vh;
}

h1 {
  font-size: 3.2em;
  line-height: 1.1;
}

header {
  font-size: 3em;
  line-height: 1.1;
  text-align: center;
  padding: 1rem;
}

#app {
  width: 100%;
  margin: 0 auto;
  padding: 2rem;
  text-align: left;
}

@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
}
</style>

Como todos los estilos se centralizaron en src/App.vue se deja en blanco src/style.css.

4. Conclusión

Es posible y práctico desarrollar interfaces de aplicaciones web con vue y vite recientes en adJ/OpenBSD.

Hemos dejado el repositorio con las fuentes de este artículo en https://gitlab.com/vtamara/markdown-aprender

Los conceptos de vue en mi humilde opinión son más simples y claros que los de React, que en últimas resultan en aplicaciones más mantenibles. Pero esto debe verificarse con una aplicación grande.

Lamentamos que el proyecto vue-native ha sido abandonado, así que aunque vue parece ser mejor alternativa que react para interfaces de aplicaciones web, en principio parece no facilitar su transción a aplicación móvil –que parece es más viable con ionic o con enfoques diferentes como mini aplicaciones de Telegram.