Cómo el joven verde escribió su recarga caliente

Antecedentes


Un par de líneas sobre mí para una comprensión general del nivel del autor y el problema que se está resolviendo.
Mi nombre es Eugene y soy desarrollador web y desarrollador frontend junior verde.
Hace algún otro año, trabajé en un campo completamente diferente y solo en teoría pensé en cambiar mi profesión, pero alrededor de diciembre de 2018 encontré mi camino y comencé a actuar.
Después de unos seis meses de capacitación total, obtengo un trabajo como programador frontend. He aprendido cosas fundamentales (quiero pensar así), js, interacción con el DOM, react + redux. HTML y CSS al menos + una comprensión general de bootstrap y ensamblaje, trabajando con git, la línea de comando.
Además de la teoría, se han realizado un par de proyectos de capacitación, incluido un chat sobre react + redux, así como un par de intentos para implementar algunas de sus ideas.
En general, un conjunto de caballeros moderno estándar de este tipo para un frente principiante.
La primera semana y media instalé una máquina virtual, hay mucho de todo y todo me resulta desconocido e incomprensible.
En el proceso, me familiarizo con nuevas herramientas y tecnologías: con bases de datos (y pongo otro marcador en la lista de "aprender"), masilla, wincsp, etc.
Pase con éxito esta carrera de obstáculos e ir al frente.

Prólogo


Después de haber escrito mi reloader y este artículo, encontré análogos, incluidos los de Habré . Sin embargo, decidió publicar su bicicleta.

Inicio


Tenemos un proyecto bastante grande, heredado, escrito en angularJS, con todos sus encantos. Después de Reaccionar, me pareció un dinosaurio, pero nada, compro cursos de angularjs, entro rápidamente y empiezo a beneficiarme.

Una impresión positiva es que el proyecto fue escrito bien, por personas con brazos claramente rectos. Variables con excelente nomenclatura clara, la estructura es la misma en todas partes y, en general, toda la lógica es muy accesible y simple.

Pero hay suficientes inconvenientes.

El primer problema: el proyecto está siendo construido por algún minimizador antiguo, y es imposible usar la sintaxis js moderna. Ninguno () => {}, const res = [... datos, subRes], asíncrono / espera ...

El segundo problema: no hay webpack, ni siquiera al menos trago, y en consecuencia tampoco hay un servidor webpack-dev-familiar que me resulte familiar con su excelente recarga en caliente.

Escribió Guardado F5 Inconveniente Dolor? No es un dolor directo, pero muy incómodo.

El tercer problema: construir el archivo .bat del proyecto, en el que parte del proyecto simplemente se copia, parte de las bibliotecas se recopilan sin minimización, parte se minimiza en un archivo, el resto de los archivos del proyecto en otro. Lista de bibliotecas en el tercer archivo. Lista de archivos para construir en el cuarto. Y así sucesivamente.

El cuarto problema: todas las bibliotecas están perfectamente en la carpeta libs y están conectadas por un script en index.html. All-all, excepto express y proxy para él (no están involucrados en el ensamblaje, sino solo para el desarrollo).
Y lejos de todas partes hay versiones o una indicación de una biblioteca específica.

Viví entrenando en un hermoso mundo de programación funcional, lleno de es6 +, webpack-dev-server, tdd, eslint, construcción automática, etc.

Y aquí en el mundo de los adultos, todo es completamente diferente ...

Empate


Pero me gusta trabajar, considero los obstáculos como oportunidades para el autodesarrollo, la empresa es buena, el ambiente es excelente, ¡tengo los ojos en llamas!

En las horas de trabajo realizo tareas de trabajo, en mi tiempo libre trato de mejorar algo.

A mediados de junio, comienzo con un intento de ajustar el paquete web, pero el primer enfoque espera un fracaso completo. He estado atormentado durante una semana, estoy muy cansado de eso, temporalmente pospuesto.

Decido comenzar con algo pequeño: conecto la nueva sintaxis a través de babel. Agrego el procesamiento inicial de babel a nuestro build.bat mágico, pero algo rompe el idilio y nuestro viejo minificador tropieza. Estoy buscando un problema

Se tropieza con una de las bibliotecas de las ordenadas librerías de papá. Miro los archivos de la biblioteca: ya están minificados en la sintaxis anterior.

