A mais nova estrutura para criar aplicativos da web com Svelte está aqui: SvelteKit. Essa estrutura é fácil de usar, mesmo para desenvolvedores menos experientes.

SvelteKit é o sucessor do Sapper, um framework JavaScript compacto, mas poderoso, desenvolvido por Svelte. A nova versão do SvelteKit é uma atualização do que o Sapper oferece e está atualmente em versão beta pública.

Explorar pessoalmente o SvelteKit me deixou impressionado pelo fato de ser muito fácil de entender; ele tem menos conceitos para aprender em comparação com outras estruturas populares como React.

Vamos nos aprofundar no básico do Svelte e do SvelteKit e, eventualmente, explorar um exemplo do SvelteKit.

O que é Svelte e SvelteKit?

Svelte é uma biblioteca de componentes como React , e SvelteKit é o framework de aplicativo como Next.js. Embora semelhante, o motivo pelo qual o Svelte se diferencia do React é porque ele fornece uma maneira diferente de pensar sobre os aplicativos da web.

O React usa o diffing virtual do DOM para decidir as mudanças necessárias para atualizar uma IU, mas o Svelte é um compilador, que compila o seu código e converte os componentes do Svelte em JavaScript para renderizá-los e atualizá-los, tornando-o mais rápido e mais leve. >

O SvelteKit então faz todo o trabalho pesado de configurar um aplicativo com renderização do lado do servidor, roteamento e muito mais, assim como Next.js. No entanto, o SvelteKit também usa um adaptador que pode exportar seu aplicativo para uma plataforma específica e se adapta bem à arquitetura sem servidor. Como a arquitetura sem servidor está se tornando mais proeminente, é um bom motivo para experimentar o SvelteKit.

Você pode usar os adaptadores SvelteKit oficiais para plataformas como Netlify e Vercel.

Ao fornecer também recursos como renderização do lado do servidor, divisão de código e muito mais, o SvelteKit é especialmente útil para iniciantes.

Com isso, vamos ver como podemos criar um novo projeto com o SvelteKit.

Configurando o SvelteKit

Antes de codificar um aplicativo de exemplo, vamos brincar com o aplicativo de demonstração que você obtém ao criar um novo projeto com o SvelteKit e revisar alguns conceitos-chave que irão familiarizá-lo com a estrutura.

Instalação

Comece inserindo o seguinte trecho de código em um terminal. Isso irá configurar um aplicativo no diretório atual.

 npm init svelte @ next

Em seguida, insira o seguinte para instalar todas as dependências e pronto.

 npm install

Além disso, se você estiver usando o Visual Studio Code, instale a extensão oficial Svelte para destaque de sintaxe e outros recursos para escrever componentes Svelte, como páginas de aplicativos.

SvelteKit configura um sistema de roteamento onde os arquivos em seu src/routes determinam as rotas em seu aplicativo. Este diretório pode ser alterado editando svelte.config.cjs .

Observe que src/routes/index.svelte é a página inicial.

Ao inserir npm run dev , você inicia um servidor de desenvolvimento. O SvelteKit usa o Vite nos bastidores, fazendo atualizações muito rápidas.

Neste ponto, instale o adaptador estático para construir a versão pré-renderizada de todo o aplicativo usando o seguinte:

 npm i-D @ sveltejs/adapter-static @ next

Agora, vamos explorar alguns códigos, fazer algumas alterações e ver o resultado.

Roteamento

Adicionaremos outra rota ao aplicativo de contador que o SvelteKit inicializou para nós inserindo about.svelte no diretório src/routes/.

 
  Sobre 

Página Sobre

Esta é a página sobre. Clique aqui para ir para a página de índice.

Como você provavelmente pode imaginar, isso definirá outra rota para nós em /about . Para navegar até esta página, adicionaremos um link para a página de índice também.

A página de índice já possui a seguinte linha:

 

Visite svelte.dev para aprender como construir aplicativos Svelte.

Vamos apenas alterá-lo para o código abaixo:

 

Visite a página sobre

Quando clicamos no link, o roteador interno entra em ação e controla a navegação. Na verdade, o SvelteKit lida com a navegação por padrão. A carga inicial é tratada no lado do servidor, então o roteador embutido do SvelteKit lida com a navegação subsequente no lado do cliente, a menos que especifique o contrário.

