Contexte
Quelques lignes sur moi pour une compréhension générale du niveau de l'auteur et du problème résolu.Je m'appelle Eugene et je suis développeur web développeur junior frontend vert.
Il y a une autre année, j'ai travaillé dans un domaine complètement différent et seulement en théorie, j'ai pensé à changer de profession, mais vers décembre 2018, j'ai trouvé ma voie et j'ai commencé à jouer.
Après environ six mois de formation totale, j'obtiens un emploi de programmeur frontend. J'ai appris des choses fondamentales (je veux le penser), js, l'interaction avec le DOM, réagir + redux. HTML et CSS au moins + une compréhension générale du bootstrap et de l'assemblage, en travaillant avec git, la ligne de commande.
En plus de la théorie, quelques projets de formation ont été réalisés, y compris un chat sur react + redux, ainsi que quelques tentatives pour mettre en œuvre certaines de leurs idées.
En général, un tel ensemble de gentleman moderne standard pour un front'a débutant.
La première semaine et demie, j'ai installé une machine virtuelle, il y a beaucoup de tout et tout m'est inconnu et incompréhensible.
Dans le processus, je me familiarise avec de nouveaux outils et technologies: avec des bases de données (et me mettre un autre signet dans la liste «apprendre»), du mastic, du wincsp, etc.
Passer avec succès cette course d'obstacles et aller à l'avant.
Préface
Ayant déjà écrit mon reloader et cet article, j'ai trouvé des analogues, dont ceux sur
Habré . Cependant, il a décidé de publier son vélo.
Commencer
Nous avons un projet assez volumineux, hérité, écrit en angularJS, avec tous ses charmes. Après React, il me semblait être un dinosaure, mais rien, j'achète des cours d'angularjs, j'arrive rapidement et commence à en bénéficier.
Une impression positive est que le projet a été bien écrit, par des gens aux bras clairement droits. Variables avec une excellente dénomination claire, la structure est la même partout et en général toute la logique est très accessible et simplement exprimée.
Mais il y a suffisamment d'inconvénients.
Le premier problème: le projet est construit par un ancien minimiseur, et il est impossible d'utiliser la syntaxe js moderne. Aucun () => {}, const res = [... data, subRes], async / wait ...
Le deuxième problème: il n'y a ni webpack, ni même au moins gulp, et en conséquence il n'y a pas de webpack-dev-server qui me soit familier avec son excellent rechargement à chaud.
A écrit. Enregistré. F5. Inopportunément. La douleur? Pas une douleur directe, mais très inconfortable.
Le troisième problème: créer le fichier .bat du projet, dans lequel une partie du projet est simplement copiée, une partie des bibliothèques est collectée sans minimisation, une partie est minimisée dans un fichier, le reste des fichiers du projet dans un autre. Liste des bibliothèques dans le troisième fichier. Liste des fichiers à construire dans le quatrième. Et ainsi de suite.
Le quatrième problème: toutes les bibliothèques sont bien dans le dossier libs et sont connectées par un script dans index.html. Tout-sauf, sauf pour express et proxy (ils ne sont pas impliqués dans le montage, mais uniquement pour le développement).
Et loin de partout, il existe des versions ou une indication d'une bibliothèque spécifique.
J'ai vécu une formation dans un monde magnifique de programmation fonctionnelle, plein d'es6 +, webpack-dev-server, tdd, eslint, build automatique et ainsi de suite.
Et ici, dans le monde adulte, tout est complètement différent ...
Cravate
Mais j'aime travailler, je considère les obstacles comme des opportunités de développement personnel, l'entreprise est bonne, l'ambiance est excellente, mes yeux sont en feu!
Pendant les heures de travail, j'exécute des tâches de travail, pendant mon temps libre j'essaie d'améliorer quelque chose.
Mi-juin, je commence par une tentative de fixation du webpack, mais la première approche s'attend à un échec complet. Je suis tourmenté depuis une semaine, j'en suis très fatigué, temporairement repoussé.
Je décide de commencer petit - je connecte la nouvelle syntaxe via babel. J'ajoute le traitement initial de babel à notre build.bat magique, mais quelque chose brise l'idylle et notre vieux minificator trébuche. Je cherche un problème.
Trébuche sur l'une des bibliothèques des bibliothèques de papa soignées. Je regarde les fichiers de bibliothèque: ils sont déjà minifiés dans l'ancienne syntaxe.
Je dis babel - "tu ne vas pas ici ... la tête recevra le code, ce sera vraiment mauvais." Je vérifie: tout fonctionne! Hourra! Maintenant, j'ai accès à toutes ces belles nouvelles choses tendance pour les jeunes! Première victoire. Nice Je pense à cette occasion pour renommer le script en e.bat (e-Evgen), mais ne peut pas décider.
La nouvelle syntaxe est tellement familière et agréable, mais l'idée d'une construction tordue ne me quitte pas.
Fin juin et début juillet. Je fais la deuxième approche, plus approfondie, mais encore une fois je rencontre des erreurs entre webpack et angularjs. Encore une semaine de recherches.
Une fois que j'ai passé plusieurs jours et partiellement des nuits à chercher une solution, je tombe sur des discours extrêmement intéressants de la conférence HolyJS, où les gars creusent déjà assez profondément dans le webpack. J'avance dans sa compréhension, mais je ne comprends toujours pas la matière jusqu'au bout.
L'intérêt se renforce.
Un collègue dit - oubliez ça, pour remettre le projet dans quelques mois, plus besoin de le faire.
Je ne martèle pas, mais je le remets - beaucoup de travail, ça me comprime tout, il n'y a plus de temps pour les activités parascolaires.
Mi-juillet, je mets entre mes mains un peu comme notre projet avec une construction sur mesure. Je vais avec lui à la troisième approche et je mets pratiquement en place un webpack avec nous, mais au final je découvre de nouvelles erreurs que je n'ai pas assez de temps pour résoudre, le travail roule avec une nouvelle intensité + ça me dévaste mentalement, je remets cette affaire à nouveau.
Corps principal
Mi-août. En conséquence, un ami parle de l'apprentissage de node.js et de son désir d'écrire son propre hot-reloader. Les réflexions sur notre assemblée éclatent avec une vigueur renouvelée.
Tâche: recharger la page en cours lors de la mise à jour des fichiers du projet.
Caractéristiques: toutes les bibliothèques sont connectées dans index.html, vous ne pouvez pas exiger, sans parler de l'importation. L'assemblage avant rechargement n'est pas encore nécessaire, seulement recharger. Dans un serveur de développement qui procède par procuration aux demandes de notre support, je peux utiliser des packages, et je peux également en avoir besoin!
Tout cela se passe vendredi et je décide que dans une version simplifiée de notre projet, je suis tout à fait capable de mettre en œuvre une technologie qui me sauvera moi et mes collègues de F5.
Le processus de réflexion se poursuit et une vision de la solution se forme dans la tête.
Le serveur le plus simple (comme le nôtre), je vais faire le tour du dossier et des sous-dossiers et former un arbre avec les dates de modification de chaque fichier.
Ensuite, après toutes les n millisecondes, je contournerai encore et encore et comparerai les valeurs du temps de changement. Modifié - recharger. Un ami vous dit - "ne réinventez pas la roue, il y a une montre dans node.js". Génial, je vais l'utiliser. Dans server.js, je configurerai watch derrière le dossier du projet et j'appellerai location.reload () pour changer quelque chose à l'intérieur.
Première itération:
server.jsvar 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().
Le premier problème est l'emplacement - ce n'est pas une variable node.js (en ce moment, je comprends pourquoi mes tentatives d'accès à process.env à l'avant ont également échoué))).
Le deuxième problème est de savoir comment faire comprendre au front ce que le rechargement doit faire.
Quittez - websocket! L'idée est tentante + j'ai travaillé avec eux des «demi-cônes» quand j'ai écrit un chat, j'ai une idée générale. En même temps, je fais un compteur de redémarrage par session, j'ajoute une variable et je traite la requête qui la donne.
J'essaye:
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; })
À l'avant, je fais l'application la plus simple sur 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;// }); }])
Et un module séparé qui le recharge. Séparez, pour que le projet ne reçoive pas trop.
watch.js var socket = io(); socket.on('change', () => { location.reload(); })
Ça marche! Il surveille également des fichiers autres que js (on ne sait jamais!): Vérifié .json, .css.
Je vérifie les sous-dossiers - cela ne fonctionne pas.
Je pense, d'accord, maintenant je vais le réduire récursivement. Au cas où, Google et - le tour est joué - est prêt
la décision.Ajoutez ce package.
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]; });
Hourra, ça marche!
Je me souviens de eslint, codeclimate et travis.
Installez le premier, ajoutez le reste.
Je nettoie le code, tout est var sur const et ainsi de suite.
Linter jure que angulaire n'est pas défini, mais mes fonctionnalités de connexion de bibliothèques dans le projet dictent ce comportement, je le désactive. En même temps, je vis un peu les variables de la ligne de commande, je l'exécute, tout fonctionne!
Il est venu travailler lundi et a attaché toute la ferme à un projet de travail. J'ai dû changer un peu, en même temps faire des changements pour qu'il soit possible de changer certains paramètres de démarrage depuis la ligne de commande et les exceptions, pour ne pas tout lire.
En conséquence, cela s'est avéré comme ceci:
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(); });
le script en cours d'exécution dans package.json appelle simplement server.js sous le nœud et il commence comme ceci:
npm start 1.100 8080
A écrit. Enregistré.
F5En conclusion, je tiens à remercier Vanya, mon ami, à certains endroits le cerveau et le kicker principal, ainsi que Sasha - l'homme que je considère comme mon mentor!
Au lieu d'une postface
Et après 2 semaines, le dernier jour de ma période d'essai, j'ai encore vissé webpack et webpack-dev-server sur notre projet, envoyant mon chargeur chaud à la poussière sur l'étagère de l'histoire.
Cependant, ces 2 semaines nous l'avons utilisé tous les jours et il faisait régulièrement son travail!