<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Strift</title>
    <description>The latest articles on DEV Community by Strift (@strift).</description>
    <link>https://dev.to/strift</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F651042%2F72ede91d-13b7-4b47-a4b7-e874cd8045bc.jpeg</url>
      <title>DEV Community: Strift</title>
      <link>https://dev.to/strift</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/strift"/>
    <language>en</language>
    <item>
      <title>Vector storage is coming to Meilisearch to empower search through AI</title>
      <dc:creator>Strift</dc:creator>
      <pubDate>Tue, 11 Jul 2023 11:05:36 +0000</pubDate>
      <link>https://dev.to/meilisearch/vector-storage-is-coming-to-meilisearch-to-empower-search-through-ai-3i1f</link>
      <guid>https://dev.to/meilisearch/vector-storage-is-coming-to-meilisearch-to-empower-search-through-ai-3i1f</guid>
      <description>&lt;p&gt;Vector search enables efficient retrieval of objects sharing similar characteristics. This AI-powered search technique uses embedding vectors. These vectors are mathematical representations of objects generated by machine learning models (like LLMs). In the upcoming 1.3 release, Meilisearch will support storing and searching vectors.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The release candidate for Meilisearch v1.3 is out—&lt;a href="https://github.com/meilisearch/meilisearch/releases/tag/v1.3.0-rc.0"&gt;try it now&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Powering the Future of Search
&lt;/h2&gt;

&lt;p&gt;Vector search might be the dawn of a new era for search. Its use cases are numerous. In &lt;a href="https://ecommerce.meilisearch.com/?utm_campaign=vector-search&amp;amp;utm_source=devto"&gt;ecommerce&lt;/a&gt;, it enables offering recommendations for similar products. It also allows building multi-modal search, like image or audio search. Building upon conversational AI technologies enables the creation of Q&amp;amp;A applications. Combining vector search with user-provided information like geolocation and search history can power even more contextual search experiences. &lt;/p&gt;

&lt;p&gt;Vector search is also the foundation for &lt;a href="https://en.wikipedia.org/wiki/Semantic_search"&gt;semantic search&lt;/a&gt;, which aims to understand the query’s meaning. Conversely, traditional lexical search only matches keywords. With semantic search, a &lt;code&gt;warm clothes&lt;/code&gt; query could give results like &lt;code&gt;gloves&lt;/code&gt;, &lt;code&gt;coat&lt;/code&gt;, and more results related to winter clothing.&lt;/p&gt;

&lt;p&gt;Vector search unlocks a world of new capabilities for search. Take a look at what some users have already implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/adrienpoly/rubyvideo/pull/19"&gt;similar videos recommendations&lt;/a&gt; on a site listing Ruby conferences&lt;/li&gt;
&lt;li&gt;a &lt;a href="https://blazy-chat.vercel.app/"&gt;documentation chatbot&lt;/a&gt; proof of concept using &lt;a href="https://platform.openai.com/docs/models/gpt-3-5"&gt;GPT3.5&lt;/a&gt; and &lt;a href="https://github.com/hwchase17/langchain"&gt;LangChain&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started with Meilisearch vector store
&lt;/h2&gt;

&lt;p&gt;Starting with v1.3, you can use Meilisearch as a vector store. Meilisearch allows you to store vector embeddings alongside your documents conveniently. You will need to create the vector embeddings using your third-party tool of choice (&lt;a href="https://huggingface.co/"&gt;Hugging Face&lt;/a&gt;, &lt;a href="https://openai.com/"&gt;OpenAI&lt;/a&gt;). As we published the first &lt;a href="https://github.com/meilisearch/meilisearch/releases/tag/v1.3.0-rc.0"&gt;v1.3 release candidate&lt;/a&gt;, you can try out vector search today.&lt;/p&gt;

