Afaste-se do jQuery para Svelte, sem dor

Olá a todos.

Sou desenvolvedor de back-end e resolvo as tarefas de front-end que puder, ou seja, no jQuery, funcionou em 2015, funciona agora. Mas com o Vue e o React, isso não é mais um camphile. Por amor de uma maneira especial, decidi dominar o Angular / React / Vue, que não foi testado por milhões de desenvolvedores, decidi experimentar o Svelte .

Depois de fazer alguns exercícios do livro, decidi seguir em frente. Para isso, fiz uma das minhas tarefas de teste concluídas com sucesso.

Na atribuição, era necessário fazer uma revisão da lista de tarefas e uma tarefa dessa lista, CRUD não é necessária.

A parte do cliente é implementada como um SPA e todo o trabalho com o DOM é feito através do jQuery, sendo um excelente candidato para substituir o jQuery pelo Svelte.

Abaixo, vou falar sobre os primeiros obstáculos ao longo do caminho e, claro, sobre como superá-los.
O tutorial do Svelte é muito acessível e intuitivo, mas como incorporar o Svelte em um projeto arbitrário não é muito claro, porque o Svelte não é uma biblioteca como o jQuery, é um compilador, ou seja, o código escrito usando as diretivas do Svelte deve, de alguma forma, ser compilado no JS nativo.

Outro obstáculo foi o uso de

$

no Svelte, esse é um caractere reservado; portanto, usá-lo no código que será compilado pelo Svelte gera um erro:


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

Usando `$`


Obviamente, pode surgir a pergunta: como é o `$` se mudarmos completamente o jQuery para o Svelte?
Sim, a pergunta é razoável, mas se você pensar bem, o problema ficará claro - você não precisa comer o elefante inteiro, pessoas experientes comem o elefante em partes. Em termos da transição do uso do jQuery para o Svelte, será uma série de refatoração atômica, o progresso sempre será visível e o “sistema” como um todo estará sempre em condições de funcionamento.

O plano é este: reescrever uma peça, testar, reparar, reescrever a próxima peça e assim por diante até comermos o elefante inteiro sem deixar vestígios.

O problema com `$` ocorre apenas no código que o Svelte compila; tenho toda a lógica do SPA movida para o arquivo "business-process.js", não há necessidade de resolver esse problema, mas todo o código de "business-process.js" deve ir para App.svelte e outros componentes de aplicativos relacionados.

Após a primeira refatoração, App.svelte apareceu com o seguinte 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>

O código está funcionando, na verdade o Svelte ainda não está sendo usado; nesse estágio, o Svelte gera apenas o código HTML inserido em

<body>

A variável `$` é isolada na chamada

jQuery(function ($) {});

nenhum conflito de nomenclatura.

Ligamos a variável de amostra ao valor do elemento de entrada com id = "sample":


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

No evento de envio do elemento do formulário com id = "search", o código é executado:


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

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

Este código deve ser executado de acordo com a diretiva Svelte, reescrevemos:


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

O código é compilado, mas não funciona, porque a função search () é definida no escopo do jQuery (function ($) {}); e no escopo global, essa função não é visível. Puxe search () em um escopo com 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>

Esse código não compila:


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

O que fazer? Google it! "Svelte how to import jquery": como uso o jQuery no Svelte?
Não gostei da resposta marcada como "correta" para importar uma biblioteca de terceiros (arbitrária * .js), não basta escrever importação *, você deve registrá-la no rollup.config.js externo:


export default { external []};

A segunda opção com window. $ Requer muito menos movimentos do corpo e, como planejamos abandonar completamente o uso do jQuery, essa diretiva para importação será temporária e a familiaridade com a importação poderá ser adiada para mais tarde.

Use copiar e colar com estouro de pilha:


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

Resta livrar-se de:


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

Removemos esse código e o adicionamos à marcação:


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

Feito.

Na documentação do Svelte , você pode encontrar:
<svelte: document>
A tag <svelte: document>, assim como <svelte: window>, oferece uma maneira conveniente de adicionar declarativamente ouvintes de eventos ao objeto de documento. Isso é útil para ouvir eventos que não são acionados na janela, como mouseenter e mouseleave.

Na prática, temos:


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

Ou seja, a etiqueta foi cortada no código , mas eles esqueceram de excluí-lo da documentação, para minha surpresa, o Svelte é desenvolvido não pelos deuses, mas por pessoas que também tendem a deixar algo para mais tarde e esquecer.

Como integrar o jQuery no código Svelte com pouco sangue que eu disse.

Como compilar diretivas Svelte no código JS


Nós bombeamos um projeto vazio para uma pasta separada, conforme descrito no blog Svelte (instale o Node.js ao longo do caminho). Agora transferimos os arquivos baixados para o diretório do nosso projeto.

Transferimos os arquivos de "public" para onde temos os arquivos para serem baixados pelo cliente (navegador do usuário), tenho "public / assets / Site", não preciso de estilos de "global.css", não transferi esse arquivo.

O arquivo "public / index.html" foi transferido para onde o servidor levará o modelo para visualização: "view / Site / index.html".

Arquivos de "src" são adicionados à fonte do frontend - "src / frontend".

Arquivos que descrevem as fontes do front-end:

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

Mudei para a raiz, lá o IDE os pegou e cuidou de tudo (dependências instaladas).
Agora você precisa alterar a configuração de compilação das diretivas Svelte em JS.

Abra rollup.config.js e altere os caminhos do arquivo:


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

Essa é a dificuldade com a integração inicial do Svelte em um projeto existente.

Instalamos as dependências e começamos a rastrear alterações no código-fonte do front-end para compilação em tempo real:

npm install
npm run dev

Não esqueça


Edite o modelo de apresentação (no meu caso, é "view / Site / index.html"):

  • Tudo dentro da tag body é portátil para App.svelte
  • Adicione links aos arquivos de recursos necessários

    
    <head>
      <link rel='stylesheet' href='/assets/Site/bundle.css'>
    </head>
    
  • Após a tag body, adicione um "link" ao arquivo de montagem gerado:

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


O código inteiro pode ser visualizado no repositório .

O abandono final do jQuery neste projeto ainda está longe, mas o artigo não era sobre isso, este artigo é sobre os primeiros passos para implementar o Svelte no seu código, sobre as coisas mais simples.

Obrigado pela atenção.

Ameaça
Como a transição acabou, você pode ler no próximo artigo " Como foi "

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


All Articles