[Ingeniería de front-end] Cuando no se usa la ventana acoplable, el proyecto de front-end se puede revertir en línea en segundos

Tabla de contenido

I. Introducción

2. Ideas

3. Practica

3.1 Preparar el proyecto de solicitud de una sola página

3.2 Guardar historial y crear contenido index.html

3.3 El servidor de simulación alberga aplicaciones front-end

3.4 Desarrollo de código de servidor de nodo de reversión rápida

3.5 Reversión rápida del desarrollo de la página visual de front-end

 3.6 Prueba de reversión rápida

4. Resumen


I. Introducción

La reversión rápida         del proyecto es una parte muy importante de la ingeniería front-end. Después de implementar el proyecto en línea, si no se puede abrir un error o si es necesario revertir a la versión anterior por otras razones, la velocidad de la reversión será particularmente importante en este momento

        Pasos normales de reversión: se requiere git reset rollback code o git rervet para deshacer el código de la versión anterior, y luego volver a empaquetar y conectarse.Toma tiempo retirar el código y volver a empaquetar, lo que afectará el tiempo en línea durante unos minutos . Una solución más rápida para lograr una reversión de segundo nivel .

        Docker es una buena solución de implementación, pero no todas las empresas usan Docker para implementar aplicaciones front-end, la mayoría de ellas se alojan localmente a través de nginx o se cargan en oss para acceder a recursos estáticos a través de CDN .

Este artículo lo guiará paso a paso para implementar una demostración         de reversión de segundo nivel de un proyecto front-end . Es adecuado para escribir manualmente junto con el artículo. Puede comprender mejor la implementación del proceso general y aplicarlo rápidamente a los proyectos de su empresa.

El código completo del ejemplo en este artículo ha sido subido: github.com/guojiongwei…

2. Ideas

        Después de empaquetar la aplicación de una sola página, hay un archivo de entrada index.html . Cada index.html empaquetado incluirá los recursos estáticos requeridos por esta versión. Si no podemos eliminar los recursos estáticos de la versión anterior (o subirlos a oss ), y cada vez que se empaqueta el proyecto, se guardan la información empaquetada y el contenido de index.html , y se guarda una lista de datos de matriz.

        Cuando necesite revertir la versión, puede seleccionar el registro de compilación en una rama del proyecto a través de la interfaz visual frontal para una reversión rápida. El principio de implementación específico es reemplazar el contenido index.html actualmente utilizado por el proyecto actual con el contenido index.html almacenado en la versión de reversión . Después de reemplazar el contenido index.html , los recursos estáticos importados se convertirán en las rutas de recursos estáticos empaquetados por esta versión, para realizar una reversión rápida.

        Los recursos estáticos generalmente se pueden colocar en os , que también es conveniente para la aceleración de CDN . Para demostrar la función, este artículo coloca los recursos estáticos empaquetados cada vez en el dist local del proyecto y la reconstrucción no eliminará los recursos originales.

        Esta solución es aplicable a todos los proyectos de aplicaciones de una sola página, independientemente de reaccionar o vue, webpack o vite. La idea general es preservar los recursos estáticos como css, js e imágenes creadas en el historial, guardar el contenido index.html de cada construir y revertir Reemplace el contenido actual con el contenido index.html de la versión correspondiente para lograr una reversión real de segundo nivel.

3. Practica

3.1 Preparar el proyecto de solicitud de una sola página

Primero prepare un proyecto de aplicación de una sola página, tome react  +  vite como ejemplo, ejecute el comando en la línea de comando para crear el proyecto:

# npm 6.x 
npm create vite@latest quick_rollback --template react-ts 

# npm 7+, 需要加双-- 
npm create vite@latest quick_rollback -- --template react-ts

Después de crear el proyecto, ingrese el proyecto para instalar las dependencias:

cd quick_rollback 
npm install

        De forma predeterminada, vite eliminará la carpeta dist original al compilar. Debe modificar la configuración para que vite no elimine el archivo dist original al compilar , de modo que los recursos estáticos de cada compilación se mantengan en dist ( el paquete web también tiene características similares) . configuración).

Modifique la configuración de vite.config.ts y agregue la configuración de compilación :

build: { 
    emptyOutDir: false, // 每次打包后不删除输出目录 
}

        Nota: Los proyectos reales generalmente cargan recursos estáticos front-end en oss . Si se usa el acceso CDN , no es necesario configurar este elemento. Este elemento se configura principalmente para la conveniencia de la demostración de este artículo.

        Si los recursos estáticos del proyecto front-end de la empresa no se cargan en oss , sino que se colocan básicamente en el archivo dist del proyecto del servidor actual y se alojan con nginx , este elemento aún debe configurarse. Es mejor mantener el histórico recursos de construcción Realice la reversión de segundo nivel.