O SvelteKit permite que você desative este roteador alterando o arquivo de configuração do Svelte svelte.config.cjs . Definir a propriedade router como false desativa o roteador de todo o aplicativo. Isso fará com que o aplicativo envie novas solicitações para cada página, o que significa que a navegação será tratada no lado do servidor.

Você também pode desativar o roteador por página, se necessário. Vamos prosseguir e ver isso em ação adicionando o seguinte ao topo de about.svelte :

 

Falarei sobre context="module" e lang="ts" em breve. Por enquanto, vamos executar o aplicativo por npm run dev . Devemos esperar que todo o roteamento da página Sobre seja tratado pelo servidor, ou seja, ao navegar da página Sobre, novas solicitações serão feitas ao servidor. Esta é uma pequena funcionalidade excelente que o SvelteKit nos oferece completamente fora da caixa.

Scripts e estilos

Olhando para o script com o qual estávamos trabalhando, os scripts que contêm context="module" são adicionados diretamente ao módulo. Isso significa que eles são executados uma vez sempre que o componente é inicializado, ao contrário de outros scripts sem context="module", que se tornam parte da instância-o componente-e são executados sempre que uma instância é criada e inicializada.

Portanto, as variáveis ​​em são compartilhadas entre as instâncias da exportação padrão do módulo, que é o próprio componente.

O lang="ts" informa ao compilador que a linguagem usada é TypeScript. Você precisa usar isso se escolheu TypeScript como a linguagem durante a configuração. Se você estiver usando JavaScript, não há necessidade de fazer nada aqui.

Como uma pequena experiência, vamos adicionar isso ao topo de src/lib/Counter.svelte :

 

E então, adicione esta linha ao topo do script de nível de instância já presente:

 console.log ("código do componente");

Também incluiremos outro componente de contador em index.svelte adicionando .

Então, o que vemos quando executamos isso? Como os dois contadores são independentes um do outro, os registros mostram que o”código do módulo”foi executado primeiro e, em seguida, as duas mensagens do”código do componente”aparecem.

Agora, vamos adicionar isso ao final de about.svelte :

 

No Svelte, os estilos aplicados aos componentes têm como escopo o componente. Este estilo só será aplicado à página Sobre.

Você também notará o componente $ layout.svelte dentro de routes/; isso pode exibir e estilizar coisas que são persistentes em diferentes rotas, como o rodapé, por exemplo.

Layout

Vamos mergulhar em como o componente de layout pode envolver cada componente dentro de si, tornando-o um lugar ideal para executar funções como fornecer a loja e configurar o contexto.

Primeiro, vamos adicionar isso ao arquivo $ layout.svelte :

 

Em seguida, adicione instruções de registro semelhantes às rotas index.svelte e about.svelte . Inicie o servidor de desenvolvimento e observe o console em seu navegador; a mensagem de layout aparece primeiro e, em seguida, a mensagem de índice.

O console em seu navegador mostra a mensagem de layout primeiro, depois a mensagem de índice.

Agora, quando navegamos para a página Sobre, os logs mostram a linha adicionada sobre o componente

Os logs da página Sobre mostram o anúncio ded Sobre a linha de componentes

Conforme o componente $ layout é renderizado primeiro, as páginas são adicionadas e removidas do layout conforme são necessárias para o roteador.

Você também pode usar o método de ciclo de vida onDestroy , que Svelte fornece para verificar se o componente de layout é renderizado apenas uma vez e nunca é desmontado ao navegar para páginas diferentes. Ao adicionar essas linhas a $ layout.svelte , você notará que nenhum registro aparece no console:

 import {onDestroy} de'svelte';
onDestroy (()=> console.log ("$ layout unmounted"));

onDestroy nunca é chamado, mesmo quando navegamos entre as páginas.

Podemos usar esse comportamento a nosso favor, buscando alguns dados de que muitas páginas precisam ou configurando um armazenamento centralizado (que veremos mais tarde) que outras páginas podem usar para transmitir dados umas às outras.

Se você está familiarizado com Svelte ou React, adicionar contexto ao código nos poupa de perfuração de suporte. Em nosso exemplo, podemos adicionar contexto para dados em $ layout.svelte para todas as páginas e seus componentes a receber.

O lado do servidor

Sabemos que o SvelteKit, por padrão, renderiza o aplicativo no lado do servidor durante o primeiro carregamento. Mas e se quiséssemos preencher nosso aplicativo com dados durante o SSR sem mostrar aos usuários um botão giratório de carregamento? Ou como passamos dados do servidor para o cliente?

