<?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: Tal Perry</title>
    <description>The latest articles on DEV Community by Tal Perry (@talolard).</description>
    <link>https://dev.to/talolard</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%2F502355%2F388a4448-5feb-4363-af83-28896e7abfa2.jpeg</url>
      <title>DEV Community: Tal Perry</title>
      <link>https://dev.to/talolard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/talolard"/>
    <language>en</language>
    <item>
      <title>Using Multiple WebWorkers With Create React App</title>
      <dc:creator>Tal Perry</dc:creator>
      <pubDate>Mon, 23 Nov 2020 18:46:39 +0000</pubDate>
      <link>https://dev.to/talolard/using-multiple-webworkers-with-create-react-app-246b</link>
      <guid>https://dev.to/talolard/using-multiple-webworkers-with-create-react-app-246b</guid>
      <description>&lt;p&gt;There are a few great articles about using &lt;strong&gt;one&lt;/strong&gt; WebWorker with Create React App. The gist of them is to use &lt;a href="https://github.com/webpack-contrib/worker-loader"&gt;worker-loader&lt;/a&gt; and something like &lt;a href="https://github.com/linonetwo/rescript-worker-loader"&gt;rescripts-worker-loader&lt;/a&gt;  to modify the Webpack config. Easy (after trying ten times). &lt;/p&gt;

&lt;h1&gt;
  
  
  Problem
&lt;/h1&gt;

&lt;p&gt;I tried and succeeded to run multiple WebWorkers with Create React App and that was harder. At first I got this lovely error message &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Conflict: Multiple assets emit to the same filename bundle.worker.js&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yuck!&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;Here's the solution, assuming you're using rescript, and an explanation follows. &lt;/p&gt;

&lt;p&gt;In your rescriptsrc.js add the following:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeMultipleWebworkersWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;// Change the output file format so that each worker gets a unique name&lt;/span&gt;
    &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;static/js/[name].bundle.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="c1"&gt;// Now, we add a rule for processing workers&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newRules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;

        &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;worker&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;c|m&lt;/span&gt;&lt;span class="se"&gt;)?[&lt;/span&gt;&lt;span class="sr"&gt;tj&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;s$/i&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;javascript/auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&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;rules&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;use&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="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;worker-loader&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="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;babel-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;presets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@babel/preset-env&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="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="c1"&gt;// Here we append all the old rules&lt;/span&gt;
    &lt;span class="p"&gt;},...&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&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;rules&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c1"&gt;// now update Webpack's config with the new rules&lt;/span&gt;
    &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&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;rules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newRules&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;
&lt;span class="p"&gt;}&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="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;makeMultipleWebworkersWork&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="cm"&gt;/*Your other stuff goes here */&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Explanation
&lt;/h1&gt;

&lt;p&gt;After a day of debugging, I realized that CRA's configuration of Webpack doesn't take filenames into account for output (at least in dev mode), so all the workers get emitted to to the same bundle.worker.js file, but they overwrite each other not append.&lt;/p&gt;

&lt;p&gt;The code above configures worker-loader and makes sure each worker goes to a different file, as desired. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why
&lt;/h1&gt;

&lt;p&gt;I'm building an open source in browser NLP thing. As you might guess, it trains NLP models in the browser interactively. &lt;br&gt;
Using multiple workers is a great why to crunch a lot of data without blocking the users main thread, e.g. keeping the app responsive and engaging. &lt;/p&gt;

&lt;p&gt;Still a bit early to release it, but follow me here and on &lt;a href="https://twitter.com/thetalperry"&gt;twitter&lt;/a&gt;  if you'd like to keep updated. &lt;/p&gt;

</description>
      <category>react</category>
      <category>webpack</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My in-browser search with IndexDB and WebWorkers</title>
      <dc:creator>Tal Perry</dc:creator>
      <pubDate>Fri, 30 Oct 2020 11:44:53 +0000</pubDate>
      <link>https://dev.to/talolard/want-to-learn-about-webworkers-and-indexeddb-2pph</link>
      <guid>https://dev.to/talolard/want-to-learn-about-webworkers-and-indexeddb-2pph</guid>
      <description>&lt;p&gt;Hi,&lt;br&gt;
I'm new to Dev, thanks for checking out my first post. &lt;br&gt;
I'm a data scientist doing data products for actual humans. I want my users to get to wow fast, and I want to develop fast. &lt;/p&gt;

&lt;p&gt;You know what gets in my way ? Servers. Writing a server, integrating with a server, authenticating a user on a server and persisting data on a server all stand between me and my goal. &lt;/p&gt;

&lt;p&gt;Recently I wanted to let my user upload a csv with a text, give them full text search over that, make some annotations on the text and have the result saved for later. &lt;/p&gt;

&lt;p&gt;Back in the day I would have set up a python server, a postgres database, connected them and then tried to get my webapp to talk to the python.&lt;/p&gt;

&lt;p&gt;That's annoying because it's a lot of setup for me, and some setup and waiting for my users. It's 2020 no-one has any patience. Let's see how we can get the time to wow down to something a millennial or genexer like me can stomach:&lt;/p&gt;

&lt;p&gt;So here's what I did. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moved the heavy computation (building the index and search) in a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers"&gt;WebWorker&lt;/a&gt; .
&lt;/li&gt;
&lt;li&gt;Wrapped the worker in a class that gives the main thread a promise when it searches. &lt;/li&gt;
&lt;li&gt;Used &lt;a href="https://github.com/tannerlinsley/react-query"&gt;react-query&lt;/a&gt; to delegate away the request/response state management instead of having a mountain of Redux code. &lt;/li&gt;
&lt;li&gt;Used the &lt;a href="https://dexie.org/"&gt;Dexie library&lt;/a&gt; to store the users data in Indexedb so thay can come back and pick up with they left off. &lt;/li&gt;
&lt;li&gt;And I used &lt;a href="https://github.com/ndx-search/ndx"&gt;ndx&lt;/a&gt; which is a really nice in JS full text search implementation. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The end result looks like this, granted the design is rough but a satisfying POC of an inbrowser search engine &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MrEJPXmR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3tjo1y825vga49w8uq2h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MrEJPXmR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3tjo1y825vga49w8uq2h.gif" alt="In browser search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is all going open source soon and I have a lot to share about each of these steps, but I'm not sure if this is interesting and exciting or kind of meh. Let me know what you think and I'll be glad to share more!&lt;br&gt;
Tal&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
