ARTIGO ANTIGO Artigo escrito em agosto de 2019. Na época o Svelte não possuia suporte nativo a TypeScript e o Sveltekit ainda não existia.
Esta não é a primeira versão do Svelte e creio que a grande maioria nunca se importou antes pois não parecia maduro o suficiente. Para mim foi assim, pelo menos. Também sinto que não sou o único que começou a ter interesse na ferramenta após a versão 3.
Para situar você, meu caro leitor, minha cara leitora e meu caro leitore de único artigo, vou introduzir um pouco sobre Svelte. O texto acabou ficando um pouco longo pois não pretendo dividir em partes dado que faço artigos com pouquíssima freqüência (nula, pra ser sincera). As minhas experiências foram focadas em integrações de Svelte com ferramentas e tecnologias de mercado. Caso você já saiba o que é Svelte, pule para a parte que falo das minhas impressões.
Adiciono também que eu repito muita coisa tanto neste próprio post quanto de conteúdo de outras postagens. Apesar disto, se você ver que eu passei rápido por um assunto é porque devem ter fontes melhores aprofundadas e eu focarei sobre esse meu tempo experimentando o framework.
O que é Svelte?
Svelte é um framework de componentes com escrita declarativa e que converte seus componentes em código nativo pro navegador.
Quando fala-se de frameworks para componentização com escrita declarativa nada mais é que escrever componentes tal como hoje os maiores frameworks de mercado fazem (React, Vue, Angular...) e evitar ficar jQueryzando toda sua aplicação, escrevendo código imperativo que modifica direto pro DOM.
Já o diferencial desta ferramenta é a segunda parte:
Na verdade este framework não é um framework que dá importância em runtime como os frameworks atuais, muito pelo contrário, seu ponto forte é o compilador.
O compilador irá transformar todo seu código declarativo e bem estruturado em algo que altere imperativamente o DOM. Diga adeus ao Virtual DOM. Ele irá jQueryizar sua aplicação por você enquanto seu código continuará componentizável e de fácil manutenção.
Desde sua concepção foi pensado em gerar aplicações reativas. Recomendo muito a palestra do Rich Harris sobre "Pensando em reatividade" 🇬🇧.
Antes de tudo, sintaxe!
Recomendo este completíssimo artigo escrito pelo Claudio Holanda: Svelte: A era dos frameworks-compiladores.
E por onde começar?
O site oficial conta com uma ótima ferramenta ao qual nós desenvolvedores estamos bem acostumados: REPL. É basicamente o parquinho das pessoas desenvolvedoras e a principal ferramenta usada pela comunidade (no chat - link no final do artigo) para apontar problemas ou erros. Não é necessário baixar nada, programe na esquerda e veja a saída na direita. Simples assim.
Caso queira um melhor direcionamento sobre as funcionalidades da plataforma, baseado no REPL também foi criada uma ferramenta interativa com tutoriais e uma galeria com exemplos básicos.
Svelte, hoje vou lhe usar!
De acordo com a documentação, para inicializar projetos Svelte foi popularizado uma outra ferramenta geradora de código chamado degit, também desenvolvida pelo Rich Harris. Basicamente com esta ferramenta você passa um repositório público Git e ele irá baixar e descompactar a última versão de uma branch na pasta onde você irá desenvolver seu código.
Para facilitar, foram disponibilizados repositórios de template com a possibilidade de escolher a ferramenta para criação de bundle em duas opções: Webpack e rollup.
Desenvolver em Svelte loucamente localmente
Para iniciar localmente uma aplicação SPA em Svelte, basta baixar o template:
# using rollup
npx degit sveltejs/template my-svelte-project
# using webpack
npx degit sveltejs/template-webpack my-svelte-project
cd my-svelte-project
npm install
npm run dev
fonte: https://svelte.dev/
Ao rodar npm run dev
a aplicação irá subir um servidor local em modo de desenvolvimento apontando para http://localhost:5000/
. Após o desenvolvimento, basta rodar npm run build
e sua aplicação SPA estará pronta para produção com os artefatos criados dentro da pasta public
.
Usando o Sapper
Desatualizado. Ler sobre Sveltekit
O Sapper é uma aplicação inspirada no Next.js, um framework bem famoso na comunidade React. Mas uma funcionalidade que me agradou bastante foi a de geração de conteúdo estático, algo bem parecido com o Gatsby (porém mais básico, sem GraphQL etc).
# for Rollup
npx degit "sveltejs/sapper-template#rollup" my-app
# for webpack
npx degit "sveltejs/sapper-template#webpack" my-app
cd my-app
npm install
npm run dev & open http://localhost:3000
fonte: https://sapper.svelte.dev/
Um aviso importante: o reload automático (HMR) pode não funcionar muito bem utilizando Sapper, necessitando constantemente ter que matar e reinicializar a aplicação durante o desenvolvimento ao utilizar códigos durante lifecycle.
Ao executar npm run build
, o Sapper gera uma aplicação Node dentro da pasta __sapper__/build
. Também é possível utilizar express (no template é utilizado um servidor mais leve chamado Polka).
Para os hypeiros e amantes de JAM Stack, como eu mencionei anteriormente também é possível gerar conteúdo estático. Basta rodar npm run export
e ele criará os artefatos para produção na pasta __sapper__/export
.
Pontos interessantes
Infelizmente não há suporte nativo oficial para TypeScript mas por um outro ângulo, talvez faça desta ferramenta mais amigável para quem está começando em relação a...
Outras ferramentas do gênero
Tem alternativas? Tem sim senhor!
Stencil
A filosofia do Svelte não é gerar web components como foco principal 🇬🇧. Porém também é possível criar custom elements nativamente conforme esta issue e utilizar como web components
.
O Stencil é desenvolvido pela equipe responsável pelo Ionic (ou seja, projeto "parrudo de responsa") e tem em seu showcase empresas de renome. Mesmo o Svelte tendo uma versão para mobile (svelte-native), diria que vale a pena ver ambos. Utiliza TypeScript.
Algumas alternativas em 2022 (edit)
Real laife
Mesmo sendo clichê de todo artigo brazuca sobre Svelte, repito aqui também um dos maiores cases são as maquininhas verdinhas de pagamento da Stone, usando o Svelte (versão 2 do Svelte).
Como citado no vídeo do Rich Harris
open source 😍.
créditos: @kaisermann
"Mas quero ver um caso real na web! 😡😡😡"
Ao lembrar que o criador trabalha no The New York Times na Vercel dedicado somente ao Svelte (2022), encontrei um outro case de uso de quando ele ainda trabalhava no NYT, integrando com d3: um especial sobre a votação na grã-bretanha. Também foi desenvolvido numa versão mais antiga do Svelte.
Enfim...
Vim de React.
Fanboy mesmo, assumida.
Sempre tinha um detalhe ou outro e que sempre me motivou a não trocar de framework do coração.
Já tinha visto algo bem superficial sobre o Svelte e tinha achado interessante porém sempre passava batido por não ter ouvido muito sobre utilização.
Passou um tempo e após três versões major surgiram muitos cases bem legais e pensei em finalmente dar uma chance e aprender mais sobre.
E por onde comecei?
Sinceramente digo que quando eu começo a aprender algo novo, me sinto intimidada em ir direto na documentação por mais que ela seja boa. Tutoriais e artigos também nem sempre são completos ou abrangentes e geralmente deixam passar algo. Optei então por um curso na Udemy (variando de R$ 28 - 60, quando tem promoção... clichê de pitches: não estou ganhando nada em citar eles 😞) ministrado pelo Maximilian Schwarzmüller: Svelte.js - The Complete Guide (em inglês), do Academind.
É um curso que, apesar de básico/iniciante, cobre muito bem diversas partes das funcionalidades principais contidas no Svelte 3 (versão atual no momento da postagem) e é bem didático.
Componentização
Como todo framework atual, seu desenvolvimento é voltado a componentização da UI. Achei a parte da criação de componentes bem semelhante ao Vue.js no caso de ter tanto o código de marcação (Markup), os estilos e o JavaScript num único arquivo.
Dentro do JavaScript, é possível escrever direto em ES6. Como citado anteriormente, ainda não possui suporte a TypeScript nativo, porem...
Preprocessadores
Como o código no Svelte é compilado, é possível utilizar preprocessadores de um jeito bem trivial. Como se trata de uma ferramenta de terceiro (módulo não oficial porém com muitos mantenedores), sua integração pode não ser das melhores.
É possível integrar outras linguagens ao escrever componentes como TypeScript e CoffeScript para aplicação; Pug (antigo Jade) para Markup (HTML) e Postcss, SASS, Less e Stylus para estilização. É bem simples para integrar.
Dei umas brincadas usando TypeScript e testei usar Stylus e não tive muitos problemas na utilização, porém tive outros problemas (que foram agregados num ítem a parte no final do artigo) com...
Ferramentas e Integrações
É bem completo o suporte do Svelte para ferramentas de integração.
ESLint
Adicione este plugin oficial: eslint-plugin-svelte3. Simples assim.
Sua configuração é bem trivial e como não se trata de um preset, é bom lembrar que a ativação das regras devem ser feitas individualmente dentro de rules
no arquivo de configuração.
Testes
Para quem veio de React já deve conhecer o react-testing-library
do Kent C. Dodds. Quando a ferramenta se popularizou e generalizou dando origem a outras Testing Libraries, e o Svelte não ficou de fora: @testing-library/svelte.
Ele requer um transformador para o Jest: jest-transform-svelte.
Prettier
Esse "embelezador" de código também não poderia ficar de fora. Basta adicionar este plugin e adicionar um override
nas configurações do Prettier conforme descrito na documentação.
Storybook
Sim, é possível ter um Storybook com componentes escritos em Svelte. Seu suporte ainda é básico.
Famoso "saiba mais"
E estilos?
Existem certas características que eu já adianto:
todo css escrito num arquivo de componente será escopado para aquele componente somente
Ao compilar, o Svelte altera os seletores e adiciona classes para evitar conflitos de estilo. E esta funcionalidade é padrão do framework.
não é possível utilizar interpolação de variáveis JavaScript dentro da tag <style>
.
Porém nada impede de repassar tais valores utilizando variáveis CSS: exemplo leviano. Claro que também é possível alterar estilos inline utilizando o atributo style
, porém lembre que por boas práticas...
o Svelte assume que o CSS deve ser intocável
Ou seja, o que estiver dentro da tag <style>
, após a transformação dos seletores em classes escopadas é um código pronto para ser extraído para um arquivo separado (extract-text-webpack-plugin
, estou falando de ti).
Não sei nem se é possível utilizar CSS-in-JS, inclusive. Porém lembre do front-end raiz, onde utilizamos classes para definir diferentes estilos ao invés de alterá-los em tempo de execução.
Mas... Não tem Virtual DOM?
É inegável que o pattern de Virtual DOM do React é performático (palavras sob influência da minha fanboyzisse, não leve a sério!), porém pela filosofia do Svelte de compilar seu código para uma aplicação que utiliza e altera direta e cirurgicamente o DOM, ter um Virtual DOM seria redundante além de adicionar um runtime talvez desnecessário.
Reatividade
O que também me chamou muita atenção foi a atualização de variáveis de forma reativa. No código, basta adicionar uma instrução específica pro Svelte: "$:
".
Faz parte da sintaxe do JavaScript, é válido e até tem um nome específico: etiqueta. No JavaScript é utilizado como controle de fluxo em loops e em outras linguagens, geralmente como controle em goto
.
Resumindo, toda vez que uma atribuição de variável, expressão ou execução de função é utilizada à direita do sinal $:
será calculado ou executado novamente em caso de mudança de valores de variáveis utilizadas.
Stores
Como toda biblioteca de componentização de UI, não poderia faltar um gerenciador de estado. E suas Stores nativas foram desenvolvidas nesta versão já pensando em reatividade, utilizando um padrão já conhecido das pessoas desenvolvedoras que é o pub-sub.
E para usos simples, há um shorthand (escrita facilitada) onde facilita o uso de dados da Store sem se preocupar com subscribe ou unsubscribe.
Loops Eficazes
Outro ponto que achei legal é que mesmo lidando direto com o DOM, o Svelte se vira bem em relação a loops. Claro que infelizmente não é algo automático pois o Svelte precisa saber qual a key para cada elemento porém é possível trabalhar com eficácia na hora de utilizar loops, evitando repaints.
E falando em shorthands...
Gostei bastante da escrita de componentes, para as tarefas mais triviais sempre tem uma forma mais reduzida de se escrever, por exemplo, um two-way bind; repassar um evento, seja personalizado ou não; alternar classes CSS; usar rest-spread ou até mesmo...
Transições e animações!
Algo que eu realmente não esperava vir de brinde. Para animações, efeitos e transições triviais o Svelte possui uma mini biblioteca com uma coleção delas, e de fácil implementação.
Também é possível utilizar funções de animação e easing personalizadas, mas aí meu amigo:
Tags especiais
O Svelte também possui alguns componentes nativos que auxiliam no desenvolvimento de um código mais declarativo. Por exemplo, fica bem trivial obter a largura do viewport.
Dentre as tags especiais há funcionalidades como alterar tags no head dentro do Sapper, usar recursividade no próprio componente, usar componentes dinâmicos...
Compilador opinativo
Tanto o compilador quanto os linters de sintaxe (pelo menos digo isto em relação ao plugin de Svelte para Visual Studio Code) avisam quando há erros triviais de acessibilidade (imagem sem alt
) e código css
não utilizados pelo componente.
Reatividade (parte 2)
Quando ouço reatividade, a primeira coisa que veio à minha cabeça foi RxJS (digo pelo nome da lib)...
Pensei levianamente comigo: "e se eu trocasse a store nativa com autosubscribe por um Observable?" Tinha lido que haviam certas compatibilidades entre ambos e decidi testar por conta própria. Para minha surpresa:
(desculpe a bagunça no código)
Sim, o Svelte integra bem com RxJS.
edit: infelizmente o exemplo acima está rodando com Svelte v3.6. Quando houve a atualização para a v3.7 acabou quebrando. Por enquanto eu fixei o codesandbox de exemplo na versão v3.6 do Svelte. Agradecimentos ao @kaisermann novamente por ter me avisado :D
Deixo um lembrete: o Svelte não lida tão bem enquanto ainda não tiver recebido algo do stream (timeouts). Para evitar possíveis erros, recomendo uma das seguintes soluções: mesclar com um outro Stream, contendo um valor nullable e emitindo antes da resposta, assim podendo checar dentro de um {#if}
se já foi emitido algum valor ou englobar o stream numa Promise/generator e utilizar {#async}
.
Mas ...runtime?
Ok, eu menti quando falei que o Svelte não possui uma lib de runtime. Não tem, claro, para Virtual DOM pois como expliquei, seria redundante. Porém a runtime é bem enxuta. São praticamente funções que lembram Hooks do React.
Lifecycle
Os pares onMount
& onDestroy
relativos a renderização e beforeUpdate
& afterUpdate
relativos a atualização do componente.
Context
setContext
& getContext
. Também semelhante a contextos no React.
preloading
Este é exclusivo do Sapper. Este é executado quando utiliza-se diretivas nos links, carregando e executando dados antes mesmo do usuário clicar no elemento (no evento de mouseover
, predizendo sua ação).
E claro, SSR!
Fica a critério do desenvolvedor. Como anteriormente citado, o Sapper auxilia neste aspecto. Como anteriormente citado, esta ferramenta foi inspirada no Next.js. Claro que é possível juntar tudo num bundle utilizando somente o Svelte e criar sua SPA.
Porém usando o Sapper, é possível estender a funcionalidade da sua aplicação para utilizar um servidor com SSR (podendo inclusive utilizar Express).
Ou no melhor dos casos, exportar uma aplicação JAM Stack utilizando o sapper export
(algo como um Gatsby simplificado), gerando artefatos estáticos, prontos para subir para um CDN. O próprio Svelte lida automagicamente com a parte de hidratação da aplicação.
Problemas que tive
Claro que nem foi somente louros. Contarei algumas experiências:
Jest
Tive alguns problemas ao utilizar Stylus. Para testes, foi contornado utilizando um transformador próprio (neste exemplo estou utilizando somente Stylus, mas é possível integrar qualquer um existente. Aconselho a utilizar este transformador personalizado pois o jest-transformer-svelte
e a maioria dos outros pacotes similares possuem dependência com rollup, pessoalmente considero desnecessário e cria arquivos não referenciando o arquivo original. Apesar disto, lembro aqui que a cobertura de código é um tanto confusa para arquivos Svelte, senão inexistente, ou seja, não muito confiável. Logo aconselharia a descartar cobertura de código em projetos Svelte.
Prettier
Algo que me fez deixar preprocessadores em segundo plano foi que tive muitos problemas ao utilizar o plugin para Prettier. Este funciona muito bem para código de estilos feitos em CSS porém a integração com o Stylus não é bem definida e tive muitos problemas como formatação errônea. Como o plugin não integrava muito bem com preprocessadores, acabava transformando o código em algo ilegível e não parseável, e, para evitar escrever muitos prettier-ignore, recomendo evitar o uso de preprocessadores.
Para estilos em específico, vi também que ao utilizar um preprocessador o compilador não chega a verificar e validar estilos não utilizados pelo componente.
ESLint
Teve um bug em específico no ESLint (já corrigido) usando Sapper. Como o lint-staged passa o nome do arquivo e os arquivos de rota com parâmetro do Sapper (e do Next.js 9) usam colchetes, o ESLint interpretava os colchetes como parâmetro de busca do Bash e não encontrava o arquivo, mesmo escapando.
HMR
Outra dor de cabeça que tive, utilizando Sapper é que o live reload pode não funcionar muito bem ao utilizar funcionalidades do lifecycle do Sapper como o preloading. Caso for utilizar o Svelte puro não terá problemas, porém ao utilizar o SSR do Sapper, ele meio que se perde ao ter modificações no lado do código do servidor sendo necessário reiniciar a aplicação dependendo da modificação.
Conclusão
(como ensinado nas aulas de redação, tem que ter um, claro!)
Não me considero uma early adopter... hypera talvez. Porém a minha experimentação foi positiva e muito melhor do que eu esperava. Como disse, balançou meu coração que era anteriormente exclusivo do React. Muitas das funcionalidades acima listadas não são nem um pouco triviais de implementar nem no meu framework favorito.
Ainda é novidade e não há mercado para sua utilização por aqui (Brasil). Porém na minha opinião ainda tem muito potencial. Claro que muito do que eu falei tem meu viés. Mesmo curtindo React, meu perfil é muito mais tentar ir para o lado do SSR e otimizações estáticas, não curtindo tanto manter somente em SPA, mobile (e consequentemente webcomponents e micro frontend) e tentar aliviar ao máximo a execução da aplicação no navegador do usuário. Logo este framework acertou em cheio minhas expectativas.
Espero em breve ter Meetups à medida que sua adoção cresça (tenho esperanças rs).
Este post foi criado como uma resposta ao pedido do @felipefialho para falar sobre minhas experiências com o Svelte
Gostaria de agradecer a galera do Discord por terem ajudado em alguns pontos deste artigo.
Também agradeço o @kaisermann novamente, por ter ajudado a escrever este artigo.
Também:
Curto conversas mais informais e memes antigos... Dificilmente escrevo para a comunidade não sendo nos fóruns. Não é minha intenção ofender ninguém com postagens deste tipo. Peço também para não me ofender nos comentários lá embaixo se não achou graça neste post e achou que isto estragou o conteúdo. A tentativa foi para tentar deixar o conteúdo do post mais leve para leitura. Peço desculpas pelos erros, principalmente de concordância, pois vou alterando o texto de acordo com o que me passa pela cabeça e nem sempre os
diffs
ficam harmoniosos. Ainda mais tendo este texto como um compilado de tudo que passei durante esse tempo de experimentação. As opiniões expressadas são pessoais e sobre este específico momento. Nunca as tome como verdade e tanto minhas opiniões como as ferramentas descritas podem mudar e evoluir e se tornarem futuramente divergentes deste texto. BTW eu adicionei as imagens sem me preocupar em normalizá-las ou copyrights pois são somente ilustrativas (inclusive podem parar de funcionar pois hotlinkei ilegalmente, sendo bem amador mesmo). Este post não possui monetização (pelo menos não para mim, autor...). Adicionalmente, peço para levar na brincadeira sobre minha posição sobre React. Não existe melhor framework, e sim o melhor framework é aquele que melhor se adequa ao produto e ao time.
Join Us!
Referências
(os conteúdos exclusivos em inglês eu deixei uma bandeirinha unicode do lado: 🇬🇧)
Meta 🇬🇧
Posts relacionados
- Why I don't use web components 🇬🇧, por Rich Harris (post obviamente viesado, porém recomendo ler os comentários)
- Svelte: o framework JavaScript que não é um framework, por Thiago Frias
- Svelte: A era dos frameworks-compiladores, por Claudio Holanda
- Svelte 3 + Firebase: Criando um CRUD com a nova ferramenta JS, onde o Sergio Lima ensina a fazer uma aplicação integrada com o Firebase
- Disappearing Frameworks 🇬🇧, por Peter O'Shaughnessy
- Getting Started with Svelte 3 🇬🇧
- Svelte 3 Tutorial for The Impatient (React) Developer 🇬🇧, por Valentino Gagliardi
Com direito a tradução dos últimos dois artigos feita pelo Eduardo Rabelo:
Vídeos
Cursos
Changelog
2019-08-06
- Adicionado breve referência sobre Storybook
- Patchfix do codesandbox fixando o Svelte na versão 3.6
- Adicionado o post do Sergio Lima nas Referências
2022-10-19
- Adicionando descrição para as imagens (espero não ter pulado nenhuma)
- Alteração de pronomes e utilização de linguagem neutra (posso ter também passado batido por algo)
Top comments (4)
Parabéns pelo artigo, Carlos. Eu fiz um passo a passo com o Svelte aqui: escoladejavascript.com/crud-com-sv...
Muito bom, tbm admito que sou meio fanboy do react, mas o svelte também me chamou muito atenção quando vi a apresentação do Rick xD
acho que vale dar uma olhada... mesmo com two-way binding, achei daora pelas facilidades de bindings e reatividade :D
Muito bom, post divertido e informativo. Vlw por escrever!