Éloignez-vous de jQuery à Svelte, pas de douleur

Bonjour à tous.

Je suis développeur principal et je résous les tâches frontales comme je peux, c'est-à-dire que sur jQuery, cela a fonctionné en 2015, cela fonctionne maintenant. Mais avec Vue et React, ce n'est plus un camphile. Par amour d'une manière spéciale, j'ai décidé de maîtriser Angular / React / Vue, qui n'a pas été testé par des millions de développeurs, j'ai décidé d'essayer Svelte .

Après avoir fait quelques exercices du manuel, j'ai décidé de passer à la pratique. Pour cela, j'ai effectué l'une de mes tâches de test avec succès.

Lors de l'affectation, il était nécessaire de revoir la liste des tâches et une tâche de cette liste, CRUD n'est pas nécessaire.

La partie client est implémentée en tant que SPA, et tout le travail avec le DOM se fait via jQuery, c'est un excellent candidat pour remplacer jQuery par Svelte.

Ci-dessous, je parlerai des tout premiers obstacles en cours de route et bien sûr de la manière de les surmonter.
Le tutoriel Svelte est très accessible et intuitif, mais comment intégrer Svelte dans un projet arbitraire n'est pas très clair, car Svelte n'est pas une bibliothèque comme jQuery, c'est un compilateur, c'est-à-dire que le code écrit à l'aide des directives Svelte doit en quelque sorte être compilé en JS natif.

Une autre pierre d'achoppement était l'utilisation de

$

dans Svelte, il s'agit d'un caractère réservé, donc son utilisation dans le code qui sera compilé par Svelte conduit à une erreur:


[!] (plugin svelte) ValidationError: $ is an illegal variable name

Utiliser `$`


Bien sûr, la question peut se poser: à quoi ressemble «$» si nous changeons complètement jQuery en Svelte?
Oui, la question est raisonnable, mais si vous y réfléchissez, le problème deviendra clair - vous n’avez pas besoin de manger l’éléphant entier, les gens expérimentés mangent l’éléphant en plusieurs parties. En termes de transition de l'utilisation de jQuery à l'utilisation de Svelte, ce sera une série de refactoring atomique, les progrès seront toujours visibles et le «système» dans son ensemble sera toujours en état de marche.

Le plan est le suivant: réécrire un morceau, tester, réparer, réécrire le morceau suivant, et ainsi de suite jusqu'à ce que nous mangions l'éléphant entier sans laisser de trace.

Le problème avec `$` se produit uniquement dans le code que Svelte compile, j'ai toute la logique SPA déplacée vers le fichier "business-process.js", il n'y a pas besoin de résoudre ce problème, mais tout le code de "business-process.js" devrait aller à App.svelte et autres composants d'application associés.

Après le premier refactoring, App.svelte est apparu avec le code suivant:


<script>
    jQuery(function ($) {

        function loadStartScreen() {
        loadPaging(0, settings.capacity);
        loadPage(0, settings.capacity);
        }

        loadStartScreen();

        async function search(sample) {
            $('#paging').empty();
            $.ajax({
                type: "GET",
                url: `/api/v1/task/search/${sample}/`,
                dataType: "json",
                success: renderTasks,
                error: function (jqXHR, textStatus, errorThrown) {
                },
                timeout: 500,
            });
        }

        $("#search").submit(async function (event) {
            event.preventDefault();
            const sample = $("#sample").val();

            if (sample) {
                search(sample);
            }
            if (!sample) {
                loadStartScreen();
            }
        });
    });
</script>

<div class="container">
    <h1>  </h1>

    <form class="form-horizontal" id="search">
        <div class="form-group">
            <label class="control-label col-sm-2" for="sample">
            
            </label>
            <div class="col-sm-10">
                <input id="sample" class="form-control " type="search"
                 placeholder="  " 
                 autofocus autocomplete="on" />
            </div>
        </div>
    </form>
    <div id="taskList">
    </div>
    <div id="paging">
    </div>

