Aléjate de jQuery a Svelte, sin dolor

Hola a todos.

Soy un desarrollador de back-end y resuelvo las tareas de front-end como puedo, es decir, en jQuery, funcionó en 2015, funciona ahora. Pero con Vue y React, esto ya no es un camphile. Por amor a una forma especial, decidí dominar Angular / React / Vue, que no ha sido probado por millones de desarrolladores, decidí probar Svelte .

Después de hacer un par de ejercicios del libro de texto, decidí pasar a practicar. Para esto, tomé una de mis tareas de prueba completadas con éxito.

En la asignación fue necesario hacer una revisión de la lista de tareas y una tarea de esta lista, CRUD no es necesaria.

La parte del cliente se implementa como un SPA, y todo el trabajo con el DOM se realiza a través de jQuery, es un excelente candidato para reemplazar jQuery con Svelte.

A continuación hablaré sobre los primeros obstáculos en el camino y, por supuesto, sobre cómo superarlos.
El tutorial de Svelte es muy accesible e intuitivo, pero no está muy claro cómo incrustar Svelte en un proyecto arbitrario, porque Svelte no es una biblioteca como jQuery, es un compilador, es decir, el código escrito usando las directivas de Svelte debe compilarse de alguna manera en JS nativo.

Otro obstáculo fue el uso de

$

en Svelte, este es un carácter reservado, por lo que usarlo en el código que compilará Svelte genera un error:


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

Usando `$`


Por supuesto, puede surgir la pregunta: ¿cómo es '$' si cambiamos completamente jQuery a Svelte?
Sí, la pregunta es razonable, pero si lo piensas bien, el problema quedará claro: no necesitas comer el elefante entero, las personas experimentadas comen el elefante en partes. En términos de la transición de usar jQuery a usar Svelte, será una serie de refactorización atómica, el progreso siempre será visible y el "sistema" en su conjunto siempre estará en condiciones de funcionamiento.

El plan es este: reescribir una pieza, probar, reparar, reescribir la siguiente pieza, y así sucesivamente hasta que comamos el elefante entero sin dejar rastro.

El problema con `$` ocurre solo en el código que compila Svelte, tengo toda la lógica SPA movida al archivo “business-process.js”, no hay necesidad de resolver este problema, pero todo el código de “business-process.js” debería ir a App.svelte y otros componentes de aplicación relacionados.

Después de la primera refactorización, App.svelte apareció con el siguiente código:


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

El código está funcionando, en realidad Svelte todavía no se usa en absoluto, en esta etapa Svelte solo genera código HTML que se inserta en

<body>

La variable `$` está aislada en la llamada

jQuery(function ($) {});

sin conflicto de nombres.

Vinculamos la variable de muestra con el valor del elemento de entrada con id = "sample":


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

En el evento de envío del elemento de formulario con id = "search", se ejecuta el código:


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

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

Este código debe ejecutarse de acuerdo con la directiva Svelte, lo reescribimos:


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

El código se compila, pero no funciona, porque la función search () está definida en el alcance jQuery (function ($) {}); y en el ámbito global, esta función no es visible. Tire de search () en un ámbito con svelteSearch (event):


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

Tal código no compila:


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

¿Qué hacer? ¡Buscalo en Google! "Svelte cómo importar jquery": ¿Cómo uso jQuery en Svelte
? No me gustó la respuesta marcada como "correcta", para importar una biblioteca de terceros (arbitraria * .js), no es suficiente escribir import *, tienes que registrarla en rollup.config.js externo:


export default { external []};

La segunda opción con window. $ Requiere mucho menos movimientos del cuerpo y dado que planeamos abandonar por completo el uso de jQuery, esta directiva para la importación será temporal y la familiaridad con la importación se puede posponer hasta más tarde.

Utilice copiar y pegar con desbordamiento de pila:


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

Queda por deshacerse de:


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

Eliminamos este código y lo agregamos al marcado:


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

Hecho.

En la documentación de Svelte , puede encontrar:
<svelte: document>
La etiqueta <svelte: document>, al igual que <svelte: window>, le brinda una manera conveniente de agregar declarativamente oyentes de eventos al objeto del documento. Esto es útil para escuchar eventos que no se activan en la ventana, como mouseenter y mouseleave.

En la práctica, tenemos:


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

Es decir, la etiqueta se cortó del código , pero se olvidaron de eliminarla de la documentación, para mi sorpresa, Svelte no fue desarrollado por los dioses, sino por personas que también tienden a dejar algo para más tarde y olvidarse.

Cómo integrar jQuery en código Svelte con poca sangre, dije.

Cómo compilar directivas Svelte en código JS


Bombeamos un proyecto vacío en una carpeta separada como se describe en el blog de Svelte (instale Node.js en el camino). Ahora transferimos los archivos descargados al directorio de nuestro proyecto.

Transferimos los archivos de "public" a donde tenemos los archivos para que los descargue el cliente (el navegador del usuario), lo tengo "public / assets / Site", no necesito estilos de "global.css", no transfirí este archivo.

El archivo "public / index.html", lo transferí a donde el servidor llevará la plantilla para ver: "view / Site / index.html".

Los archivos de "src" se agregan a la fuente del frontend - "src / frontend".

Archivos que describen las fuentes de la interfaz:

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

Cambié a la raíz, allí el IDE los recogió y se encargó de todo (dependencias instaladas).
Ahora necesita cambiar la configuración de compilación de las directivas Svelte en JS.

Abra rollup.config.js y cambie las rutas de los archivos:


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

Esa es la dificultad con la integración inicial de Svelte en un proyecto existente.

Instalamos las dependencias y comenzamos a rastrear los cambios en el código fuente de la interfaz para compilar sobre la marcha:

npm install
npm run dev

No se olvide


Edite la plantilla de presentación (en mi caso, es "view / Site / index.html"):

  • Todo lo que está dentro de la etiqueta del cuerpo es portátil para App.svelte
  • Agregar enlaces a los archivos de recursos necesarios

    
    <head>
      <link rel='stylesheet' href='/assets/Site/bundle.css'>
    </head>
    
  • Después de la etiqueta del cuerpo, agregue un "enlace" al archivo de ensamblaje generado:

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


Todo el código se puede ver en el repositorio .

El abandono final de jQuery en este proyecto aún está lejos, pero el artículo no trataba sobre eso, este artículo trata sobre los primeros pasos para implementar Svelte en su código, sobre las cosas más simples.

Gracias por la atención.

Amenaza
Cómo resultó la transición, puede leer en el siguiente artículo " Cómo fue "

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


All Articles