Vamos a probarlo, primero realice el primer empaquetado:

npm run build

La carpeta dist se genera en el proyecto.

1.png

Modifique el código en src/App.tsx y reemplace:

<h1>Vite + React</h1> 
// 替换为 
<h1>Vite + React + 秒级回滚</h1>

Una vez que se complete el reemplazo, ejecute npm run build nuevamente para empaquetar.

2.png

Se puede ver que la carpeta dist no se vació al volver a empaquetar , y se conservó el index.js de la última compilación .

Lo siguiente que debe hacer es registrar el valor de index.html         cada vez que la compilación sea exitosa , guardarlo y usarlo para reemplazarlo cuando se deshaga.

3.2 Guardar historial y crear contenido index.html

Agregue un nuevo archivo de secuencia de comandos build.mjs en el directorio raíz del proyecto (utilice .mjs para facilitar el uso de la sintaxis del Módulo ES ), agregue el código:

// build.mjs 
console.log('打包记录历史构建index.html内容')

Y ejecute el archivo después de que npm ejecute build , modifique package.json :

"build": "tsc && vite build && node build.mjs",

Ahora el archivo node build.mjs         se ejecutará cada vez que se empaquete , y el contenido index.html empaquetado se obtendrá y guardará.

El contenido del registro de compilación guardado debe guardarse y puede almacenarse en la base de datos. Este artículo almacena el archivo history.json en         el directorio raíz del proyecto para una simulación simple .

Modificar build.jms :

// build.js
import path from 'path'
import fs from 'fs'

function start() {
  // 设置存储构建的history.json文件路径
  const historyPath = path.resolve('history.json')
  // 如果json文不存在就创建一个,初始值为 { list: [] }
  if(!fs.existsSync(historyPath)) {
    fs.writeFileSync(historyPath, JSON.stringify({ list: [] }))
  }
  // 读取本次打包后的dist/index.html内容
  const html = fs.readFileSync(path.resolve('./dist/index.html'), 'utf-8')
  // 获取到当前histyory.json的内容
  const history = JSON.parse(fs.readFileSync(historyPath, 'utf-8'))
  // 将当前打包的信息push到history的list中,包含构建时间和index.html内容还有id
  // 实际应用中还可以添加其他的很多信息
  history.list.push({
    time: new Date().toLocaleString('zh-cn'),
    html,
    // 模拟生成一个随机的id
    id: Math.random().toString(16).substr(2),
    // ... 分支信息,commit信息,构建时间,构建人,构建环境等字段
  })

  // 将最新的构建记录内容写入到history.json中
  fs.writeFileSync(historyPath, JSON.stringify(history, null, 2))
}

start()

Lógica específica:

  1. Primero configure la ruta del archivo history.json para almacenar la compilación.
  2. Si el archivo json no existe, cree uno, el valor inicial es  { list: [] } .
  3. Lea el contenido de dist/index.html después de empaquetar esta vez .
  4. Obtenga el contenido del archivo history.json actual .
  5. Empuje la información empaquetada actualmente a la lista , incluido el tiempo de compilación, el contenido de index.html y la identificación (y otra información).
  6. Escriba los últimos datos del registro de compilación en el archivo history.json .

Una vez completada la modificación, primero realice un paquete:

npm run build

Luego modifique src/App.tsx y vuelva a cambiar los cambios ahora mismo:

<h1>Vite + React + 秒级回滚</h1> 
// 替换为 
<h1>Vite + React</h1>

Después de completar el reemplazo, empaquételo de nuevo:

npm run build

Una vez que se completa el empaquetado, verifique el archivo history.json y verá que la información index.html de las dos compilaciones se conserva en él.

3.png

        Después de guardar los registros históricos de construcción, debe crear un servicio de nodo y una página de reversión visual de front-end para implementar la lógica de reversión. Los pasos de implementación son:

  1. Después de seleccionar un registro de compilación en la página de visualización frontal, pase la identificación al servidor del nodo .
  2. El servidor encuentra el contenido html correspondiente de acuerdo con la identificación y reemplaza el contenido de dist/index.html con el contenido html .
  3. Una vez que se completa el reemplazo, el usuario puede acceder al contenido de la versión correspondiente cuando visita la página, realizando una reversión de segundo nivel.

