L'une des caractĂ©ristiques agrĂ©ables de la technologie 1C:Entreprise est que la solution applicative, dĂ©veloppĂ©e selon la technologie des formulaires gĂ©rĂ©s, peut ĂȘtre lancĂ©e Ă la fois dans un client lĂ©ger (exĂ©cutable) sous Windows, Linux, MacOS X, et comme client web sous 5 navigateurs â Chrome, Internet Explorer, Firefox, Safari, Edge â et tout cela sans modification du code source de l'application. De plus, l'application en client lĂ©ger et dans le navigateur fonctionne et apparaĂźt pratiquement de maniĂšre identique.
Trouvez 10 différences (2 images sous le pli) :
FenĂȘtre du client lĂ©ger sur Linux :

La mĂȘme fenĂȘtre dans le client web (dans le navigateur Chrome) :

Pourquoi avons-nous créé le client web ? Pour dire les choses de maniĂšre un peu pompeuse, cette tĂąche nous a Ă©tĂ© imposĂ©e par le temps. Cela fait longtemps que le travail via Internet est devenu une condition nĂ©cessaire pour les applications professionnelles. Au dĂ©but, nous avons ajoutĂ© la possibilitĂ© de travailler via Internet pour notre client lĂ©ger (certains de nos concurrents, d'ailleurs, se sont arrĂȘtĂ©s lĂ ; d'autres, au contraire, ont abandonnĂ© le client lĂ©ger et se sont limitĂ©s Ă la mise en Ćuvre du client web). Nous avons dĂ©cidĂ© de donner Ă nos utilisateurs la possibilitĂ© de choisir l'option de client qui leur convient le mieux.