Bem, o SvelteKit fornece ganchos que são executados apenas no servidor e nos ajudam a atingir esses objetivos. Mas antes de explorar os ganchos, quero falar sobre endpoints para entender melhor o lado do servidor.

Os pontos de extremidade estão do lado do servidor e são criados de maneira semelhante às páginas e rotas. No entanto, os arquivos que são endpoints terminarão com uma extensão .js ou .ts no diretório routes .

//src/routes/dogs.ts
importar tipo {RequestHandler, Response} de"@ sveltejs/kit"; interface dog {
nome: string
}
cães const: cachorro []=[{nome:"Pastor Alemão"}, {nome:"BullDog"}, {nome:"Poodle"}]
export const get: RequestHandler=async ()=> { const res: Resposta={ corpo:{ cachorros } } return res;
}

O nome do método get corresponde ao método HTTP GET. Este endpoint está disponível em /dogs . Se você navegar para /dogs em seu navegador, encontrará uma resposta JSON contendo a lista de cachorros.

Com os ganchos, você tem um controle mais preciso sobre o lado do servidor, criando um local ideal para executar funções como autenticação, porque eles também recebem o objeto de solicitação HTTP do cliente. Existem três ganchos no SvelteKit e usaremos getContext e getSession na próxima seção.

Construindo no SvelteKit

Compreendendo os fundamentos do ecossistema SvelteKit, podemos construir um aplicativo de brinquedo muito simples que buscará dados de uma fonte que iremos configurar, realizará alguma autenticação simples e configurará um armazenamento central.

Nosso aplicativo conterá as seguintes rotas: /counter1 , /counter2 , /about e /login . As páginas do contador serão protegidas e a página Sobre não.

Portanto, vamos nos concentrar primeiro na lógica de autenticação.

Autenticação

Uma vez que os ganchos são executados no servidor em cada solicitação antes de qualquer outra coisa ser executada e porque eles têm acesso aos parâmetros da solicitação, src/hooks.ts é o lugar ideal para extrair cookies e criar um sessão para o usuário.

Observe que a sessão não é uma sessão em seu sentido típico; o lado do servidor não manterá nenhum registro das sessões. A sessão que usaremos aqui simplesmente nos ajudará a passar os dados para o lado do cliente e fornecer o estado inicial.

O gancho getContext recebe os cabeçalhos da solicitação, que podem ou não conter cookies, dependendo da autenticação de uma solicitação. Quando extraímos o token de autenticação e o retornamos, o próximo gancho receberá esse contexto como um parâmetro.

Qualquer coisa retornada do gancho getSession está disponível para todas as páginas como uma variável de sessão.

//src/hooks.ts
import {defaultState} de'$ lib/store';
importar * como cookie de'cookie';
const auth_token='demo_token_for_example';
const userDetails={nome:"Deb", idade: 45} export const getContext: GetContext=({headers})=> { cookies const=cookie.parse (cabeçalhos.cookie ||''); Retorna { token: cookies ['token'] };
}
export const getSession: GetSession=async ({context})=> { let initialState={... defaultState}; if (contexto ['token']===auth_token) { console.log ("correspondência de tokens"); initialState.authenticated=true initialState.user=userDetails; } console.log (initialState) return initialState
}

Para fins de brevidade e simplicidade, armazenaremos o token de autenticação e os detalhes do usuário no próprio arquivo. Em um projeto real, você provavelmente usaria um banco de dados para isso ou um back-end de autenticação.

A ideia é extrair um cookie dos cabeçalhos em getContext e verificar se ele possui o token correto. Se ele contiver o token correto, retornamos o estado inicial “autenticado”. Não se preocupe com o initialState , veremos $ lib/store posteriormente nesta postagem.

Agora vamos configurar um endpoint que aceitará uma solicitação GET e retornará um cookie contendo o token. Isso será útil no componente de login.

//src/routes/auth.ts
const auth_token='demo_token_for_example';
const cookie=`token=$ {auth_token}; HttpOnly; Seguro`
cabeçalho const: Cabeçalhos={'set-cookie': cookie}
export const get: RequestHandler=()=> { Retorna{ cabeçalhos: cabeçalho, corpo:{ token: auth_token, sucesso: verdadeiro, do utilizador:{ nome:"Deb", idade: 45 } } } }