3.3 El servidor de simulación alberga aplicaciones front-end

        Una vez que el proyecto de interfaz de usuario se empaqueta en recursos estáticos html , css y js , generalmente será alojado por nginx para lograr el acceso a la red externa. Este artículo utiliza un servidor de recursos estáticos de interfaz de usuario para alojar nuestros recursos empaquetados.

Instale primero globalmente ( mac necesita agregar sudo ):

npm i serve -g

        Una vez completada la instalación, vaya a nuestro proyecto de retroceso rápido quick_rollback , ejecute el comando de servicio y aloje los recursos estáticos de la carpeta dist :

serve -s dist

        Después de que el inicio sea exitoso, la terminal mostrará la dirección de acceso alojada y el navegador puede abrir la dirección para ver que el proyecto ya está accesible.

4.png

3.4 Desarrollo de código de servidor de nodo de reversión rápida

Primero cree un server.mjs para escribir el código del lado del servidor, las cosas que hacer del lado del servidor:

  1. Inicie un servicio en el puerto 3001 .
  2. Al acceder a la ruta raíz, se devuelve una página de reversión visual de front-end.
  3. Proporcione  la interfaz /history para proporcionar datos de registros de construcción históricos para la página de inicio.
  4. La interfaz /rollback se proporciona  para proporcionar una interfaz a la que se revertirá la versión de la página de inicio.
  5. Procese  la lógica /rollback, busque la versión correspondiente del contenido html y reemplace el contenido del archivo dist/index.html .

1. Cree un nuevo server.mjs en el directorio raíz del proyecto

Primero cree un servidor básico con http :

import http from 'http';
import url from 'url';
import fs from 'fs';
import path from 'path';

const server = http.createServer((req, res) => {
  // 获取请求的路径
  const { pathname } = url.parse(req.url, true);
  // 获取请求的方法
  const method = req.method.toLowerCase();
	
  // ... 后续的代码都会写在这里
})

server.listen(3001, () => {
  console.log('server is running on http://localhost:3001')
});

2. Agregue la interfaz de ruta raíz y regrese a la página de reversión visual rollback.html

        Será más conveniente deshacer la operación de la página visual en la parte frontal.Cree un archivo rollback.html en el directorio raíz del proyecto y agregue un código simple:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>rollback</title>
  </head>
  <body>
  </body>
</html>

Luego modifique el archivo server.mjs y agregue la interfaz de ruta raíz:

// server.mjs

// 如果请求的是根路径,就返回rollback.html
if(pathname === '/' && method === 'get') {
	res.writeHead(200, { 'Content-Type': 'text/html' }, 'utf-8')
	res.end(fs.readFileSync(path.resolve('./rollback.html'), 'utf-8'))
}

        De esta forma, cuando node server.mjs inicie el servidor para acceder a la dirección http://localhost:3001 , accederá a la página rollback.html .

3. Agregar interfaz para obtener registros de construcción

        En la página de visualización de rollback.html, necesitamos obtener registros históricos de construcción para facilitar la operación de reversión. Necesitamos proporcionar una interfaz en el lado del servidor para devolver el contenido del archivo history.json , modificar el archivo server.mjs y añadir código:

// 如果请求的是history,就返回history.json的内容
if(pathname === '/history' && method === 'get') {
  res.writeHead(200, { 'Content-Type': 'application/json' }, 'utf-8')
  res.end(JSON.stringify({
  	code: 200,
  	mssage: '操作成功',
  	data: JSON.parse(fs.readFileSync(path.resolve('./history.json'), 'utf-8'))
  }))
}

4. Agregue una reversión rápida a la interfaz

        Después de acceder a los registros históricos de construcción en la página de visualización, puede seleccionar una versión histórica para revertir, por lo que el servidor debe proporcionar una interfaz de reversión, modificar server.mjs y agregar código:

// 如果请求的是rollback,就将对应版本的html内容写入到dist/index.html中
if(pathname === '/rollback' && method === 'get') {
  res.writeHead(200, { 'Content-Type': 'application/json' }, 'utf-8')
  const { query } = url.parse(req.url, true);
  const { id } = query;
  const history = JSON.parse(fs.readFileSync(path.resolve('./history.json'), 'utf-8'));
  const html = history.list.find(item => item.id === id).html;
  fs.writeFileSync(path.resolve('./dist/index.html'), html);
  res.end(JSON.stringify({
    code: 200,
    mssage: '操作成功',
    data: {}
  }));
}