&lt;p&gt;First, pull the release candidate by using this Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 7700:7700 &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/meili_data:/meili_data getmeili/meilisearch:v1.3.0-rc.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, enable the vector store experimental feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; PATCH &lt;span class="s1"&gt;'http://localhost:7700/experimental-features/'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;  &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-binary&lt;/span&gt; &lt;span class="s1"&gt;'{
    "vectorStore": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 This guide uses curl to make HTTP requests to communicate with Meilisearch. When v1.3 will officially be released, you will be able to use the corresponding &lt;a href="https://github.com/meilisearch/integration-guides"&gt;SDK methods&lt;/a&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Meilisearch now accepts a &lt;code&gt;_vector&lt;/code&gt; field in your documents. Use it to store the vector embeddings corresponding to your document in this field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="s1"&gt;'localhost:7700/indexes/songs/documents'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--data-binary&lt;/span&gt; &lt;span class="s1"&gt;'[
         { "id": 0, "_vectors": [0, 0.8, -0.2], "title": "Across The Universe" },
         { "id": 1, "_vectors": [1, -0.2, 0], "title": "All Things Must Pass" },
         { "id": 2, "_vectors": [[0.5, 3, 1], [-0.2, 4, 6]], "title": "And Your Bird Can Sing" }
     ]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After storing your vectorized documents in Meilisearch, you can query them using the &lt;code&gt;search&lt;/code&gt; or &lt;code&gt;multi-search&lt;/code&gt; route. To do this, you need to compute the vector of your query (using a third-party tool) and send it in the &lt;code&gt;vector&lt;/code&gt; field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="s1"&gt;'localhost:7700/indexes/songs/search'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--data-binary&lt;/span&gt; &lt;span class="s1"&gt;'{ "vector": [0, 1, 2] }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using vector search, returned documents include a &lt;code&gt;semanticScore&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"hits"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"id"&lt;/span&gt;: 0, &lt;span class="s2"&gt;"_vectors"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;0, 0.8, &lt;span class="nt"&gt;-0&lt;/span&gt;.2], &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Across The Universe"&lt;/span&gt;, &lt;span class="s2"&gt;"_semanticScore"&lt;/span&gt;: 0.6754 &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"id"&lt;/span&gt;: 1, &lt;span class="s2"&gt;"_vectors"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;1, &lt;span class="nt"&gt;-0&lt;/span&gt;.2, 0], &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"All Things Must Pass"&lt;/span&gt;, &lt;span class="s2"&gt;"_semanticScore"&lt;/span&gt;: 0.7546 &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"id"&lt;/span&gt;: 2, &lt;span class="s2"&gt;"_vectors"&lt;/span&gt;: &lt;span class="o"&gt;[[&lt;/span&gt;0.5, 3, 1], &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-0&lt;/span&gt;.2, 4, 6]], &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"And Your Bird Can Sing"&lt;/span&gt;, &lt;span class="s2"&gt;"_semanticScore"&lt;/span&gt;: 0.78 &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"query"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
  &lt;span class="s2"&gt;"vector"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;0, 1, 2],
  &lt;span class="s2"&gt;"processingTimeMs"&lt;/span&gt;: 0,
  &lt;span class="s2"&gt;"limit"&lt;/span&gt;: 20,
  &lt;span class="s2"&gt;"offset"&lt;/span&gt;: 0,
  &lt;span class="s2"&gt;"estimatedTotalHits"&lt;/span&gt;: 2
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;📢 This API is experimental. You can help us improve it by sharing your feedback in &lt;a href="https://github.com/meilisearch/product/discussions/677"&gt;this Github discussion&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A First Step Toward Semantic Search
&lt;/h2&gt;

&lt;p&gt;Vector search is our first step towards semantic search. But our long-term goal is to provide hybrid search—combining the benefits of full-text and semantic search to provide the most relevant search experience. Clément Renault, founder and CTO of Meilisearch, shared his thoughts on Github about &lt;a href="https://github.com/meilisearch/meilisearch/issues/3838"&gt;exploring semantic search&lt;/a&gt; — read for a founder’s perspective. We can’t wait to share more with you!&lt;/p&gt;