Le code fonctionne, en fait Svelte n'est pas encore utilisé du tout, à ce stade Svelte ne génère que du code HTML qui est inséré dans

<body>

La variable `$` est isolée dans l'appel

jQuery(function ($) {});

aucun conflit de dénomination.

Nous lions l'exemple de variable à la valeur de l'élément d'entrée avec id = "sample":


                <input id="sample" class="form-control " type="search"
                 placeholder="  "
                 autofocus autocomplete="on"
                 bind:value={sample}
                 />

Lors de l'événement submit de l'élément de formulaire avec id = "search", le code est exécuté:


        $("#search").submit(async function (event) {
            event.preventDefault();

            if (sample) {
                search(sample);
            }
            if (!sample) {
                loadStartScreen();
            }
        });

Ce code doit être exécuté selon la directive Svelte, nous le réécrivons:


<script>
    async function svelteSearch(event) {
        event.preventDefault();
        if (sample) {
            search(sample);
        }
        if (!sample) {
            loadStartScreen();
        }
    }
</script>
<form class="form-horizontal" id="search"
on:submit="{svelteSearch}">
</form>

Le code se compile, mais ne fonctionne pas, car la fonction search () est définie dans la portée jQuery (function ($) {}); et dans la portée globale, cette fonction n'est pas visible. Tirez la recherche () dans une portée avec svelteSearch (événement):


<script>
    function loadStartScreen() {
        loadPaging(0, settings.capacity);
        loadPage(0, settings.capacity);
    }

    let sample = '';

    jQuery(function ($) {
        loadStartScreen();
    });
    async function search(sample) {
        $('#paging').empty();
        $.ajax({
            type: "GET",
            url: `/api/v1/task/search/${sample}/`,
            dataType: "json",
            success: renderTasks,
            error: function (jqXHR, textStatus, errorThrown) {
            },
            timeout: 500,
        });
    }
    async function svelteSearch(event) {
        event.preventDefault();
        if (sample) {
            search(sample);
        }
        if (!sample) {
            loadStartScreen();
        }
    }
</script>

Un tel code ne compile pas:


[!] (plugin svelte) ValidationError: $ is an illegal variable name

Que faire? Recherche le sur Google! "Svelte comment importer jquery": Comment utiliser jQuery dans Svelte?
Je n'aimais pas la réponse marquée comme "correcte" pour importer une bibliothèque tierce (arbitraire * .js), il ne suffit pas d'écrire import *, vous devez l'enregistrer dans rollup.config.js externe:


export default { external []};

La deuxième option avec fenêtre. $ Nécessite beaucoup moins de mouvements corporels et puisque nous prévoyons d'abandonner complètement l'utilisation de jQuery, cette directive pour l'importation sera temporaire et la familiarité avec l'importation peut être reportée à plus tard.

Utilisez le copier-coller avec débordement de pile:


<script>
    function loadStartScreen() {
        loadPaging(0, settings.capacity);
        loadPage(0, settings.capacity);
    }
    jQuery(function ($) {
        loadStartScreen();
    });

    let sample = '';

    async function search(sample) {
        window.$('#paging').empty();
        window.$.ajax({
            type: "GET",
            url: `/api/v1/task/search/${sample}/`,
            dataType: "json",
            success: renderTasks,
            error: function (jqXHR, textStatus, errorThrown) {
            },
            timeout: 500,
        });
    }
    async function svelteSearch(event) {
        event.preventDefault();
        if (sample) {
            search(sample);
        }
        if (!sample) {
            loadStartScreen();
        }
    }
</script>

<div class="container">
    <h1>  </h1>
    <form class="form-horizontal" id="search"
    on:submit="{svelteSearch}">
        <div class="form-group">
            <label class="control-label col-sm-2" for="sample">
            
            </label>
            <div class="col-sm-10">
                <input id="sample" class="form-control " type="search"
                 placeholder="  "
                 autofocus autocomplete="on"
                 bind:value={sample}
                 />
            </div>
        </div>
    </form>