L'ajout de la possibilité de travailler via Internet pour le client léger était un grand projet avec un changement complet de l'architecture de l'interaction client-serveur. Créer le client web, c'est un projet complÚtement nouveau, commencé from scratch.
Définition du problÚme
Ainsi, les exigences du projet sont : le client web doit faire la mĂȘme chose que le client lĂ©ger, Ă savoir :
- Afficher l'interface utilisateur
- Exécuter le code client écrit dans le langage 1C
L'interface utilisateur dans 1C est dĂ©crite dans un Ă©diteur visuel, mais de maniĂšre dĂ©clarative, sans placement pixel par pixel des Ă©lĂ©ments ; environ une trentaine de types d'Ă©lĂ©ments d'interface sont utilisĂ©s â boutons, champs de saisie (textes, numĂ©riques, date/heure), listes, tableaux, graphiques, etc.
Le code client en langage 1C peut contenir des appels serveur, travailler avec des ressources locales (fichiers, etc.), imprimer et bien d'autres choses.
Tant le client lĂ©ger (lorsqu'il est utilisĂ© via le web) que le client web utilisent le mĂȘme ensemble de services web pour communiquer avec le serveur d'applications 1C. La mise en Ćuvre pour les clients est, bien sĂ»r, diffĂ©rente â le client lĂ©ger est Ă©crit en C++, le client web est en JavaScript.
Un peu d'histoire
Le projet de crĂ©ation d'un client web a dĂ©butĂ© en 2006, avec une Ă©quipe d'environ 5 personnes en moyenne. Ă diffĂ©rentes Ă©tapes du projet, des dĂ©veloppeurs ont Ă©tĂ© engagĂ©s pour mettre en Ćuvre des fonctionnalitĂ©s spĂ©cifiques (documents tableurs, diagrammes, etc.); en rĂšgle gĂ©nĂ©rale, ce Ă©taient les mĂȘmes dĂ©veloppeurs qui avaient conçu ces fonctionnalitĂ©s dans le client lĂ©ger. C'est-Ă -dire que les dĂ©veloppeurs ont réécrit en JavaScript les composants qu'ils avaient auparavant créés en C++.
DĂšs le dĂ©part, nous avons rejetĂ© l'idĂ©e d'une conversion automatique (mĂȘme partielle) du code C++ du client lĂ©ger en JavaScript pour le client web en raison des fortes diffĂ©rences conceptuelles entre ces deux langages; le client web a Ă©tĂ© Ă©crit en JavaScript Ă partir de zĂ©ro.
Lors des premiĂšres itĂ©rations du projet, le client web convertissait le code client Ă©crit en 1C dans JavaScript. Le client lĂ©ger fonctionne diffĂ©remment: le code en 1C est compilĂ© en bytecode, puis ce bytecode est interprĂ©tĂ© cĂŽtĂ© client. Par la suite, le client web a adoptĂ© ce mĂȘme processus â d'une part, cela a amĂ©liorĂ© les performances, d'autre part, cela a permis d'unifier l'architecture des clients lĂ©ger et web.
La premiĂšre version de la plateforme 1C:Entreprise avec un client web a Ă©tĂ© publiĂ©e en 2009. Ă l'Ă©poque, le client web supportait 2 navigateurs â Internet Explorer et Firefox. Les plans initiaux incluaient la prise en charge d'Opera, mais en raison de problĂšmes insurmontables avec les gestionnaires de fermeture d'application dans Opera (il Ă©tait impossible de suivre avec 100 % de certitude si l'application se fermait, et Ă ce moment-lĂ d'effectuer la procĂ©dure de dĂ©connexion du serveur d'applications 1C), ces plans ont dĂ» ĂȘtre abandonnĂ©s.
Structure du projet
Il y a au total 4 projets dans la plateforme 1C:Entreprise, écrits en JavaScript:
- WebTools â bibliothĂšques communes utilisĂ©es par les autres projets (nous incluons Ă©galement ici ).
- ĂlĂ©ment de contrĂŽle (rĂ©alisĂ© en JavaScript tant dans le client lĂ©ger que dans le client web)
- ĂlĂ©ment de contrĂŽle (rĂ©alisĂ© en JavaScript tant dans le client lĂ©ger que dans le client web)
- Un client web
La structure de chaque projet ressemble Ă celle des projets Java (ou des projets .NET â selon les prĂ©fĂ©rences); nous avons des namespaces, et chaque namespace est dans un dossier sĂ©parĂ©. Ă l'intĂ©rieur de chaque dossier se trouvent les fichiers et les classes du namespace. Le projet du client web contient environ 1000 fichiers.
Structurellement, le client web est principalement divisé en les sous-systÚmes suivants:
- Interface gérée de l'application cliente
- Interface général de l'application (menus systÚme, panneaux)
- Interface des formulaires gĂ©rĂ©s, comprenant notamment environ 30 Ă©lĂ©ments de contrĂŽle (boutons, diffĂ©rents types de champs d'entrĂ©e â texte, numĂ©rique, date/heure, etc., tableaux, listes, graphiques, etc.)
- ModÚle d'objet accessible aux développeurs cÎté client (plus de 400 types au total : modÚle d'objet d'interface gérée, paramÚtres de mise en page des données, mise en forme conditionnelle, etc.)
- Interpréteur du langage embarqué 1C
- Extensions de navigateur (utilisées pour des fonctionnalités non prises en charge par JavaScript)
- Travail avec la cryptographie
- Travailler avec des fichiers
- Technologie des composants externes, permettant de les utiliser à la fois dans le client léger et le client Web
Particularités du développement
La mise en Ćuvre de tout ce qui prĂ©cĂšde en JavaScript n'est pas une tĂąche facile. Peut-ĂȘtre que le client Web 1C est l'une des plus grandes applications cĂŽtĂ© client Ă©crites en JavaScript â environ 450 000 lignes. Nous utilisons activement dans le code du client Web une approche orientĂ©e objet qui simplifie le travail avec un projet aussi vaste.
Pour minimiser la taille du code client, nous avons d'abord utilisĂ© notre propre obfuscateur, et depuis la version 8.3.6 de la plateforme (octobre 2014), nous utilisons . L'effet de cette utilisation en chiffres â la taille du framework du client Web aprĂšs obfuscation :
- Notre propre obfuscateur â 1556 Ko
- Google Closure Compiler â 1073 Ko
L'utilisation de Google Closure Compiler nous a permis d'améliorer la performance du client Web de 30 % par rapport à notre propre obfuscateur. De plus, la consommation mémoire de l'application a diminué de 15 à 25 % (selon le navigateur).
Google Closure Compiler fonctionne trÚs bien avec du code orienté objet, donc son efficacité pour le client Web est maximale. Closure Compiler nous fournit plusieurs avantages :
- Vérification statique des types au moment de la construction du projet (assurée par le fait que nous complétons le code avec des annotations JSDoc). Le résultat est une typage statique trÚs proche de celui en C++. Cela aide à attraper un pourcentage assez élevé d'erreurs lors de la compilation du projet.
- Réduction de la taille du code par obfuscation
- Un certain nombre d'optimisations du code exécuté, par exemple, telles que :
- remplacements inline des fonctions. Appeler une fonction en JavaScript est une opération relativement coûteuse, et les remplacements inline de petites méthodes couramment utilisées accélÚrent considérablement le code.
- Calcul des constantes à la compilation. Si une expression dépend d'une constante, la valeur réelle de la constante sera substituée.
Pour le développement du client web, nous utilisons WebStorm.
Pour l'analyse du code, nous utilisons , oĂč nous intĂ©grons des analyseurs de code statiques. GrĂące Ă ces analyseurs, nous surveillons la dĂ©gradation de la qualitĂ© du code source en JavaScript et nous faisons en sorte de l'Ă©viter.

Quelles tùches avons-nous résolues/résolvons-nous
Au cours de la mise en Ćuvre du projet, nous avons Ă©tĂ© confrontĂ©s Ă plusieurs tĂąches intĂ©ressantes que nous avons dĂ» rĂ©soudre.
Ăchange de donnĂ©es avec le serveur et entre les fenĂȘtres
Il existe des situations oĂč l'obfuscation du code source peut entraver le fonctionnement du systĂšme. Le code externe par rapport au code exĂ©cutable du client web, Ă cause de l'obfuscation, peut avoir des noms de fonctions et de paramĂštres diffĂ©rents de ceux que notre code exĂ©cutable attend. Pour nous, le code externe est :
- Le code qui arrive du serveur sous forme de structures de données
- Le code d'une autre fenĂȘtre de l'application
Pour éviter l'obfuscation lors de l'interaction avec le serveur, nous utilisons la balise @expose :
/**
* @constructor
* @extends {Base.SrvObject}
*/
Srv.Core.GenericException = function ()
{
/**
* @type {string}
* @expose
*/
this.descr;
/**
* @type {Srv.Core.GenericException}
* @expose
*/
this.inner;
/**
* @type {string}
* @expose
*/
this.clsid;
/**
* @type {boolean}
* @expose
*/
this.encoded;
}Et pour Ă©viter l'obfuscation lors de l'interaction avec d'autres fenĂȘtres, nous utilisons ce que l'on appelle des interfaces exportables (interfaces dont toutes les mĂ©thodes sont exportables).
/**
* ĐĐșŃĐżĐŸŃŃĐžŃŃĐ”ĐŒŃĐč ĐžĐœŃĐ”ŃŃĐ”ĐčŃ ĐșĐŸĐœŃŃĐŸĐ»Đ° DropDownWindow
*
* @interface
* @struct
*/
WebUI.IDropDownWindowExp = function(){}
/**
* ĐĐ”ŃĐ”ĐŒĐ”ŃĐ°Đ”Ń ĐČŃĐŽĐ”Đ»Đ”ĐœĐžĐ” ĐœĐ° 1 ĐČпДŃДЎ ОлО ĐœĐ°Đ·Đ°ĐŽ
*
* @param {boolean} isForward
* @param {boolean} checkOnly
* @return {boolean}
* @expose
*/
WebUI.IDropDownWindowExp.prototype.moveMarker = function (isForward, checkOnly){}
/**
* ĐĐ”ŃĐ”ĐŒĐ”ŃĐ°Đ”Ń ĐČŃĐŽĐ”Đ»Đ”ĐœĐžĐ” ĐČ ĐœĐ°ŃĐ°Đ»ĐŸ ОлО ĐșĐŸĐœĐ”Ń
*
* @param {boolean} isFirst
* @param {boolean} checkOnly
* @return {boolean}
* @expose
*/
WebUI.IDropDownWindowExp.prototype.moveMarkerTo = function (isFirst, checkOnly){}
/**
* @return {boolean}
* @expose
*/
WebUI.IDropDownWindowExp.prototype.selectValue = function (){}Nous avons utilisé le Virtual DOM avant qu'il ne devienne courant)
Comme tous les dĂ©veloppeurs traitant avec des interfaces utilisateur web complexes, nous avons rapidement compris que le DOM ne convient pas au travail avec une interface utilisateur dynamique. TrĂšs rapidement, un Ă©quivalent du Virtual DOM a Ă©tĂ© mis en Ćuvre pour optimiser le travail avec l'UI. Lors du traitement d'un Ă©vĂ©nement, toutes les modifications du DOM sont enregistrĂ©es en mĂ©moire et, seulement Ă la fin de toutes les opĂ©rations, les modifications accumulĂ©es sont appliquĂ©es Ă l'arbre DOM.
Optimisation de l'efficacité du client web
Pour que notre client web fonctionne plus rapidement, nous essayons d'exploiter au maximum les capacités natives du navigateur (CSS, etc.). Ainsi, la barre de commande du formulaire (présente dans presque tous les formulaires de l'application) est rendue exclusivement avec les outils du navigateur, grùce à une mise en page dynamique basée sur CSS.