&lt;p&gt;Drop your email below to learn more about our progress with AI-powered search. We’ll keep you posted on all updates regarding vector search &amp;amp; semantic search.&lt;/p&gt;

&lt;p&gt;We’re excited to walk our first steps toward semantic search. We can’t wait to hear your thoughts on integrating Meilisearch as a vector store. You can give your feedback in &lt;a href="https://github.com/meilisearch/product/discussions/677"&gt;this Github discussion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can stay in the loop by subscribing to our &lt;a href="https://meilisearch.us2.list-manage.com/subscribe?u=27870f7b71c908a8b359599fb&amp;amp;id=79582d828e"&gt;newsletter&lt;/a&gt;. To learn more about Meilisearch's future and help shape it, look at our &lt;a href="https://roadmap.meilisearch.com/"&gt;roadmap&lt;/a&gt; and participate in our &lt;a href="https://github.com/meilisearch/product/discussions/"&gt;Product Discussions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For anything else, join our developers community on &lt;a href="https://discord.gg/meilisearch"&gt;Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ll see you there.&lt;/p&gt;

</description>
      <category>search</category>
      <category>machinelearning</category>
      <category>database</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Bun.js - Fresh JavaScript runtime out of the oven 🧑‍🍳</title>
      <dc:creator>Strift</dc:creator>
      <pubDate>Thu, 21 Jul 2022 11:24:14 +0000</pubDate>
      <link>https://dev.to/strift/bunjs-fresh-javascript-runtime-out-of-the-oven-536e</link>
      <guid>https://dev.to/strift/bunjs-fresh-javascript-runtime-out-of-the-oven-536e</guid>
      <description>&lt;p&gt;When JS devs got bored of rebuilding libraries, they started rebuilding the runtime. &lt;/p&gt;

&lt;h2&gt;
  
  
  An all-in-one JavaScript runtime
&lt;/h2&gt;

&lt;p&gt;A few weeks ago, Jared Sumner released Bun.js—an all-in-one runtime for JavaScript. Bun includes a native bundler, TypeScript transpiler, task runner, and npm client. &lt;/p&gt;

&lt;p&gt;And it is &lt;em&gt;fast&lt;/em&gt;. ⚡&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OrNXTS7U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ui5hy84ol3fxbewl5i0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OrNXTS7U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ui5hy84ol3fxbewl5i0u.png" alt="Bun benchmark" width="393" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since Bun is an all-in-one tool, performance is not limited to apps. Developer tooling also benefit from it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/jarredsumner/status/1499225725492076544"&gt;4.5x faster starts&lt;/a&gt; than node&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/jarredsumner/status/1454218996983623685"&gt;30x faster script runs&lt;/a&gt; than npm&lt;/li&gt;
&lt;li&gt;20x faster installs than yarn&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On top of all, Bun has full compatibility with all the NPM ecosystem. So there's little to no migration needed. ✅&lt;/p&gt;

&lt;h2&gt;
  
  
  Should we use Bun?
&lt;/h2&gt;

&lt;p&gt;By all means, try it out! Bun.js looks extremely promising.  Its sheer performance could be driving change across the entire JS ecosystem; the same way Vite changed the face of front-end dev in a couple months. &lt;/p&gt;

&lt;p&gt;Personally, I'd love to see more tools aim at running on the edge.&lt;/p&gt;

&lt;p&gt;But Bun still has to come to grips with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project scoping&lt;/strong&gt;—A monumental scope is not a bad thing per se, but it makes the challenge greater&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sustainable maintaining&lt;/strong&gt;—Building a team around the creator is vital to ensuring continuous development and support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Zig question&lt;/strong&gt;—Bun is built with the Zig language which is quite unproven in the industry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dig further by reading &lt;a href="https://bun.sh/"&gt;Bun.js documentation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Like the content? Follow for more JavaScript &amp;amp; front-end stuff!&lt;/p&gt;