Digo babel: "no vayas aquí ... la cabeza obtendrá el código, será realmente malo". Lo compruebo: ¡todo funciona! ¡Hurra! ¡Ahora tengo acceso a todas esas nuevas y agradables cosas de moda para jóvenes! Primera victoria Agradable Creo en esta ocasión cambiar el nombre del script en e.bat (e-Evgen), pero no puedo decidir.

La nueva sintaxis es tan familiar y agradable, pero la idea de una construcción torcida no me deja.

Finales de junio y principios de julio. Estoy haciendo el segundo enfoque, más exhaustivo, pero nuevamente me encuentro con errores entre webpack y angularjs. Nuevamente una semana de investigación.

Una vez que paso varios días y en parte noches buscando una solución, me encuentro con discursos extremadamente interesantes de la conferencia HolyJS, donde los muchachos ya están cavando bastante en el paquete web. Estoy avanzando en su comprensión, pero todavía no entiendo el material hasta el final.

El interés se fortalece.

Un colega dice: olvídalo, para entregar el proyecto en un par de meses, ya no es necesario que lo hagas.
No martillo, pero lo pospuse: mucho trabajo, me exprime todo, no queda tiempo para actividades extracurriculares.

A mediados de julio, me pongo en mis manos de forma similar a nuestro proyecto con una construcción personalizada. Voy con él al tercer enfoque y prácticamente estoy configurando un paquete web con nosotros, pero al final encuentro nuevos errores que no tengo tiempo suficiente para resolver, el trabajo avanza con nueva intensidad + me devasta mentalmente, pospongo este negocio nuevamente.

Cuerpo principal


Mediados de agosto. Como resultado, un amigo habla sobre el aprendizaje de node.js y su deseo de escribir su propio Hot-Reloader. Los pensamientos sobre nuestra asamblea estallan con renovado vigor.

Tarea: vuelva a cargar la página actual al actualizar archivos en el proyecto.
Características: todas las bibliotecas están conectadas en index.html, no puede requerir, por no mencionar la importación. El ensamblaje antes de la recarga aún no es necesario, solo recargue. En un servidor de desarrollo que envía solicitudes de nuestro respaldo, puedo usar paquetes, ¡y también puedo solicitarlos!

Todo esto sucede el viernes y decido que en una versión simplificada para nuestro proyecto, soy bastante capaz de implementar una tecnología que nos salvará a mí y a mis colegas de F5.

El proceso de pensamiento continúa y se forma una visión de la solución en la cabeza.
El servidor más simple (como el nuestro), en él recorreré toda la carpeta y subcarpetas y formaré un árbol con las fechas de modificación de cada archivo.

Luego, después de cada n milisegundos, omitiré una y otra vez y compararé los valores del tiempo de cambio. Cambiado - recargar. Un amigo te dice: "no reinventes la rueda, hay un reloj en node.js". Genial, lo usaré. En server.js, configuraré watch detrás de la carpeta del proyecto y llamaré a location.reload () para cambiar algo dentro.

Primera iteración:

server.js
var express = require('express'); var app = express(); var server = require('http').Server(app); const port = 9080; server.listen(port); app.use(express.static(__dirname + '/src')); location.reload(). 


El primer problema es la ubicación: esta no es una variable node.js (en este momento entiendo por qué mis intentos de acceder a process.env en el frente tampoco tuvieron éxito))).

El segundo problema es cómo hacer que el frente entienda qué debe hacer la recarga.

Salir - websocket! La idea es tentadora + Trabajé con ellos "conos medios" cuando escribí un chat, tengo una idea general. Al mismo tiempo, hago un contador de reinicio por sesión, agrego una variable y proceso la solicitud que me da.

Lo intento

server.js
 var express = require('express'); //  express var app = express(); var server = require('http').Server(app); //  http  app var io = require('socket.io')(server); //  socket.io     var fs = require('fs'); const port = 9080; server.listen(port); app.use(express.static(__dirname + '/src')); let count = 0; app.get('/data', (req, res) => { res.data = count; res.send(`${count}`); }) const dir = './src'; fs.watch(dir, () => { io.emit('change', {data: count}); count += 1; }) 


En el frente estoy haciendo la aplicación más simple en angularjs

