![Por que grandes modelos de linguagem não substituirão codificadores humanos](https://optimuscloud.com.br/wp-content/uploads/2024/02/1709223715_Por-que-grandes-modelos-de-linguagem-nao-substituirao-codificadores-humanos-150x150.jpg)
Por que grandes modelos de linguagem não substituirão codificadores humanos
29 de fevereiro de 2024![Painel de desenvolvedores quer um ‘Jamstack anticapitalista’](https://optimuscloud.com.br/wp-content/uploads/2024/02/1709235753_Painel-de-desenvolvedores-quer-um-‘Jamstack-anticapitalista-150x150.jpg)
Painel de desenvolvedores quer um ‘Jamstack anticapitalista’
29 de fevereiro de 2024Neste post, explicarei como construir uma pesquisa de site usando as coleções de conteúdo do Astro, endpoints estáticos e a integração Astro do Qwik com Fuse.js.
Preparei um site de demonstração e um repositório de código aberto, que você encontrará nos seguintes links:
- 🚀 https://tns-astro-site-search.netlify.app
- ⚙️ https://github.com/PaulieScanlon/tns-astro-site-search
O que são coleções de conteúdo?
O Astro tem uma maneira conveniente de consultar “em massa” ou transformar conteúdo de tipos semelhantes. No caso da minha demonstração, isso se aplicaria a postagens de blog todas escritas em MDX. Todas as postagens do blog compartilham o mesmo modelo ou layout e esquema. Aqui está o esquema para postagens do blog.
// src/content/config.js import { z, defineCollection } from 'astro:content'; export const collections = { posts: defineCollection({ type: 'content', schema: z.object({ draft: z.boolean().optional(), audioFeedId: z.string().optional(), base: z.string(), title: z.string(), tags: z.array(z.string()).optional(), date: z.date(), author: z.string(), featuredImage: z.string(), }), }), };
Você pode ver o src
no repositório aqui: src/content/config.js.
E para garantir, aqui está o tema inicial de uma das postagens do meu blog (mas todas as postagens do blog usarão o mesmo esquema).
// src/content/posts/2024/02/the-qwik-astro-audiofeed-experiment.mdx --- base: posts title: The Qwik, Astro, Audiofeed Experiment tags: (Qwik, Astro, Audiofeed, AI) date: 2024-02-06 author: Paul Scanlon featuredImage: https://res.cloudinary.com/www-paulie-dev/image/upload/v1707261626/paulie.dev/2024/02/get-started-with-qwik-astro_qtxmyq.jpg ---
Você pode ver o src
no repositório aqui: the-qwik-astro-audiofeed-experiment.mdx.
Como consultar as coleções de conteúdo do Astro
Para criar a funcionalidade de pesquisa no site, primeiro preciso consultar todas as postagens do blog. Consegui isso usando um endpoint estático. eu liguei all-content.json.js
e vive no src/pages
diretório. Por exemplo:
// src/pages/all-content.json.js import { getCollection } from 'astro:content'; export const GET = async () => { const posts = await getCollection('posts'); const search = posts .filter((item) => item.data.draft !== true) .map((data) => { const { slug, data: { base, title, date }, } = data; return { date: date, title: title, base: base, path: `/${base}/${slug}`, }; }) .sort((a, b) => b.date - a.date); return new Response(JSON.stringify({ search })); };
Depois de consultar todas as postagens do blog usando getCollection('posts')
faço um filtro rápido para remover quaisquer postagens de blog que possam estar no modo rascunho, depois retorno apenas os campos do assunto inicial que serão úteis para a pesquisa e, em seguida, classifico-os por data.
O resultado é stringificado e retornado como uma resposta padrão.
Aqui está a aparência do resultado.
( { date: 2024-02-22T00:00:00.000Z, title: 'How to Build a Survey With KwesForms and Astro', base: 'posts', path: '/posts/2024/02/how-to-build-a-survey-with-kwesforms-and-astro' }, { date: 2024-02-06T00:00:00.000Z, title: 'The Qwik, Astro, Audiofeed Experiment', base: 'posts', path: '/posts/2024/02/the-qwik-astro-audiofeed-experiment' } ... )
Você pode ver o src
no repositório aqui: src/pages/all-content.json.js.
Esses dados fornecem tudo que preciso para começar a construir o componente de pesquisa.
Como consultar um endpoint estático
Para construir o componente de pesquisa (a seguir!), Primeiro preciso consultar os dados do endpoint estático e passá-los para o componente de pesquisa. Eu consulto os dados no meu componente de layout, que está presente em cada página do meu site de demonstração, por exemplo:
// src/pages/index.astro --- import Layout from '../layouts/layout.astro'; --- <Layout> <h1>Lorem ipsum</h1> <p>...</p> </Layout>
Você pode ver o src
no repositório aqui: src/pages/index.astro.
E aqui está o componente de layout que faz uma solicitação do lado do servidor para o endpoint.
// src/layouts/layout.astro --- import Search from '../components/search'; const content = await fetch(`${import.meta.env.PROD ? 'https://tns-astro-site-search.netlify.app' : 'http://localhost:4321'}/all-content.json`); const { search } = await content.json(); --- <html lang='en'> <head>...</head> <body> <header> <Search data={search} /> </header> <main> <slot /> </main> </body> </html>
Uma coisa a destacar aqui é a URL usada na busca. Se o site for implantado e PROD
é true
o URL para o endpoint estático será https://tns-astro-site-search.netlify.app/all-content.json e, durante o desenvolvimento, o URL do host local será usado.
Desde que eu consiga consultar os dados de pesquisa, posso transmiti-los ao meu componente de pesquisa por meio do data
suporte.
Você pode ver o src
no repositório aqui: src/layouts/layout.astro.
Construindo o Componente de Pesquisa
Existem duas dependências adicionais a serem instaladas para construir o componente de pesquisa. Eles são os seguintes.
npm install fuse.js @qwikdev/astro
Fusível.js
Usei o Fuse.js para ajudar na “pesquisa difusa”. Os toques do teclado são capturados e transmitidos pelo Fuse.js. Se alguma das letras ou palavras corresponder a um título ou data, Fuse.js retornará o item.
Qwik
Eu uso a integração Astro do Qwik para ajudar a gerenciar o estado do lado do cliente. Qwik é mais leve que React e menos detalhado que JavaScript vanilla.
As etapas restantes abordarão como configurar a pesquisa e a filtragem. Criei um exemplo simples, que você pode visualizar aqui: https://tns-astro-site-search.netlify.app/simple. O src
pode ser encontrado aqui: src/components/simple-search.jsx.
Observação: o exemplo usado em minha demonstração contém muito CSS e JavaScript adicionais para lidar com o modal, o que não é necessário para criar a funcionalidade de pesquisa.
Componente de pesquisa: Etapa 1
A primeira etapa é criar o componente de pesquisa e retornar uma entrada HTML. Adicione um onInput$
manipulador de eventos e crie uma função chamada handleInput
para capturar as teclas digitadas.
// src/components/simple-search.jsx import { component$, $ } from '@builder.io/qwik'; const Search = component$(({ data }) => { const handleInput = $(async (event) => { const { target: { value }, } = event; }); return ( <div> <input type="text" placeholder="Search" onInput$={handleInput} /> </div> ); }); export default Search;
Componente de pesquisa: Etapa 2
Próxima importação useSignal
e crie duas novas constantes para armazenar os valores de todos os dados e dos dados filtrados.
// src/components/simple-search.jsx - import { component$, $ } from '@builder.io/qwik'; + import { component$, $, useSignal } from '@builder.io/qwik'; const Search = component$(({ data }) => { + const all = useSignal(data); + const filtered = useSignal(data); const handleInput = $(async (event) => { const { target: { value }, } = event; }); return ( <div> <input type="text" placeholder="Search" onInput$={handleInput} /> </div> ); }); export default Search;
Componente de pesquisa: Etapa 3
Em seguida, importe e inicialize o Fuse.js. A configuração do Fuse.js aceita o valor do useSignal
const (all.value
) e aplicará um limite de filtro difuso de 0,5 quando qualquer valor de entrada corresponder aos valores do título ou data.
fuse.search
pode ser usado para filtrar quaisquer itens do array que não atendam aos parâmetros de configuração, e um novo array é retornado. Chamei esse novo array de “resultados”.
// src/components/simple-search.jsx import { component$, $, useSignal } from '@builder.io/qwik'; const Search = component$(({ data }) => { const all = useSignal(data); const filtered = useSignal(data); const handleInput = $(async (event) => { const { target: { value }, } = event; + const FuseModule = await import('fuse.js'); + const Fuse = FuseModule.default; + const fuse = new Fuse(all.value, { + threshold: 0.5, + keys: ('title', 'date'), + }); + const results = fuse.search(value).map((data) => { + const { item: { base, path, title, date } } = data; + return { + title, + date, + path, + base, + }; }); }); return ( <div> <input type="text" placeholder="Search" onInput$={handleInput} /> </div> ); }); export default Search;
Componente de pesquisa: Etapa 4
O próximo passo é adicionar um if
declaração. Se houver um valor capturado da entrada HTML, defino useSignal
filtered.value
igual aos resultados, e se não houver nenhum valor capturado da entrada HTML, então defino o useSignal
filtered.value
igual ao all.value
.
Isso retornará uma lista filtrada ou a lista inteira.
// src/components/simple.search.jsx import { component$, $, useSignal } from '@builder.io/qwik'; const Search = component$(({ data }) => { const all = useSignal(data); const filtered = useSignal(data); const handleInput = $(async (event) => { ... + if (value) { + filtered.value = results; + } else { + filtered.value = all.value; + } }); return ( <div> <input type="text" placeholder="Search" onInput$={handleInput} /> </div> ); }); export default Search;
Componente de pesquisa: Etapa 5
A etapa final é iterar sobre o filtered.value
(se tiver comprimento) e retorne uma lista de itens. Se não houver resultados, então eu retorno null
.
// src/components/simple-search.jsx import { component$, $, useSignal } from '@builder.io/qwik'; const Search = component$(({ data }) => { const all = useSignal(data); const filtered = useSignal(data); const handleInput = $(async (event) => { ... }); return ( <div> <input type="text" placeholder="Search" onInput$={handleInput} /> + <ul> + {filtered.value.length > 0 + ? filtered.value.map((data, index) => { + const { path, title } = data; + return ( + <li key={index}> + <a href={path}>{title}</a> + </li> + ); + }) + : null} + </ul> </div> ); }); export default Search;
Finalizado
E é isso, são todos os princípios por trás de como consultar dados usando as coleções de conteúdo do Astro, como disponibilizar os dados usando um endpoint estático e, em seguida, implementar a pesquisa difusa usando Fuse.js e a integração Astro do Qwik para gerenciar o estado do lado do cliente .
Usei essa mesma abordagem em meu site e está funcionando muito bem até agora!
A postagem Como construir pesquisa de sites com Astro, Qwik e Fuse.js apareceu pela primeira vez no The New Stack.