&lt;p&gt;Cheers ✌&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>State of Vue 2022: Amsterdam recap</title>
      <dc:creator>Strift</dc:creator>
      <pubDate>Tue, 21 Jun 2022 08:22:45 +0000</pubDate>
      <link>https://dev.to/strift/state-of-vue-2022-amsterdam-recap-36jp</link>
      <guid>https://dev.to/strift/state-of-vue-2022-amsterdam-recap-36jp</guid>
      <description>&lt;p&gt;Since v3.0 became the default this February, Vue 3 adoption has grown steadily. NPM downloads have known a 4x increase to reach an average of 800k/week.&lt;/p&gt;

&lt;p&gt;Since then, the Vue 3 team has been at work on fixing issues with v3 and improving the SFC playground. Meanwhile, the ecosystem is finally catching up. Let's recap what Evan You discussed during the &lt;em&gt;State of the Vuenion&lt;/em&gt; talk in Amsterdam two weeks ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;State of the ecosystem

&lt;ul&gt;
&lt;li&gt;Nuxt 3&lt;/li&gt;
&lt;li&gt;Vuetify 3&lt;/li&gt;
&lt;li&gt;VitePress 1&lt;/li&gt;
&lt;li&gt;Volar&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;What's coming for Vue?

&lt;ul&gt;
&lt;li&gt;Back-porting features to Vue 2.7&lt;/li&gt;
&lt;li&gt;Next minor version: Vue 3.3&lt;/li&gt;
&lt;li&gt;A note on Vite 3&lt;/li&gt;
&lt;li&gt;Experimental: new compilation strategies&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Bonus: The Vue Report
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  State of the ecosystem
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Nuxt 3
&lt;/h3&gt;

&lt;p&gt;One of the most anticipated release is probably that of Nuxt 3. Currently in Release Candidate stage, the framework is nearing stability. It seems safe enough to start migrating your development environment. Since the conference, NuxtLabs released RC4—check out the &lt;a href="https://github.com/nuxt/framework/releases/tag/v3.0.0-rc.4"&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Nuxt team has announced that Nuxt v3 should release this summer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Related: A few weeks ago, the team released &lt;a href="https://content.nuxtjs.org/"&gt;v2 of @nuxt/content&lt;/a&gt;—it supports Nuxt 3!&lt;/p&gt;

&lt;h3&gt;
  
  
  Vuetify 3
&lt;/h3&gt;

&lt;p&gt;The Material Design framework is currently in beta. The third beta release has been available for a fortnight. Read the &lt;a href="https://github.com/vuetifyjs/vuetify/releases/tag/v3.0.0-beta.3"&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  VitePress 1
&lt;/h3&gt;

&lt;p&gt;The Vue team has long been dog-fooding VitePress with the new Vue.js docs. To prepare for the v1.0 release, core team member Kia worked on a providing a higher-level API for end users. VitePress is now the recommended solution for Vue 3-powered Static Site Generation. Read the &lt;a href="https://vitepress.vuejs.org/"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, &lt;a href="https://github.com/vuejs/vitepress/discussions/548"&gt;discussion remains&lt;/a&gt; on the name and the coexistence with VuePress. Simply put, the question is whether VitePress should replace VuePress 3 or not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Volar
&lt;/h3&gt;

&lt;p&gt;Johnson Chu, developer of the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Vue.volar"&gt;Volar VS Code extension&lt;/a&gt; joined the Vue.js core team. There are brighter days ahead for IDE tooling as the maintainer of the extension is now sponsored by Vue.&lt;/p&gt;

&lt;p&gt;This is a welcome news. With the integration of TypeScript, setup syntax, compile-time macros, and Nuxt 3 auto-imports, tooling is now paramount.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's coming for Vue?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Back-porting features to Vue 2.7
&lt;/h3&gt;