app.js
 angular.module('App', []) .controller('myAppCtrl',['$scope', '$timeout','$http', ($scope, $timeout, $http) => { $scope.title = '       '; $scope.count = 0; $scope.todo = [ '  ,  ', '   node.js watch   ', '     ,         ', ' , codeclimate  travis   ' ] $scope.marks = [ 'watcher      ' ] // var socket = io(); // socket.on('change', (data) => { // console.log(data.data); // $scope.count = data.data; // console.log('scope.count: ', $scope.count); // $scope.$digest();// // location.reload();//agfr // }) $http({method: 'GET',url: 'data'}) .then(response => { $scope.count = response.data;// }); }]) 


Y un módulo separado que lo recarga. Separar, para que el proyecto no se vuelva demasiado.

watch.js
 var socket = io(); socket.on('change', () => { location.reload(); }) 


Funciona! También supervisa archivos que no sean js (¡nunca se sabe!): Marcado .json, .css.
Compruebo las subcarpetas, no funciona.

Creo que está bien, ahora lo reduciré recursivamente. Por si acaso, google y - voila - está listo
La decisión.

Agrega este paquete.

server.js
 var express = require('express'); //  express var app = express(); var server = require('http').Server(app); //  http  app var io = require('socket.io')(server); //  socket.io     var fs = require('fs'); var watch = require('node-watch'); const port = 9080; server.listen(port); app.use(express.static(__dirname + '/src')); let count = 0; let changed = []; app.get('/data', (req, res) => { res.data = count; res.send({count, changed}); }) const translate = { remove: "", update: "" } watch('./', { recursive: true }, function(evt, name) { io.emit('change', {data: count}); count += 1; changed = [{name, evt}, ...changed]; }); 


¡Hurra, funciona!

Recuerdo eslint, codeclimate y travis.
Instale el primero, agregue el resto.
Limpio el código, todo es var en constante y así sucesivamente.

Linter jura que angular no está definido, pero mis características de conexión de bibliotecas en el proyecto dictan este comportamiento, lo apago. Al mismo tiempo, atornillo un poco las variables de la línea de comando, lo ejecuto, ¡todo funciona!

Llegó a trabajar el lunes y sujetó toda la granja a un proyecto de trabajo. Tuve que cambiar un poco, al mismo tiempo hacer cambios para que fuera posible cambiar algunos parámetros de inicio desde la línea de comandos y excepciones, para que no lo leyera todo.

Como resultado, resultó así:

server.js
 const express = require('express'), http = require('http'), watch = require('node-watch'), proxy = require('http-proxy-middleware'), app = express(), server = http.createServer(app), io = require('socket.io').listen(server), exeptions = ['git', 'js_babeled', 'node_modules', 'build', 'hotreload'], // ,   ,    backPortObj = { /*  ,   back*/ }, address = process.argv[2] || /*    back*/, localHostPort = process.argv[3] || 9080, backMachinePort = backPortObj[address] || /*   back */, isHotReload = process.argv[4] || "y", // "n" || "y" target = `http://192.168.${address}:${backMachinePort}`, str = `Connected to machine: ${target}, hot reload: ${isHotReload === 'y' ? 'enabled' : 'disabled'}.`, link = `http://localhost:${localHostPort}/`; server.listen(localHostPort); app .use('/bg-portal', proxy({ target, changeOrigin: true, ws: true })) .use(express.static('.')); if (isHotReload === 'y') { watch('./', { recursive: true }, (evt, name) => { let include = false; exeptions.forEach(item => { if (`${name}`.includes(item)) include = true; }) if (!include) { console.log(name); io.emit('change', { evt, name, exeptions }); }; }); }; console.log(str); console.log(link); 


app.js
 var socket = io.connect(); socket.on('change', ({ evt, name, exeptions }) => { location.reload(); }); 


el script en ejecución en package.json solo llama a server.js desde debajo del nodo y comienza así:

 npm start 1.100 8080 

Escribió Guardado F5

En conclusión, quiero agradecer a Vanya, mi amigo, en algunos lugares, al autor intelectual y al pateador principal, así como a Sasha, ¡el hombre a quien considero mi mentor!

En lugar de un epílogo


Y después de 2 semanas, en el último día de mi período de prueba, todavía atornillé webpack y webpack-dev-server en nuestro proyecto, enviando mi cargador caliente al polvo en el estante de la historia.

Sin embargo, estas 2 semanas lo usamos todos los días y ¡él hizo su trabajo regularmente!

Source: https://habr.com/ru/post/466237/


All Articles