Geh weg von jQuery nach Svelte, ohne Schmerzen

Hallo alle zusammen.

Ich bin ein Backend-Entwickler und löse die Front-End-Aufgaben so gut ich kann, das heißt, auf jQuery hat es 2015 funktioniert, es funktioniert jetzt. Aber mit Vue and React ist dies kein Kampfer mehr. Aus Liebe zu einer besonderen Art entschied ich mich, Angular / React / Vue zu beherrschen, das nicht von Millionen von Entwicklern getestet wurde. Ich entschied mich, Svelte auszuprobieren .

Nachdem ich ein paar Übungen aus dem Lehrbuch gemacht hatte, beschloss ich, weiter zu üben. Dafür habe ich eine meiner erfolgreich abgeschlossenen Testaufgaben übernommen.

Bei der Zuweisung musste die Liste der Aufgaben überprüft werden, und eine Aufgabe aus dieser Liste, CRUD, wird nicht benötigt.

Der Client-Teil ist als SPA implementiert, und alle Arbeiten mit dem DOM werden über jQuery ausgeführt. Dies ist ein hervorragender Kandidat, um jQuery durch Svelte zu ersetzen.

Im Folgenden werde ich über die ersten Hindernisse auf dem Weg sprechen und natürlich darüber, wie man sie überwinden kann.
Das Svelte-Tutorial ist sehr zugänglich und intuitiv, aber wie man Svelte in ein beliebiges Projekt einbettet, ist nicht sehr klar, da Svelte keine Bibliothek wie jQuery ist, sondern ein Compiler, dh Code, der mit Svelte-Direktiven geschrieben wurde, muss irgendwie in natives JS kompiliert werden.

Ein weiterer Stolperstein war die Verwendung von

$

In Svelte ist dies ein reserviertes Zeichen. Die Verwendung in dem von Svelte kompilierten Code führt daher zu einem Fehler:


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

Verwenden von $


Natürlich kann sich die Frage stellen: Wie ist "$", wenn wir jQuery vollständig in Svelte ändern?
Ja, die Frage ist vernünftig, aber wenn Sie darüber nachdenken, wird das Problem klar - Sie müssen nicht den ganzen Elefanten essen, erfahrene Leute essen den Elefanten in Teilen. Beim Übergang von der Verwendung von jQuery zur Verwendung von Svelte wird es sich um eine Reihe von atomaren Refactorings handeln, der Fortschritt wird immer sichtbar sein und das „System“ als Ganzes wird immer in einem funktionierenden Zustand sein.

Der Plan ist folgender: ein Stück umschreiben, testen, reparieren, das nächste Stück umschreiben und so weiter, bis wir den ganzen Elefanten spurlos essen.

Das Problem mit "$" tritt nur in dem Code auf, den Svelte kompiliert. Ich habe die gesamte SPA-Logik in die Datei "business-process.js" verschoben. Es ist nicht erforderlich, dieses Problem zu lösen, aber der gesamte Code aus "business-process.js" sollte aufgerufen werden App.svelte und andere verwandte Anwendungskomponenten.

Nach dem ersten Refactoring wurde App.svelte mit dem folgenden Code angezeigt:


<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>

Der Code funktioniert, tatsächlich wird Svelte noch gar nicht verwendet. Zu diesem Zeitpunkt generiert Svelte nur HTML-Code, in den eingefügt wird

<body>

Die Variable `$` ist im Aufruf isoliert

jQuery(function ($) {});

Kein Namenskonflikt.

Wir binden die Beispielvariable mit dem Wert des Eingabeelements mit id = "sample":


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

Beim Submit-Ereignis des Formularelements mit id = "search" wird der Code ausgeführt:


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

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

Dieser Code muss gemäß der Svelte-Direktive ausgeführt werden, wir schreiben ihn neu:


<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>

Der Code wird kompiliert, funktioniert jedoch nicht, da die Funktion search () im Bereich jQuery (function ($) {}) definiert ist. und im globalen Bereich ist diese Funktion nicht sichtbar. Ziehen Sie search () mit svelteSearch (event) in einen Bereich:


<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>

Ein solcher Code wird nicht kompiliert:


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