&lt;p&gt;Vue 2.7 aims at back-porting the built-in composition API, the &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; syntax, and the improvements to TypeScript support to Vue 2.x. As of writing, the composition API has been fully ported, and the team is working on porting &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Regarding the latter, the team aims at making vue/compiler-sfc adhere to the same interface as its Vue 3 counterpart. The goal is to make it compatible with &lt;code&gt;vue-loader&lt;/code&gt; 16+ and &lt;code&gt;@vitejs/plugin-vue&lt;/code&gt; so as to unify loaders across Vue 2 and Vue 3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vue 2.7 will be the last minor release of Vue 2.x.&lt;/strong&gt; It will have 18 months of LTS starting from the 2.7 stable release. Companies can notify interest for extended supported &lt;a href="https://link.vuejs.org/xlts"&gt;via this link&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next minor version: Vue 3.3
&lt;/h3&gt;

&lt;p&gt;In v3.3, we should expect a stabilized API for &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;. The Vue team is collaborating with the Nuxt team that is heavily testing the feature in Nuxt 3. Stability should also come for the &lt;a href="https://vuejs.org/guide/extras/reactivity-transform.html"&gt;reactivity transforms API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, the teams keeps on improving server-side rendering with lazy/conditional hydration and better warnings about SSR mismatch.&lt;/p&gt;

&lt;h3&gt;
  
  
  A note on Vite 3
&lt;/h3&gt;

&lt;p&gt;The next major of Vite is in development. Although the updates can be considered minor, many will introduce breaking changes. Still, those will be invisible for most end users. Only tools that use Vite directly will need to update, eg. Nuxt, Vitest, etc.&lt;/p&gt;

&lt;p&gt;The biggest internal update is &lt;a href="https://github.com/vitejs/vite/pull/8178"&gt;moving Vite itself to full ESM&lt;/a&gt; and thus dropping support for Node.js 12. The server-side rendering build will &lt;a href="https://github.com/vitejs/vite/pull/8348"&gt;now default to ESM output&lt;/a&gt;. With these changes, Vite aims to forward the ecosystem migration to ES modules. Also, Vite will now use esbuild for both dev and prod bundling, to reduce friction when deploying.&lt;/p&gt;

&lt;h3&gt;
  
  
  Experimental: new compilation strategies
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;⚠️ This is experimental and may never land.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The team has started experimenting with a new compilation strategy inspired by SolidJS. The idea is moving to a no-virtual DOM approach. This will significantly improve memory usage on top of reducing the runtime size.&lt;/p&gt;

&lt;p&gt;Although the adoption strategies aren’t clear — &lt;em&gt;that is, if these changes ever release&lt;/em&gt; — this would be a great step into transitioning Vue into a more &lt;em&gt;compiler-oriented&lt;/em&gt; framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: The Vue Report
&lt;/h2&gt;

&lt;p&gt;The fine folks at Monterail have produced an insightful report on the state of Vue.js. It's packed with community experts opinions and features experts articles and interview.&lt;/p&gt;

&lt;p&gt;Read it here: &lt;a href="https://www.monterail.com/vue-report-amsterdam-2022?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=Vue_development_vuejs_amsterdam_&amp;amp;utm_content=laurent_cazanove_"&gt;Vue Report&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A that’s a wrap!&lt;/p&gt;




&lt;p&gt;Follow me here or &lt;a href="https://twitter.com/StriftCodes"&gt;@StriftCodes&lt;/a&gt; on Twitter for more Vue content.  You can watch the original talk &lt;a href="https://www.youtube.com/watch?v=1ntuhMzAzU8"&gt;on YouTube&lt;/a&gt; and get the slides &lt;a href="https://docs.google.com/presentation/d/1tPaimqwJEXinPYifwUvA4gLCI6SezZsViuJvieWGAug/edit#slide=id.p"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