La lógica del código es relativamente simple:

  1. Proporciona una interfaz de solicitud  de obtención /retroceso .
  2. Recibe el id del parámetro de consulta .
  3. Obtener los datos históricos del registro de construcción de la historia .
  4. Compare la identificación con los datos del registro de compilación histórico para encontrar el registro de compilación correspondiente.
  5. Obtenga el contenido index.html correspondiente y modifique  ./dist/index.html para realizar una operación de reversión rápida.
  6. Luego responde al front-end.

En este punto, se escribe la lógica básica del servidor y se inicia el código para la página de visualización de reversión rápida rollback.html .

Código completo de server.mjs :

import http from 'http';
import url from 'url';
import fs from 'fs';
import path from 'path';

const server = http.createServer((req, res) => {
  // 获取请求的路径
  const { pathname } = url.parse(req.url, true);
  // 获取请求的方法
  const method = req.method.toLowerCase();

  // 如果请求的是根路径,就返回rollback.html
  if(pathname === '/' && method === 'get') {
    res.writeHead(200, { 'Content-Type': 'text/html' }, 'utf-8')
    res.end(fs.readFileSync(path.resolve('./rollback.html'), 'utf-8'))
  }

  // 如果请求的是history,就返回history.json的内容
  if(pathname === '/history' && method === 'get') {
    res.writeHead(200, { 'Content-Type': 'application/json' }, 'utf-8')
    res.end(JSON.stringify({
      code: 200,
      mssage: '操作成功',
      data: JSON.parse(fs.readFileSync(path.resolve('./history.json'), 'utf-8'))
    }))
  }

  // 如果请求的是rollback,就将对应版本的html内容写入到dist/index.html中
  if(pathname === '/rollback' && method === 'get') {
    res.writeHead(200, { 'Content-Type': 'application/json' }, 'utf-8')
    const { query } = url.parse(req.url, true);
    const { id } = query;
    const history = JSON.parse(fs.readFileSync(path.resolve('./history.json'), 'utf-8'));
    const html = history.list.find(item => item.id === id).html;
    fs.writeFileSync(path.resolve('./dist/index.html'), html);
    res.end(JSON.stringify({
      code: 200,
      mssage: '操作成功',
      data: {}
    }));
  }
})

server.listen(3001, () => {
  console.log('server is running on http://localhost:3001')
});

3.5 Reversión rápida del desarrollo de la página visual de front-end

        La página frontal también es relativamente simple. La interfaz prepara un cuadro de selección para seleccionar la versión de reversión y un botón OK para confirmar la operación de reversión.

Para liberarse de las operaciones de dom , petite-vue desarrollado por Youda se utilizará aquí para desarrollar la página de inicio.

        petite-vue  es  una distribución alternativa de Vue  optimizada para la mejora progresiva. Proporciona   la misma sintaxis de plantilla y modelo reactivo que Vue estándar:

  • Solo 5.8kb de tamaño
  • Sintaxis de plantillas compatibles con Vue
  • Basado en DOM, conversión en el lugar
  • conductor receptivo

Modifique rollback.html , agregue elementos de botón de selección y botón , y luego importe el archivo petite-vue cdn para la creación de instancias:

  1. Solicite obtener la lista de registros de construcción inmediatamente después de inicializar la instancia y asígnela a this.historyList .
  2. El recorrido del registro de construcción en la página genera la opción de selección y el valor de enlace del modelo v es this.currentItem .
  3. El botón es un botón de confirmación de reversión. Después de hacer clic, primero juzgará si hay una versión de reversión seleccionada.
  4. Preguntar si no hay otra opción, elige usar confirmar para confirmar dos veces.
  5. Después de la confirmación, llame a la interfaz de reversión del lado del servidor para pasar el id y obtener el resultado de la ejecución de acuerdo con el contenido de la respuesta.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>rollback</title>
  </head>
  <body>
    <script src="https://cdn.bootcdn.net/ajax/libs/petite-vue/0.4.1/petite-vue.umd.min.js"></script>
    <div id="app" @vue:mounted="onMounted">
      <select v-model="currentItem">
        <option value="">请选择回滚版本</option>
        <option v-for="item in historyList" :key="item.id" :value="item">发版时间:{
   
   { item.time }}</option>
      </select>
      <button @click="onRollback">回滚</button>
    </div>
  </body>
  <script>
    /** vue实例 */
    PetiteVue.createApp({
      historyList: [], // 构建记录列表
      currentItem: undefined, // 当前选中的项目
      onMounted() {
        this.getHistory();
      },
      /** 获取构建记录列表 */
      getHistory() {
        fetch("/history").then(res => res.json()).then(res => {
          if (res.code === 200) {
            this.historyList = res.data.list;
          }
        });
      },
      /** 代码回滚 */
      onRollback() {
        if (!this.currentItem) return alert("请选择回滚目标版本!");
        const isRollback = confirm(`确认项目回滚到${this.currentItem.time}版本!`);
        if (isRollback) {
          fetch(`/rollback?id=${this.currentItem.id}`).then(res => res.json()).then(res => {
            if (res.code === 200) {
              alert("快速回滚成功!");
            }
          });
        }
      },
    }).mount("#app");
  </script>