Was zu tun ist? Google es! "Svelte, wie man jquery importiert": Wie verwende ich jQuery in Svelte ? Die
als "korrekt" gekennzeichnete Antwort zum Importieren einer Drittanbieter-Bibliothek (willkürlich * .js) hat mir nicht gefallen. Es reicht nicht aus, import * zu schreiben. Sie müssen sie in rollup.config.js registrieren extern:


export default { external []};

Die zweite Option mit Fenster. $ Erfordert viel weniger Körperbewegungen. Da wir die Verwendung von jQuery vollständig aufgeben möchten, ist diese Direktive für den Import vorübergehend und die Vertrautheit mit dem Import kann auf später verschoben werden.

Verwenden Sie Copy-Paste mit Stapelüberlauf:


<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>

Es bleibt zu beseitigen:


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

Wir entfernen diesen Code und fügen ihn dem Markup hinzu:


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

Erledigt.

In der Svelte-Dokumentation finden Sie:
<svelte: document>
Das <svelte: document> -Tag bietet Ihnen genau wie <svelte: window> eine bequeme Möglichkeit, dem Dokumentobjekt Ereignis-Listener deklarativ hinzuzufügen. Dies ist nützlich, um Ereignisse abzuhören, die nicht im Fenster ausgelöst werden, z. B. Mouseenter und Mouseleave.

In der Praxis haben wir:


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

Das heißt, das Tag wurde aus dem Code herausgeschnitten , aber sie haben vergessen, es aus der Dokumentation zu löschen. Zu meinem Erstaunen wurde Svelte nicht von den Göttern entwickelt, sondern von Menschen, die auch dazu neigen, etwas für später zu hinterlassen und zu vergessen.

Wie man jQuery mit wenig Blut in Svelte-Code integriert, sagte ich.

Kompilieren von Svelte-Anweisungen in JS-Code


Wir pumpen ein leeres Projekt in einen separaten Ordner, wie im Svelte-Blog beschrieben (installieren Sie Node.js auf dem Weg). Jetzt übertragen wir die heruntergeladenen Dateien in das Verzeichnis unseres Projekts.

Wir übertragen die Dateien von "public" dorthin, wo wir die Dateien haben, die vom Client (dem Browser des Benutzers) heruntergeladen werden sollen. Ich habe sie "public / assets / Site". Ich benötige keine Stile von "global.css". Ich habe diese Datei nicht übertragen.

Die Datei "public / index.html" habe ich an den Ort übertragen, an den der Server die Vorlage zur Ansicht nimmt: "view / Site / index.html".

Dateien von "src" werden zur Quelle des Frontends hinzugefügt - "src / frontend".

Dateien, die die Quellen des Frontends beschreiben:

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

Ich wechselte zum Stammverzeichnis, dort nahm die IDE sie auf und kümmerte sich um alles (installierte Abhängigkeiten).
Jetzt müssen Sie die Kompilierungskonfiguration von Svelte-Direktiven in JS ändern.

Öffnen Sie rollup.config.js und ändern Sie die Dateipfade:


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');
			}
		}),

Das ist die Schwierigkeit bei der anfänglichen Integration von Svelte in ein bestehendes Projekt.

Wir installieren die Abhängigkeiten und beginnen, Änderungen im Quellcode des Frontends für die sofortige Kompilierung zu verfolgen:

npm install
npm run dev

Vergessen Sie nicht


Bearbeiten Sie die Präsentationsvorlage (in meinem Fall "view / Site / index.html"):

  • Alles innerhalb des Body-Tags ist auf App.svelte portierbar
  • Fügen Sie Links zu den erforderlichen Ressourcendateien hinzu

    
    <head>
      <link rel='stylesheet' href='/assets/Site/bundle.css'>
    </head>
    
  • Fügen Sie nach dem Body-Tag einen "Link" zur generierten Assembly-Datei hinzu:

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


Der gesamte Code kann im Repository angezeigt werden .

Die endgültige Aufgabe von jQuery in diesem Projekt ist noch weit entfernt, aber in diesem Artikel ging es nicht darum. In diesem Artikel geht es um die ersten Schritte zur Implementierung von Svelte in Ihrem Code, um die einfachsten Dinge.

Vielen Dank für Ihre Aufmerksamkeit.

Bedrohung
Wie sich der Übergang herausstellte, können Sie im nächsten Artikel " Wie es war " lesen.

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


All Articles