</description>
      <category>vue</category>
      <category>nuxt</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Displaying TwicPics Images When Working Offline With Nuxt.js</title>
      <dc:creator>Strift</dc:creator>
      <pubDate>Tue, 14 Jun 2022 11:28:01 +0000</pubDate>
      <link>https://dev.to/strift/displaying-twicpics-images-when-working-offline-with-nuxtjs-hd3</link>
      <guid>https://dev.to/strift/displaying-twicpics-images-when-working-offline-with-nuxtjs-hd3</guid>
      <description>&lt;p&gt;TwicPics is an image transformation and optimization SaaS. It works in the cloud, and front-end developers interact with the API via the JavaScript library. But when working in local, you might not want (or be able) to connect to the Internet. &lt;/p&gt;

&lt;p&gt;This happened to me, so I wrote a wrapper component around TwicPics that allows me to fallback to local images when necessary. Obviously, this means skipping any image optimization or  transformation. But it provides a quick toggle for switching it off and on, which can be useful when working locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a on/off switch for local images
&lt;/h2&gt;

&lt;p&gt;First, we’ll add a configuration entry to our Nuxt configuration to be able to easily toggle TwicPics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// nuxt.config.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;publicRuntimeConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;enableOptimization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we configure the app to default to local images when we’re in development mode. But we could choose any conditions we like or use a specific environment variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping our image in a component
&lt;/h2&gt;

&lt;p&gt;Now that we have a configuration toggle, let’s create an component that makes use of it. We’ll go with the straightforward approach: when &lt;code&gt;enableOptimization&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, we’ll simply display the image; otherwise, we’ll process it with TwicPics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- components/BaseImage.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; 
        &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$config.enableOptimization"&lt;/span&gt;
        &lt;span class="na"&gt;:src=&lt;/span&gt;&lt;span class="s"&gt;"src"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
        &lt;span class="na"&gt;v-else&lt;/span&gt;
        &lt;span class="na"&gt;:data-twic-src=&lt;/span&gt;&lt;span class="s"&gt;"`image:${src}`"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// In reality, you'd probably have more props to handle transformations, etc.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it! &lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;BaseImage&lt;/code&gt; component will load your local image whenever  &lt;code&gt;enableOptimization&lt;/code&gt; is false. You don’t have to change your code to keep using TwicPics in production.&lt;/p&gt;

&lt;p&gt;Obviously, that's a simplified example. In reality, you'd probably be wrapping a &lt;code&gt;&amp;lt;TwicImage/&amp;gt;&lt;/code&gt; component instead of base &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;. But the overall logic is the same. Read more about &lt;code&gt;@twicpics/components&lt;/code&gt; in &lt;a href="https://www.twicpics.com/docs/components/overview"&gt;the documentation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;To go further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nuxtjs.org/"&gt;Nuxt.js docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.twicpics.com/docs/getting-started/overview"&gt;TwicPics docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or just ask a questions in the comments!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m a web developer working with Nuxt.js &amp;amp; serverless. I’m writing about the stuff I learn. Follow &lt;a href="https://twitter.com/StriftCodes"&gt;@StriftCodes&lt;/a&gt; on Twitter for more.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

</description>
      <category>vue</category>
      <category>nuxt</category>
      <category>javascript</category>
      <category>image</category>
    </item>
    <item>
      <title>Testing Firebase Functions with the emulators suite</title>
      <dc:creator>Strift</dc:creator>
      <pubDate>Mon, 05 Jul 2021 09:44:58 +0000</pubDate>
      <link>https://dev.to/strift/testing-firebase-functions-with-the-emulators-suite-4dmi</link>
      <guid>https://dev.to/strift/testing-firebase-functions-with-the-emulators-suite-4dmi</guid>
      <description>&lt;p&gt;Integration tests can be hard to write, especially when using external services. We’ve all heard the “don’t test what you don’t own”. When running serverless, you pretty much own nothing. So how can you test your Firebase functions? Enters the Firebase emulators suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  The use case: a function that lists users