</html>

 3.6 Prueba de reversión rápida

Vite + ReactEl paquete anterior genera dos páginas de versión de compilación, y las etiquetas h1 de las dos páginas de versión muestran y         respectivamente Vite + React + 快速回滚Primero, use serve para alojar y ejecutar los recursos estáticos de la carpeta dist actual:

serve -s dist

Abra el navegador de direcciones del proyecto para ver el contenido actual:

4.png

Abra una nueva terminal e inicie nuestro código de servidor:

node server.mjs

Luego abra la página http://localhost:3001

5.png

        Elegimos la versión con un tiempo de lanzamiento anterior y se muestra la página correspondiente a esa versión Vite + React + 快速回滚. Después de completar la selección, haga clic en Revertir para confirmar la segunda vez. Si ve el siguiente mensaje, significa que la reversión se realizó correctamente:

6.png

        En este momento, regrese a la página del proyecto de reacción del front-end , actualice el navegador y podrá ver que el contenido de la página ha cambiado a nuestra versión revertida:

7.png

        En este punto, se ha completado la función central de reversión de segundo nivel.

4. Resumen

Esta forma de preservar el código de construcción histórico también evita dos problemas comunes:

  1. El archivo dist se borra cuando se compila el front-end y no se podrá acceder al proyecto de acceso al front-end en este momento.
  2. Se utiliza la carga diferida de enrutamiento.Después de que se lanza la nueva versión, el archivo original desaparece y el usuario salta a la página para solicitar recursos, lo que resulta en 404, lo que hace que la página sea anormal.

        Se puede decir que sirve para múltiples propósitos, pero solo en este punto, todavía hay un problema, porque los archivos históricos de construcción no se eliminan, se acumularán cada vez más, lo que resultará en un desperdicio de recursos de almacenamiento.

        La solución es modificar el archivo build.mjs , y solo mantener los últimos 5 resultados de compilación, y eliminar los recursos de compilación menos de 5 veces , para lograr una reversión de segundo nivel sin causar demasiado desperdicio de recursos.

Aquí hay algunas ideas de implementación:

  1. Obtenga todos los archivos de recursos estáticos generados por esta compilación cada vez que compila.
  2. Después de obtenerse, se guarda en el registro de compilación actual.
  3. Al mismo tiempo, guarde el nombre del archivo en un archivo files.json y la ruta del archivo como clave .
  4. Después de cada compilación, juzgue el número total de compilaciones actuales, si son más de 5 .
  5. Obtenga la lista de archivos de recursos estáticos generados por la compilación más antigua.
  6. Use el archivo de recursos estáticos generado más temprano para comparar en el archivo general files.json .
  7. Si el archivo generado por la compilación más antigua no se usa en las próximas cinco compilaciones, entonces el archivo se puede eliminar.

        Por lo general, la reversión consiste en volver a la versión anterior. Es raro que se revierta a más de 5 versiones. Si este es el caso, vuelva a empaquetar y compilar.

        Este artículo solo proporciona una idea de reversión de segundo nivel para proyectos front-end en línea, que es adecuada para todos los proyectos de aplicaciones de una sola página. La empresa para la que trabajo ahora usa esta solución, pero es más complicada de usar en la práctica y necesita Los proyectos se desacoplan de los proyectos, lo que facilita el uso de cada proyecto.

Los registros de construcción deben almacenarse en la base de datos o en el archivo oss json         proyecto por proyecto La plataforma de gestión visual puede controlar todos los proyectos y revertir rápidamente las respectivas ramas de proyectos individuales.

        Además de este método, hay muchas otras formas de lograr la reversión de segundo nivel.Este método es relativamente simple de implementar, de bajo costo y ampliamente utilizado.

        Más adelante, habrá otro artículo sobre el uso de Docker para lograr una reversión rápida de proyectos. La solución panacea, los proyectos frontales de una sola página, varias páginas y del lado del servidor pueden usar Docker para lograr una reversión rápida.

Supongo que te gusta

Origin blog.csdn.net/lambert00001/article/details/131985820
Recomendado
Clasificación