Test
Pour les tests fonctionnels et de performance, nous utilisons un outil développé en interne (écrit en Java et C++), ainsi qu'un ensemble de tests basé sur .
Notre outil est polyvalent : il permet de tester pratiquement toutes les applications de bureau, ce qui le rend adaptĂ© pour tester Ă la fois les clients lourds et les clients web. L'outil enregistre les actions de l'utilisateur ayant lancĂ© l'application « 1C » dans un fichier de script. En mĂȘme temps, des images de l'interface utilisateur sont capturĂ©es â les rĂ©fĂ©rences. Lors du contrĂŽle des nouvelles versions du client web, les scĂ©narios sont exĂ©cutĂ©s sans intervention de l'utilisateur. En cas de non-conformitĂ© entre la capture d'Ă©cran et la rĂ©fĂ©rence Ă un moment donnĂ©, le test est considĂ©rĂ© comme Ă©chouĂ©, aprĂšs quoi un spĂ©cialiste qualitĂ© enquĂȘte â il s'agit d'une erreur ou d'un changement de comportement prĂ©vu du systĂšme. En cas de comportement prĂ©vu, les rĂ©fĂ©rences sont automatiquement remplacĂ©es par de nouvelles.
L'outil mesure également la performance des applications avec une précision de 25 millisecondes. Dans certains cas, nous répétons des parties du scénario (par exemple, la saisie d'une commande plusieurs fois) pour analyser la dégradation des temps d'exécution au fil du temps. Tous les résultats des mesures sont enregistrés dans un journal pour analyse.