Novamente, os detalhes do usuário serão normalmente obtidos de um banco de dados. Mas aqui, nós os estamos codificando para simplificar.

Construindo a loja

Se você não está familiarizado com os armazenamentos graváveis ​​do Svelte, eles podem ser gravados de e para qualquer lugar dentro do aplicativo e são reativos. Esta é uma maneira simples de configurar um armazenamento gravável que armazenará o estado global de nosso aplicativo.

//src/lib/store.ts
import {gravável, gravável} de'svelte/store';
export type User={ nome: string | null, idade?: número
}
export interface stateType { autenticado: booleano, usuário: usuário, contador: número
}
export const defaultState: stateType={ autenticado: falso, do utilizador:{ nome: nulo, }, contador: 0
}
exportar classe padrão Store { estado: Gravável ; construtor (initialState: stateType=defaultState) { this.state=gravável ({... initialState}) } changeAuthenticationState=(usuário: Usuário)=> { this.state.update ((obj)=> { console.log ("estado antigo") console.log (obj) Retorna { ... obj, autenticado:! obj.authenticated, usuário: usuário } }) } updateCounter=(val: number)=> { this.state.update ((obj)=> { Retorna { ... obj, contador: val } }) }
}

A seguir, vamos configurar um contexto na raiz $ layout.svelte e fornecer nossa loja para todos os descendentes, permitindo que todas as páginas acessem a loja.

 



Observe como estamos criando uma nova loja usando o estado inicial que recebemos da sessão e passando-o para setContext . A loja agora pode ser acessada em qualquer página pela tecla 'store'.

A função load

Nossas páginas também podem exportar uma função especial chamada função load . Essa função pode buscar dados ou gravar na sessão antes que o componente seja renderizado, primeiro executando no lado do servidor e, em seguida, no lado do cliente. Isso é especialmente útil durante a renderização do lado do servidor, pois podemos precisar preencher nossa página com dados que devem ser buscados com antecedência.

 


Página de login

Na função load da página de Login, podemos verificar se o usuário está autenticado, pois não queremos exibir a página de Login para o usuário autenticado.

Se eles forem autenticados, nós os redirecionamos para a página /counter1 . Caso contrário, buscamos o token e atualizamos o estado. Uma vez autenticados, podemos navegar para as rotas protegidas como /counter1 .

Os contadores

A função load de counter1.svelte verifica se o usuário está autenticado e o redireciona para a página de Login, caso não esteja. Realizamos essa verificação apenas no lado do servidor, pois nosso aplicativo está estruturado de uma forma que não fornece nenhuma maneira de navegar para a página /counter1 sem realizar uma solicitação completa ao servidor.

 

  Contador 1 

Olá {$ state.user.name}

Visite Contador2

No entanto, não incluímos links para as páginas protegidas em qualquer página desprotegida, portanto, não há como navegar até elas sem um carregamento completo. Isso significa que uma solicitação ao servidor será feita.

Quando uma solicitação de /counter1 é feita, getSession é executado e atribui o estado inicial, que define o contador para 0. O load a função então executa e atualiza o valor do contador para 1, enviando a sessão atualizada para o componente de layout para configurar a loja com o estado atualizado.

Observe que se tivéssemos uma função de carregamento em $ layout.svelte , ela seria executada antes da função de carregamento de counter1.svelte .

A página /counter2 é a mesma que /counter1 , exceto que inicializamos o contador em 2, solicitando que a Linha 13 se tornasse session.counter=2 .

No código a seguir, podemos usar o componente contador nas páginas /counter1 e /counter2 :

 

 Cliques: {contagem}

Concluindo

Para finalizar o aplicativo, devemos adicionar a página about.svelte :

 

página Sobre

Criando um build de produção

npm run build criará um build de produção para nós. Como estamos usando o adaptador de nó padrão, obtemos um servidor de nó em /build e disponibilizamos o aplicativo usando node build .

Conclusão

Usando o SvelteKit, conseguimos criar um aplicativo contendo SSR, autenticação e uma loja em apenas alguns minutos!

Como a estrutura do SvelteKit ainda está em beta, pode ser difícil encontrar respostas se você enfrentar problemas ao trabalhar com ela. No entanto, se atender aos requisitos do seu projeto, pode ser incrivelmente eficaz.

A postagem Explorando o SvelteKit, a mais nova estrutura baseada em Svelte apareceu primeiro no LogRocket Blog .