&lt;/h2&gt;

&lt;p&gt;Let’s take the example of a simple function. This one is a simple function that returns a list of users' UIDs. Internally, the function uses Firebase Auth to list the users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// api/listUsers.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../services/firebase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PAGE_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;allUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;listUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PAGE_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;allUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;allUsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;listUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PAGE_SIZE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;allUsers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firebase Auth module’s own listUsers function returns a paginated response. So we use the &lt;code&gt;pageToken&lt;/code&gt; to check if there are more pages and concatenate that in one single response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up tests with Jest
&lt;/h2&gt;

&lt;p&gt;We’ve got our function, now let’s set up our testing tools. For this example, I will use Jest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; jest &lt;span class="c"&gt;# Or `npm install --save-dev jest`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re running on VS Code, you will want Intellisense to pick-up Jest global imports. Including Jest types as a development dependency will do the trick.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; @types/jest &lt;span class="c"&gt;# or `npm install --save-dev @types/jest`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Writing the tests
&lt;/h2&gt;

&lt;p&gt;Now that we’re all set, let’s actually write tests, shall we? First, let’s scaffold our test file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test/api/listUsers.test.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase-admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FIREBASE_AUTH_EMULATOR_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost:9099&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase-functions-test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)()&lt;/span&gt;

&lt;span class="c1"&gt;// Mock config values here&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../index.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// import functions *after* initializing Firebase&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;listUsers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;wrapped&lt;/span&gt;

 &lt;span class="nx"&gt;beforeAll&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;wrapped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listUsers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;

 &lt;span class="nx"&gt;afterAll&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;

 &lt;span class="c1"&gt;// tests will go here&lt;/span&gt;

&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At line 3, we initialize &lt;code&gt;firebase-functions-test&lt;/code&gt; without parameters. Because of this, all calls to Firebase will be using the project default’s — most likely your production. We obviously don’t want this. That’s why we initialized it after the following line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FIREBASE_AUTH_EMULATOR_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost:9099&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When initialized, Firebase will recognize the environment variable and use the emulator for Auth instead of the production service. We can now safely write our test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returns an empty array when there are no users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wrapped&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, running the tests should fail because Firebase cannot connect to it’s Auth service. You should get an error like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error while making request: connect ECONNREFUSED 127.0.0.1:9099. Error code: ECONNREFUSED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you don’t get this error, make sure you’ve updated the environment variable and initialized &lt;code&gt;firebase-functions-test&lt;/code&gt; without configuration. Your app might be trying to connect to production. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, how do we get this working? Well, we use the Firebase emulators suite. Like the name suggests, it allows you to emulate Firebase services locally. It’s perfect for local development, but also for testing. Install it by running the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; firebase-tools &lt;span class="c"&gt;# or `npm install -save-dev firebase-tools`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use the emulator &lt;code&gt;emulators:exec&lt;/code&gt; command to launch the Auth service emulator and run our tests. For convenience, I included it in my &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt; 

&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"test:run"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest ./test/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you're&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Yarn&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"firebase emulators:exec --only auth 'yarn test:run'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you're&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;NPM&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"firebase emulators:exec --only auth 'npm run test:run'"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ta-da! Your tests should now run without any connection issues. This example only uses the Auth service. You can use the same technique to emulate other Firebase services. Just update the &lt;code&gt;--only&lt;/code&gt; parameter to include the other services you need.&lt;/p&gt;

&lt;p&gt;Until next time,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://laurentcazanove.com/articles/"&gt;On my blog&lt;/a&gt; where I write about code, esports, and writing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/lau_cazanove"&gt;On my Twitter&lt;/a&gt; where I casually post on similar topics&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>firebase</category>
      <category>serverless</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