Notre outil de test et l'application testée
Notre outil et Selenium se complÚtent ; par exemple, si un bouton sur l'un des écrans change de position, Selenium peut ne pas le détecter, mais notre outil le remarquera, car il effectue une comparaison pixel par pixel de la capture d'écran avec la référence. De plus, l'outil est capable de détecter des problÚmes de traitement des entrées au clavier ou à la souris, puisqu'il les reproduit.
Les tests sur les deux outils (le nĂŽtre et Selenium) exĂ©cutent des scĂ©narios types de fonctionnement Ă partir de nos solutions applicatives. Les tests sont automatiquement lancĂ©s aprĂšs la compilation quotidienne de la plateforme « 1C:Enterprise ». En cas de ralentissement des scĂ©narios (par rapport Ă la compilation prĂ©cĂ©dente), nous menons une enquĂȘte et Ă©liminons la cause de ce ralentissement. Notre critĂšre est simple : la nouvelle compilation ne doit pas ĂȘtre plus lente que la prĂ©cĂ©dente.
Pour enquĂȘter sur les incidents de ralentissement, les dĂ©veloppeurs utilisent diffĂ©rents outils ; principalement, il est utilisĂ© de la sociĂ©tĂ© . L'enregistrement des journaux des opĂ©rations problĂ©matiques est effectuĂ© Ă la fois sur l'ancienne et la nouvelle version, puis les journaux sont analysĂ©s. Dans ce cas, le temps d'exĂ©cution des opĂ©rations individuelles (en millisecondes) peut ne pas ĂȘtre un facteur dĂ©cisif â le navigateur exĂ©cute pĂ©riodiquement des processus de maintenance comme le nettoyage, ce qui peut interfĂ©rer avec le temps d'exĂ©cution des fonctions et fausser les rĂ©sultats. Les paramĂštres plus pertinents dans ce cas seront le nombre d'instructions JavaScript exĂ©cutĂ©es, le nombre d'opĂ©rations atomiques sur le DOM, etc. Si le nombre d'instructions/opĂ©rations dans le mĂȘme scĂ©nario augmente dans la nouvelle version, cela signifie presque toujours une dĂ©gradation des performances qui doit ĂȘtre corrigĂ©e.
Une autre raison de la baisse des performances peut ĂȘtre le fait que Google Closure Compiler n'a pas pu effectuer le remplacement en ligne de la fonction (par exemple, parce que la fonction est rĂ©cursive ou virtuelle). Dans ce cas, nous essayons de rĂ©soudre le problĂšme en réécrivant le code source.
Extensions de navigateur
Lorsque l'application nécessite une fonctionnalité qui n'est pas disponible dans JavaScript, nous utilisons des extensions de navigateur :
- pour travailler avec des fichiers
- pour travailler avec la cryptographie
- interagir avec
Nos extensions se composent de deux parties. La premiĂšre partie est ce que l'on appelle une extension de navigateur (gĂ©nĂ©ralement des extensions Ă©crites en JavaScript pour Chrome et Firefox), qui interagit avec la seconde partie â l'extension binaire, rĂ©alisant la fonctionnalitĂ© dont nous avons besoin. Il convient de mentionner que nous Ă©crivons 3 versions d'extensions binaires â pour Windows, Linux et MacOS. L'extension binaire est fournie avec la plateforme 1C:Entreprise et se trouve sur le serveur des applications 1C. Lors de la premiĂšre invocation depuis le client web, elle est tĂ©lĂ©chargĂ©e sur l'ordinateur client et installĂ©e dans le navigateur.
Lors de l'utilisation de Safari, nos extensions utilisent NPAPI, tandis qu'avec Internet Explorer, elles utilisent la technologie ActiveX. ne prend pas encore en charge les extensions, donc le client web fonctionne avec des limitations.
Développement futur
Un des groupes de tĂąches pour l'Ă©quipe de dĂ©veloppement du client web est d'amĂ©liorer les fonctionnalitĂ©s. Les fonctionnalitĂ©s du client web doivent ĂȘtre identiques Ă celles du client lĂ©ger, toutes les nouvelles fonctionnalitĂ©s Ă©tant mises en Ćuvre simultanĂ©ment dans les deux versions.
D'autres tùches consistent à développer l'architecture, refactoriser, améliorer les performances et la fiabilité. Par exemple, l'une des directions est de s'orienter davantage vers un modÚle de travail asynchrone. Une partie des fonctionnalités du client web est actuellement basée sur un modÚle d'interaction synchrone avec le serveur. Le modÚle asynchrone devient de plus en plus pertinent dans les navigateurs (et pas seulement dans les navigateurs), ce qui nous pousse à modifier le client web en remplaçant les appels synchrones par des appels asynchrones (et à refactoriser le code en conséquence). La transition progressive vers le modÚle asynchrone s'explique par la nécessité de supporter les solutions déjà publiées et leur adaptation progressive.
Source : habr.com