// ..skip..
</div>

Reste à se débarrasser de:


    jQuery(function ($) {
        loadStartScreen();
    });

Nous supprimons ce code et l'ajoutons au balisage:


<svelte:window on:load = {loadStartScreen} />

Terminé.

Dans la documentation Svelte , vous pouvez trouver:
<svelte: document>
La balise <svelte: document>, tout comme <svelte: window>, vous offre un moyen pratique d'ajouter des écouteurs d'événements de manière déclarative à l'objet document. Ceci est utile pour écouter les événements qui ne se déclenchent pas sur la fenêtre, tels que mouseenter et mouseleave.

En pratique, nous avons:


[!] (plugin svelte) ParseError: Valid <svelte:...> tag names are svelte:head, svelte:options, svelte:window, svelte:body, svelte:self or svelte:component

Autrement dit, la balise a été coupée du code , mais ils ont oublié de la supprimer de la documentation, à ma grande surprise, Svelte est développé non pas par les dieux, mais par des personnes qui ont également tendance à laisser quelque chose pour plus tard et à oublier.

Comment intégrer jQuery dans le code Svelte avec peu de sang, j'ai dit.

Comment compiler les directives Svelte en code JS


Nous pompons un projet vide dans un dossier séparé comme décrit dans le blog Svelte (installez Node.js en cours de route). Maintenant, nous transférons les fichiers téléchargés dans le répertoire de notre projet.

Nous transférons les fichiers de "public" à l'endroit où nous avons les fichiers à télécharger par le client (le navigateur de l'utilisateur), je l'ai "public / assets / Site", je n'ai pas besoin de styles de "global.css", je n'ai pas transféré ce fichier.

Le fichier "public / index.html", je l'ai transféré à l'endroit où le serveur prendra le modèle en vue: "view / Site / index.html".

Les fichiers de "src" sont ajoutés à la source du frontend - "src / frontend".

Fichiers décrivant les sources du frontend:

  • rollup.config.js
  • package-lock.json
  • package.json

Je suis passé à la racine, là l'IDE les a récupérés et s'est occupé de tout (dépendances installées).
Vous devez maintenant modifier la configuration de compilation des directives Svelte dans JS.

Ouvrez rollup.config.js et modifiez les chemins d'accès aux fichiers:


export default {
	input: 'src/frontend/main.js',
	output: {
		sourcemap: true,
		format: 'iife',
		name: 'app',
		file: 'public/assets/Site/bundle.js'
	},
	plugins: [
		svelte({
			dev: !production,
			css: css => {
				css.write('public/assets/Site/bundle.css');
			}
		}),

C'est la difficulté de l'intégration initiale de Svelte dans un projet existant.

Nous installons les dépendances et commençons à suivre les modifications dans le code source du frontend pour une compilation à la volée:

npm install
npm run dev

Ne pas oublier


Modifiez le modèle de présentation (dans mon cas, c'est "view / Site / index.html"):

  • Tout à l'intérieur de la balise body est portable pour App.svelte
  • Ajouter des liens vers les fichiers de ressources nécessaires

    
    <head>
      <link rel='stylesheet' href='/assets/Site/bundle.css'>
    </head>
    
  • Après la balise body, ajoutez un «lien» au fichier d'assemblage généré:

    
    <body>
    </body>
    <script src='/assets/Site/bundle.js'></script>
    


Le code complet peut être consulté dans le référentiel .

L'abandon final de jQuery dans ce projet est encore loin, mais l'article ne portait pas sur cela, cet article concerne les premières étapes pour implémenter Svelte dans votre code, sur les choses les plus simples.

Merci pour l'attention.

Menace
Comment s'est déroulée la transition, vous pouvez lire dans le prochain article " Comment ça s'est passé "

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


All Articles