<?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: Yeom suyun</title>
    <description>The latest articles on DEV Community by Yeom suyun (@artxe2).</description>
    <link>https://dev.to/artxe2</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%2F1096626%2F93c589ef-99c5-4df8-96ba-ffca79f9e0f1.jpeg</url>
      <title>DEV Community: Yeom suyun</title>
      <link>https://dev.to/artxe2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/artxe2"/>
    <language>en</language>
    <item>
      <title>Implementing Drag-and-Drop using Svelte 5</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sat, 25 Nov 2023 18:18:51 +0000</pubDate>
      <link>https://dev.to/artxe2/implementing-drag-and-drop-using-svelte-5-767</link>
      <guid>https://dev.to/artxe2/implementing-drag-and-drop-using-svelte-5-767</guid>
      <description>&lt;p&gt;It's been two weeks since Svelte 5 was published on npm as the next version.&lt;br&gt;
During that time, I had the chance to try out Svelte 5 in my free time, and working with runes was quite a fun task.&lt;br&gt;
In this post, I'll introduce drag-and-drop functionality using Svelte 5.&lt;br&gt;
For projects using the CLI, as Dev.to's embed feature doesn't seem to fully support StackBlitz, I'll provide a REPL link instead.&lt;br&gt;
&lt;a href="https://svelte-5-preview.vercel.app/#H4sIAAAAAAAACs0aDW_bxvWvnNWgkBJRltN1A2hLXpukS7d0KAoDaycJCi2ebLYUyZGUbU3Rf997775PpKw4CDIksMi79969e9_vjtvOMkl51Qkn204WrXgn7HxXFJ1-p94U-FLd8bTm8F7l63KBIxfVokyKmi3yrOYP9WjaWeXxOuXTzniawWAFUyWPaj6v8zifpwkMjFi3x0Zjtp1m0zrlNUtqvqqewfizqgbQLo5P6634mdZxnvGQTdi0cxVVf7B_Tzts1leTSBYm1Sv8E1DfTTv9vcHvmwZfNQ2-bhp80zT4Q9Pg35oG3zYN_tg0-PemwX80Db6bdtTYTDzs8KeHf4T4b3lyc1tXIF0pUCHO0-fP2V9RrWybrVfXvJzMduz5aXcy68HUqVxJSPcRWATdaV1W87iMbm6S7MbS6DJKK05MtdBS6HUZZdUyL1cWMizjYU47uAmwgw9gFMjjtGMTQQbmCGnblETpaUazmD9YAEM9A-9lPW-cV2yUvF6XWcW2d3kSq6WFvHkWkwRcM5_WyZJ1beH0mDZwnHIWPRlJ9iwgRR-dBWgLn5mYrc4GVZEmC-5Q6rOz3mQ4MzTa0RTCsE-0ewpnZ5kV4LvqJb1q_YNo8IeBgIqojFZKxTuxG2-uUYnIk4JzhSxGHUHXvNSiphX6hO9LnWwGRGo23WOr_I7PcZ8OosDhsCdG6sIpxLRF2hM2mtRJnlE8E2C9LyQFvZEDQvhUw5EoCO2ai28tnue4DzL62L6p9gmBxvb7ibMuRi42GAzk2-4LCVrs7RFza95GgxiaJHVQQJ7j1eXa8btmETgb8MxWreo7i97BhKZnXpySLI89n7DCFCCzLkVYbQLn8DyWL_AcBA6CLbZJMgOsoZnc6TjEyC8fX-jCLPTixVMW0qWFo0w0QWtEZVuPq0YDsCR3tOAcA3nBzj52Z4HM-7ajT2yiMxawsycI2mEsEIx9jG4f5-tFC19uItpzHZoQTqw4kGvJYuYGdvBML9u1-JRYhiW5lI1oOWADqu2eTcgYu5rQKKY1IFgSaUCz5dWArEXegGrU4SKqskW_quTatwMWDkhZw3_-UORlDdF5r8SHyYtT0RqMsWy60M_JinBeA6EfMSEty3wFAXlwqkYGosnAutaD_TmNFvxtnsa83EezJpspvIIOJUoyH1cPW1iqc7FbFn-LXSoHqVzkQi5znvIVyA2ArVK1u0gTGPw1ZCIy95kY-M0MIHLI3l799O6NoEAZJco2VGTL8rMnS21XrHFyB8awSTk0XnECqTnahMsUHfH3dQVRZxNQY5bV4YI0ek592bS-cCVyDaYUwj5wVPIw2vr70o6YZzgMBjPaanEMlP3sxgLsAGv4N7gvoyLEP4qlY5DipOQLzGDhIk_Xq-yc3QCVs2HxYBEBMlURZZrOErYZVMl_efiSr4AQvt5TYAivwV5w_aucxTlIFtBsMjY3IpSEg2-BBmBcnMKkBbv9ikeLW5kltFCE309UvTHrg9lh98qiit1B5bSzFtMeQW492tqTtIIm60-0KkoGYLDDkWKBndpMnyLTO3sXkKhs9k1UY19_bc_oUInlsa6nGrZjO63LibUhj6tkqSm5cnY0UkRxDIyFL1Eneyr5Uqb0GorMz2lJooj9opYk6-jPY0mC-JGWJDn5aEsyzxduEhhjgMW5Th8PspJlwuNOiMX2rq-PxBRDR5yLAT3qUpjOB1t6YSxelxGa36XKA3KcdOaN-WoJ2ZOzCvY2kqoWWsh-odrgChi8QC7zJROJswtZcnB6BYDvAO7NQ7QqUq4TZW_gJ8WxIg1EQtbQcdH8boc_pyrLUoWixAHJ80_DIdUcosXCJ3__NKgXFW_UKO3wuKYo86IS6dlK_9F1yt3MjyMNSd-2VKAG1pbc8bjrLOnYM864Jm2VZ2w0skrUNstHILGDnq49VJ12HBOtTmVIo-FftrNp96AeoOZlUPJ4Dc1_twCDI3tasEtWQBuwYCGDwaE-NgobCcieUgCF2H6RnrSPyCb2p3xd8Td3GIEYxx8x63folhHdRlmc8jl4weIPkBgh6c42SjnaMi1qlWaWb1ClRUgDEAoU0VRtXQ7wTPuVqKAQvUdlr7OiKIWgtHLP--zCSFXS3lFTEyVSiaZkiJjq2yPiloPa0GMO6W60_WY4lPFP1GxEZrT1F5QwjxaAImJiLqOCMV8uAeQtpTO7FFQdHp0XSY3rMKyy4HVeglUHZRQn60okQ3afxPVt-Gd8zNd1CgE5HJxBHqvyNInPGSojiNLkJlPVLPMS8mJdVnkZFnkiprXdhfSUQrD6rbvVo7vioXeuGNt-tGORDnD-vTlaCZ9tVSjbrar3O0Peoznt5EW0SOpNOHhpbfel2i77KooiSISGwMleNWALWNBUhU4msui5uR3IM_INrXx62yvpQWqOedCIKum3BxnYiXSqEyuVPGmOV0LUNXZ0ASTUTBo_rFJhFVKpeNAJL3kKz18Nh0PTNxzmi70AuZycyJpCMXihU8BRqd6qPT4p6x-Zcz97yjWMiEjC_Mz55Bgnz0EbNTJIeXZT36q7JZmVRCh0A9lJEDCx5wBsIy85i87ONkGWB9gNJ4tAhqSAHD2iQr5iQTD2emJII2VQAfCiJp9ojzFxVN3yo4KM9tu_fNsQc5THHeFRaFzslpf85NiqU9epn2SEizSqqgoKz6ouqX4RBakJ_ZdO3Xh5LiF03w_zIlmGVFpRovarSwGMTnsMtJt6jq5vTUHcWudqy8ejGjJbsX02og6KbNHaOgxn6zSlYb1f6w03pGpSi2O_9HRn0W0E__MHtZP5xt2CcSuXGxtmqs_yF8oQ5tjF4vGUPsaC4uX7fJ1ha_yKVvoFIMip6wcElHxgzeYQAedc0gobA7XZh6rzQrIh14uKAkTUtbimtdwyWlxX7HzByNqvpSATOtMrydcHcWxPzxvxbJG4zvOUR5lBdwr1vctnA1fy_6x5BeVw3MbSpQEGFy6BJ_FiMST5kRRkMbtljxkzGKmsWPcK2hVWwmh0aEOakqbAdsZuvAvmnnv7B2GqFBYFBjKXG-iq_N-8Y3nNH-eLNb4OpBlWP0Ab9TPGu67PT09_ECC_QRBsqcWxlhIrY7MvR70LJgng3CLIsQGWN1G9uKUY0s34vYkoXVFmgPLvME_619eaBtPrehNHEKfYbYhL0gvjVr_KEeNCv8lcp8rPbs9ODxQeB41r4ZRZSlknhPY8Tef3SX0r0u1roDnI8vtuT11A-21Fna8Xt-Chbu62zWtddEUOtq32CtHsFmzfNomytE234fKNV7VWxEo1Gc4a2h_Jistmm03bMRKMykSjktZ7dZuk-yGpzb6ONQCIfJZhGXvChOFYxH4-kcs7MVF_O2FlmhZjgBm1tNCwqyvPZSVnlaUxy-cxGisAJWYBJKoza17WawjhXAEO6TJSwruXkShhZ_uG2iSZNVxH6Um89rM_YbKv8zQUfpGwc45I0Klcm_mUDOmx32RvA6otB_b5zHvj3s-2C0ytLekVGs4-AxDMq825FVvS9216VjmrTlbcUm5bcEBNIqTtTCbN9ZgQrhCzGgUc-fJdlqyoj_0B1uZdIeC9-IML9HrH8_oYjw4ndAtMKbayFajt8fzcsTuEAnvT6eo6jzeWxV1D5_SH46cCaSB4-hc2BmwMaw1E6KYBLzlp6HegTSdFWdSbrtAdRNjMmZk6THcfdWhPOsu2X5aLJUA1sC_ftnEFIOvP-65I9c1Retg8RQ8btUtxngSK2ChFiBFPExr-Ki8-RhE23r4eWqnuIT5RC5t2LZBw_XlfC8KLqCmQcc3u2x4LbScaUa9rgoBF_0ERB6M4QFIAbxTw5iCwCq0mGuJnIw_WKyRyA1CSFVxoCPHugEC4RBIb8-ZMX-d1na-QxMYeOLxzKKVgJ6aqonMOClA0FVC0atnOhb0bvYx23-83utz2MQMX87mIiafsm6H-4ndoFdXSql0WSuk2tryOZULgBh7uo2zsywGVcGFpRDOwaWDAUPUoBA4Fi43HZCBVPm7R-NFMSDqBT6eFFTISt8JvLdjBipoOvMQxTnifZHF-r4pCXT_rEyQ9snNg1oULsS70vC7SNYQecWHoew6vZ5DXqZk5869vk2q01SlAtUB4pALDdLKibhPUNX0uT8ZLDuJJ7rj-BgVPh8cgBvw59gQMT2w_x-EX3pf4V7HWncn_yRmWdWHacIqFe7COqojxI86q9s47Xid3h05hjoCmfd0l_N6B3j_xBsauwKHydT1mH9jQOmARo35R-elHKeBd2XFHKSTOnuIEP3zUzHbNdVxfmE5_jxxFAQpR1t1dA9DRbbBkxBzrpDwqFUNqUp42aJ6HppV4SnOvriPbu3uU5zHd_cedQjiXwaqTUCeXhyY3jqO4n2zvn8D6PWP7V3z7ht7taiMfLPC4AYo22Dr78MH4Sg8K2Dzj_8xj3sVYZk7H7JVkQ6niJLl0dF3l6Vp-mNAEXVMRanpacReLpSled-FHTC2IqWgifEzqLWxUN2Y8fnztxZ2WgwyaE0cZh1MgO5zZPnPOIlqBuFYS90Z7F0niHmmZ1OoLS-vmR3uGyzuOuDnXvY83Q7v2BLm_MW2Hu73v3YhTO90yTKX6Rvbx5Dvb_Q-psrT8EzgAAA=="&gt;Svelte 5 preview&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Synergy between Runes and Module Context
&lt;/h2&gt;

&lt;p&gt;The new feature in Svelte 5, Rune, is a kind of macro that allows you to write reactive programs outside Svelte files in js files, just like in Svelte files.&lt;br&gt;
This is particularly convenient when leveraging Svelte's module context, which is compiled in the following way.&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="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;context=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// scripts in module&lt;/span&gt;
&lt;span class="c1"&gt;// scripts in module&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// scripts in default&lt;/span&gt;
&lt;span class="c1"&gt;// scripts in default&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// scripts in module&lt;/span&gt;
&lt;span class="c1"&gt;// scripts in module&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// scripts in default&lt;/span&gt;
  &lt;span class="c1"&gt;// scripts in default&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The module context is a great space for writing reactive instance creation functions using runes.&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="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;context=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;count$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;$count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;count$&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;count$&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_counter&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;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;{counter.increment}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  clicks: {counter.$count}
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Considerations for mouse move and mouse up events
&lt;/h2&gt;

&lt;p&gt;To implement drag and drop, I used mousedown, mousemove, and mouseup events.&lt;br&gt;
I chose this approach instead of using &lt;code&gt;draggable="true"&lt;/code&gt; because I wanted to display an HTML element instead of a dragImage.&lt;br&gt;
One thing to note here is that the mousemove and mouseup events need to be connected to the window.&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="nt"&gt;&amp;lt;svelte:window&lt;/span&gt;
    &lt;span class="na"&gt;onmousemove=&lt;/span&gt;&lt;span class="s"&gt;{handle_mousemove}&lt;/span&gt;
    &lt;span class="na"&gt;onmouseup=&lt;/span&gt;&lt;span class="s"&gt;{handle_mouseup}&lt;/span&gt;
    &lt;span class="na"&gt;ontouchmove=&lt;/span&gt;&lt;span class="s"&gt;{handle_touchmove}&lt;/span&gt;
    &lt;span class="na"&gt;ontouchend=&lt;/span&gt;&lt;span class="s"&gt;{handle_touchend}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  DragContainer and Draggable
&lt;/h2&gt;

&lt;p&gt;When dragging begins, the draggable passes the drag target to the drag container.&lt;br&gt;
Since there is only one drag target, a drag container with drag-related logic can control multiple draggables, even with just one instance.&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="nt"&gt;&amp;lt;DragContainer&lt;/span&gt; &lt;span class="na"&gt;bind:setDragElement=&lt;/span&gt;&lt;span class="s"&gt;{set_drag_element}&lt;/span&gt;
    &lt;span class="na"&gt;ondragend=&lt;/span&gt;&lt;span class="s"&gt;{todo_list.end_drag}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;DragItem&lt;/span&gt; &lt;span class="na"&gt;index=&lt;/span&gt;&lt;span class="s"&gt;{i}&lt;/span&gt;
      &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="na"&gt;todo_list&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
      &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="na"&gt;set_drag_element&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"todo"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;While Svelte 5 hasn't been officially released yet, the current preview version is already quite intriguing.&lt;br&gt;
What's astonishing is how convenient and rational the syntax of runes becomes the more you use it.&lt;br&gt;
Declarative frontend frameworks, originating from React, seem to already have a familiar feel to the implicit magic executed by runes, given their nature of meta-programming.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Managing the types folder with a simple script</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sun, 19 Nov 2023 10:57:10 +0000</pubDate>
      <link>https://dev.to/artxe2/managing-the-types-folder-with-a-simple-script-180k</link>
      <guid>https://dev.to/artxe2/managing-the-types-folder-with-a-simple-script-180k</guid>
      <description>&lt;p&gt;A few weeks ago, I wrote an article on setting up a project for an npm package using JSDoc.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/artxe2" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nlVVhPaX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--lb22Ecr_--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/1096626/93c589ef-99c5-4df8-96ba-ffca79f9e0f1.jpeg" alt="artxe2"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/artxe2/how-to-set-up-jsdoc-for-npm-packages-1jm1" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to configure JSDoc instead of TypeScript&lt;/h2&gt;
      &lt;h3&gt;Yeom suyun ・ Sep 2&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#typescript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
When using JSDoc, it generates d.ts files using &lt;code&gt;tsc&lt;/code&gt;.&lt;br&gt;
However, if there are deleted js files during this process, the corresponding d.ts files are not automatically removed.&lt;br&gt;
If I delete the types folder before running &lt;code&gt;tsc&lt;/code&gt;, this issue can be resolved.&lt;br&gt;
However, when working with VSCode, it can be quite annoying that unchanged files are marked as modified in the Git tab.&lt;br&gt;
To address this problem, I've written a simple script.&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;readdirSync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;rmdirSync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;statSync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;unlinkSync&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:child_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fileURLToPath&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:path&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;dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileURLToPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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;pacakge_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/packages/&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;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;current_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`cd &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pacakge_path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; tsc`&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="cm"&gt;/**
     * @param {string} dir_path
     * @returns {void}
     */&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;clean_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir_path&lt;/span&gt;&lt;span class="p"&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;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir_path&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;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
      &lt;span class="k"&gt;for&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;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&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;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&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;stat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;statSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file_path&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;stat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isDirectory&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="nx"&gt;clean_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&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;modified_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;getTime&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;modified_time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;current_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;unlinkSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;rmdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;clean_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pacakge_path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/types&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The principle is simple.&lt;br&gt;
Record the current time in JavaScript, run &lt;code&gt;tsc&lt;/code&gt;, and then delete the unchanged files.&lt;br&gt;
If you're curious about the entire project, check out the StackBlitz link below.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/github-p9xwsc?file=scripts%2Ftsc_with_clean.js"&gt;https://stackblitz.com/edit/github-p9xwsc?file=scripts%2Ftsc_with_clean.js&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Is JavaScript's freedom a strength or a weakness?</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sun, 12 Nov 2023 11:30:41 +0000</pubDate>
      <link>https://dev.to/artxe2/is-javascripts-freedom-a-strength-or-a-weakness-1358</link>
      <guid>https://dev.to/artxe2/is-javascripts-freedom-a-strength-or-a-weakness-1358</guid>
      <description>&lt;p&gt;JavaScript is a very interesting programming language.&lt;br&gt;
It is easy and quick to code, runs immediately in runtimes like the web or Node.js, and is quite fast despite being a dynamic type language.&lt;br&gt;
However, the freedom of JavaScript seems to be somewhat controversial.&lt;br&gt;
For example, many developers believe that strict comparison is essential when comparing values.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implicit Casting in JavaScript
&lt;/h2&gt;

&lt;p&gt;I like to use implicit casting when writing JavaScript. All values in JavaScript can be implicitly cast to boolean.&lt;/p&gt;
&lt;h3&gt;
  
  
  True
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;// non-zero number&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// non-empty string&lt;/span&gt;
&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kd"&gt;function&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="c1"&gt;// non-null object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  False
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// zero&lt;/span&gt;
&lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="c1"&gt;// empty string&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="c1"&gt;// null object&lt;/span&gt;
&lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Loose Comparison in JavaScript
&lt;/h2&gt;

&lt;p&gt;Loose comparison in JavaScript casts the compared values to the number type if they are of different types. Object types are compared by their address values, but the equality comparison of null and undefined is exceptionally treated as true.&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="mi"&gt;123&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;00123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// 123 &amp;gt;= 123&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// 2 == 1&lt;/span&gt;
&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// *{} == *{}&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="c1"&gt;// *null &amp;gt;= undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;JavaScript is a very liberal language, and the features of JavaScript such as implicit casting may seem confusing at first, but I personally think this is one of the advantages of JavaScript.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Introduction to eslint-plugin-lube</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sat, 04 Nov 2023 03:57:56 +0000</pubDate>
      <link>https://dev.to/artxe2/introduction-to-eslint-plugin-lube-9dh</link>
      <guid>https://dev.to/artxe2/introduction-to-eslint-plugin-lube-9dh</guid>
      <description>&lt;p&gt;ESLint is quite a useful tool for code linting.&lt;br&gt;
When used with vsce, it notifies you of coding convention violations in real time and even supports auto-fix features.&lt;br&gt;
However, if you look at the GitHub star history, ESLint's indicators are relatively low compared to Prettier.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PPalp4tI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xde1guvs73uknygtbi1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PPalp4tI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xde1guvs73uknygtbi1h.png" alt="Star history" width="800" height="510"&gt;&lt;/a&gt;&lt;br&gt;
That may be because ESLint's fix features are not as good as Prettier's formatting features, which enforce coding styles.&lt;br&gt;
For example, ESLint's &lt;code&gt;max-len&lt;/code&gt; rule will warn you if a line is too long, but it does not provide an auto-fix feature to automatically insert line breaks, unlike Prettier.&lt;br&gt;
To be honest, I don't know if there are any other examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prettier's strictness is inconvenient
&lt;/h2&gt;

&lt;p&gt;Many people use ESLint and Prettier together.&lt;br&gt;
This is a good choice because the two libraries have their own roles for linters and formatters.&lt;br&gt;
However, Prettier has one drawback.&lt;br&gt;
In order to pass the check option after modifying a file, you must always run Prettier with the write option.&lt;br&gt;
No matter how fast Prettier's performance is, this restriction is quite inconvenient for me.&lt;br&gt;
Since ESLint already provides auto-fix features for most coding styles, I decided not to use Prettier and support the missing features through eslint-plugins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional rules provided by the plugin
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/eslint-plugin-lube?activeTab=readme"&gt;eslint-plugin-lube&lt;/a&gt; provides the following four rules that support auto-fix features.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;Docs&lt;/th&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;pretty-imports&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-imports.md"&gt;docs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/rules/pretty-imports.js"&gt;code&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/test/pretty-imports"&gt;test&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pretty-jsdoc-casting&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-jsdoc-casting.md"&gt;docs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/rules/pretty-jsdoc-casting.js"&gt;code&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/test/pretty-jsdoc-casting"&gt;test&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pretty-sequence&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-sequence.md"&gt;docs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/rules/pretty-sequence.js"&gt;code&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/test/pretty-sequence"&gt;test&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;svelte-naming-convention&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/svelte-naming-convention.md"&gt;docs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/rules/svelte-naming-convention.js"&gt;code&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/test/svelte-naming-convention"&gt;test&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-imports.md"&gt;pretty-imports&lt;/a&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ggg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hhh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iii&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jjj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kkk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lll&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;module/2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aaaaa_bbbbb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;aaaaa_ccccc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;aaaaa_ddddd&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-jsdoc-casting.md"&gt;pretty-jsdoc-casting&lt;/a&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="cm"&gt;/** @type {A} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/** @type {B} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/** @type {C} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="cm"&gt;/**/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="cm"&gt;/**/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="cm"&gt;/**/&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="cm"&gt;/** @type {A} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="cm"&gt;/**/&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cm"&gt;/** @type {A} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="cm"&gt;/**/&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-sequence.md"&gt;pretty-sequence&lt;/a&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;aaaaaaaaaa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;bbbbbbbbbb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;cccccccccc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;dddddddddd&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aaaaaaaaaa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;bbbbbbbbbb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;cccccccccc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;dddddddddd&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;aaaaaaaaaa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;bbbbbbbbbb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;cccccccccc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;dddddddddd&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;aaaaaaaaaa_bbbbbbbbbb_cccccccccc&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;aaaaaaaaaa_bbbbbbbbbb_cccccccccc&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;aaaaaaaaaa_bbbbbbbbbb_cccccccccc&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;aaaaaaaaaa_bbbbbbbbbb_cccccccccc&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;b&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="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;aaaaaaaaaa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;bbbbbbbbbb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nx"&gt;aaaaaaaaaa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;bbbbbbbbbbb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;ccccccccccc&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;aaaaaaaaaa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;bbbbbbbbbbb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;ccccccccccc&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/eslint-plugin-lube/docs/svelte-naming-convention.md"&gt;svelte-naming-convention&lt;/a&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;snake_case&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;snake1_2_3case_4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;SNAKE_CASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;SNAKE1_2_3CASE_4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;PascalCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;P1ascal2Case345&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;__snake_case$$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$$snake_case$$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/eslint-plugin-lube?activeTab=readme"&gt;eslint-plugin-lube&lt;/a&gt; is still in version &lt;code&gt;0.4.2&lt;/code&gt;, and the minor version is incremented by 1 whenever a new rule is added.&lt;br&gt;
All rules support auto-fix features, and they are created on the premise of not using Prettier.&lt;br&gt;
If you find Prettier inconvenient, try this plugin.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>eslint</category>
    </item>
    <item>
      <title>Performance of Runtime CSS Generation using MutationObserver</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sat, 28 Oct 2023 14:18:09 +0000</pubDate>
      <link>https://dev.to/artxe2/performance-of-runtime-css-generation-using-mutationobserver-3ndi</link>
      <guid>https://dev.to/artxe2/performance-of-runtime-css-generation-using-mutationobserver-3ndi</guid>
      <description>&lt;p&gt;Recently, I found an interesting tweet on Twitter.&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1714081079840154017-875" src="https://platform.twitter.com/embed/Tweet.html?id=1714081079840154017"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1714081079840154017-875');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1714081079840154017&amp;amp;theme=dark"
  }



&lt;br&gt;
The contents of the commit attached to the above tweet were as follows.&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;// before&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cssFunctions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;min&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;max&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clamp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isCSSFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cssFunctions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`^&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// after&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cssFunctions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;min&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;max&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clamp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calc&lt;/span&gt;&lt;span class="dl"&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;IS_CSS_FN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`^(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cssFunctions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;)\\(.*\\)`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isCSSFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;IS_CSS_FN&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;value&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;I think most people will be able to tell immediately what was changed when they see the original code.&lt;br&gt;
The original code was very inefficiently written.&lt;br&gt;
I would have changed it in the following way, but regardless, the &lt;a href="https://github.com/tailwindlabs/tailwindcss/pull/12215#issuecomment-1765454107"&gt;performance of isCSSFunction has been greatly improved&lt;/a&gt; through the commit.&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;let&lt;/span&gt; &lt;span class="nx"&gt;IS_CSS_FN&lt;/span&gt; &lt;span class="o"&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;calc|clamp|max|min&lt;/span&gt;&lt;span class="se"&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;/&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isCSSFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;IS_CSS_FN&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;value&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;h2&gt;
  
  
  Tailwind is still slow
&lt;/h2&gt;

&lt;p&gt;I once attached a benchmark result using a site called &lt;a href="https://pagespeed.web.dev/"&gt;PageSpeed Insights&lt;/a&gt; while writing an article about the CSS Library I created.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/artxe2" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nlVVhPaX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--lb22Ecr_--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/1096626/93c589ef-99c5-4df8-96ba-ffca79f9e0f1.jpeg" alt="artxe2"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/artxe2/css-lube-highly-optimized-css-interpreter-2nl5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;CSS Lube: Highly-optimized CSS Interpreter&lt;/h2&gt;
      &lt;h3&gt;Yeom suyun ・ Aug 22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#opensource&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;However, this site runs on a local PC, so there is a large deviation every time and the reliability is low.&lt;br&gt;
I found a site called &lt;a href="https://www.webpagetest.org/"&gt;WebPageTest&lt;/a&gt; that can get more reliable measurement results.And the following are the numbers measured using this site.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9B0-LGup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wux8teuenw19j3zcbh06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9B0-LGup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wux8teuenw19j3zcbh06.png" alt="Benchmark" width="800" height="268"&gt;&lt;/a&gt;&lt;br&gt;
Here's something to keep in mind.&lt;br&gt;
Tailwind is ultimately used in production as a built-in result, so the performance expectation is the same as Atomic CSS, regardless of whether or not jit mode is used.&lt;br&gt;
The Tailwind CDN used in the test is a feature that allows you to try Tailwind using &lt;code&gt;MutationObserver&lt;/code&gt; without going through the build stage, and is not suitable for production use.&lt;br&gt;
Recently, I saw an argument in an article titled &lt;a href="https://nuejs.org/blog/tailwind-vs-semantic-css/"&gt;Tailwind vs Semantic CSS&lt;/a&gt; that Tailwind is slow and requires much more markup to compensate for the lack of selector functionality.&lt;br&gt;
This is not true.&lt;br&gt;
So why is tailwind-jit included in the benchmark?&lt;br&gt;
It's because CSS Lube is implemented using the &lt;code&gt;MutationObserver&lt;/code&gt; feature, just like Tailwind's Play CDN feature.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why is CSS Lube fast?
&lt;/h2&gt;

&lt;p&gt;That's the topic of this article.&lt;br&gt;
CSS Lube has a total blocking time of over 2 seconds, which is a bit long, but it is still scoring a speed index score that is almost the same as inline style.&lt;br&gt;
And as you can see from the test page, the test page has 11,186 elements, and the blocking time includes the time it takes to parse the remaining invisible elements outside the first screen after quickly loading the first screen.&lt;br&gt;
This performance was actually possible thanks to the extremely simple logic.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using RegExp instead of querySelectors
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;MutationObserver&lt;/code&gt; is basically used by creating two.&lt;br&gt;
One detects changes in className, and the other detects new nodes being added.&lt;br&gt;
It is enough to simply iterate through the classList and check if it is a new className and execute &lt;code&gt;compile_style&lt;/code&gt;, but it is a bit different in the case of a new node being added.&lt;br&gt;
When CSS Lube detects childList, it first selects the top nodes that do not overlap, and then executes a regular expression on the outerHTML to get the className.&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="cm"&gt;/** @type {Set&amp;lt;Element&amp;gt;} */&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * @param {Element} target
   * @returns {void}
   */&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;collect_unique_top_nodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodeType&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;for&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;e&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;)&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&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;get_class_name_regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/class="&lt;/span&gt;&lt;span class="se"&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;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;"/g&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;get_cname_regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * @param {Element} target
   * @returns {void}
   */&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;detect_childs_with_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&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;class_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;for&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;substr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerHTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;get_class_name_regex&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;class_name&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;substr&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;class_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;get_cname_regex&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;get_cname_handler&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;One interesting thing here is that it was much faster to execute &lt;code&gt;get_cname_regex&lt;/code&gt; once after connecting the classNames than to execute &lt;code&gt;get_cname_regex&lt;/code&gt; for each className.&lt;/p&gt;

&lt;h3&gt;
  
  
  Previous version problems
&lt;/h3&gt;

&lt;p&gt;Before version 2, CSS Lube used the &lt;code&gt;readystatechange&lt;/code&gt; event or the defer attribute on the script tag to use &lt;code&gt;MutationObserver&lt;/code&gt; on &lt;code&gt;document.body&lt;/code&gt;.&lt;br&gt;
However, I saw that the &lt;a href="https://css.master.co/"&gt;Master CSS&lt;/a&gt; library had a speed index of 2 seconds, which was faster than CSS Lube.&lt;br&gt;
Even though the total blocking time was over 6 to 8 seconds, which was quite bad.&lt;br&gt;
After analyzing the cause, I was able to speed up the speed index from the late 2 seconds to the early 1 second by simply using &lt;code&gt;document.documentElement&lt;/code&gt; instead of &lt;code&gt;document.body&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple compilation logic
&lt;/h3&gt;

&lt;p&gt;Ultimately, the most important factor for fast performance is simple logic and a simple syntax that makes it possible.&lt;br&gt;
This is also mentioned in my first article attached above.&lt;br&gt;
Basically, CSS Lube can be written the same way as inline styles, and &lt;code&gt;_&lt;/code&gt; is replaced with a space to support spaces.&lt;br&gt;
If the first letter is a special character other than &lt;code&gt;-&lt;/code&gt;, the characters before &lt;code&gt;/&lt;/code&gt; become the selector.&lt;br&gt;
In addition, if the first letter is &lt;code&gt;@&lt;/code&gt;, the previous characters before the next &lt;code&gt;@&lt;/code&gt; become the media query.&lt;br&gt;
The abbreviation function is simply a function that can be used to shorten media queries or some styles.&lt;br&gt;
Through this simple syntax, it was possible to provide powerful styling features without restrictions while still being lightweight and fast, with a size of 2,655 bytes in gzip, half of which is filled with mappings for abbreviations.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ib53RTch--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--6MAdJtJF--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqtf1m4p4vxxp9l6g3t8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ib53RTch--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--6MAdJtJF--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqtf1m4p4vxxp9l6g3t8.gif" alt="CSS Lube" width="625" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;CSS Lube uses MutationObserver to achieve Atomic CSS-level performance without the need for a build step.&lt;br&gt;
It requires no configuration and runs at runtime, so you can manipulate CSS like inline styles using JS, and there are no restrictions on using selectors and media queries.&lt;br&gt;
The concise syntax minimizes the learning curve and improves workflow.&lt;br&gt;
Does all of this sound like hype?&lt;br&gt;
Check it out for yourself in the &lt;a href="https://artxe2.github.io/css-lube/repl"&gt;REPL - CSS Lube&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>css</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>JavaScript and Basic Security</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sat, 21 Oct 2023 10:24:45 +0000</pubDate>
      <link>https://dev.to/artxe2/javascript-and-basic-security-1oc5</link>
      <guid>https://dev.to/artxe2/javascript-and-basic-security-1oc5</guid>
      <description>&lt;p&gt;JavaScript is one of the most widely used languages in the world.&lt;br&gt;
It is not only the basic programming language that runs on the web, but also appears to have high demand as a server-side programming language since the advent of Nodejs.&lt;br&gt;
However, how well do programs made with JavaScript, especially web services, protect their security?&lt;br&gt;
We will learn about the basic security policies of JavaScript that must be observed regardless of programming skills.&lt;/p&gt;
&lt;h2&gt;
  
  
  XSS
&lt;/h2&gt;

&lt;p&gt;XSS, or cross-site scripting, is a type of attack that injects malicious code into a web page. It can be classified into two main types reflected and stored.&lt;br&gt;
Web browsers have a number of security policies in place, including one that invalidates script blocks inserted by the browser. This means that even if someone were to manipulate something like HTMLElement.innerHTML to inject a script block into a page, the script would not execute.&lt;br&gt;
So what's the problem? The problem occurs when malicious scripts are downloaded from the server.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reflected XSS
&lt;/h3&gt;

&lt;p&gt;Reflected XSS is a vulnerability that occurs when user-supplied parameters are inserted into a page without validation.&lt;br&gt;
For example, when showing search results based on the value of the query parameter q, if the value of q is inserted into the search bar directly, it can be used to create a URL that executes malicious scripts to a domain such as Dev.to.&lt;br&gt;
One way to address this is to escape tag characters to make them strings.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aQsHFRFj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/px3548ng5w2rttdom3s3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aQsHFRFj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/px3548ng5w2rttdom3s3.png" alt="Reflected XSS Protection" width="800" height="220"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Stored XSS
&lt;/h3&gt;

&lt;p&gt;Stored XSS is a type of attack that works on the same principle as reflected XSS, but it stores malicious scripts on the server's database using functions such as a bulletin board.&lt;br&gt;
It may seem that it can be dealt with in the same way as reflected XSS, but the thing to consider here is functions such as WYSIWYG.&lt;br&gt;
To support WYSIWYG, only the function that executes scripts without invalidating HTML should be filtered.&lt;br&gt;
The filtering targets are as follows.&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="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Attack&lt;/span&gt;&lt;span class="dl"&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;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"javascript:alert('Attack')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"javas&amp;amp;#x09;cript:alert('Attack')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"alert('Attack')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;onmousemove=&lt;/span&gt;&lt;span class="s"&gt;"alert('Attack')"&lt;/span&gt;
    &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position:absolute; z-index: 12345;
    left:-100vw; top:-100vh; width:200vw; height:200vh;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, &lt;code&gt;script&lt;/code&gt; tags should be filtered, and &lt;code&gt;href&lt;/code&gt; attributes with &lt;code&gt;javascript&lt;/code&gt; or event handlers starting with &lt;code&gt;on&lt;/code&gt; should also be filtered, even though they are executed when the user clicks.&lt;br&gt;
Here, it is important to note that filtering can be bypassed using &lt;code&gt;\&amp;amp;#x09;&lt;/code&gt;, or malicious scripts can be executed without clicking using &lt;code&gt;onmousemove&lt;/code&gt; and some styles.&lt;/p&gt;
&lt;h2&gt;
  
  
  Unverified Redirection
&lt;/h2&gt;

&lt;p&gt;If you use the URL sent by the user without validation in the redirection, it can be used to create URLs such as &lt;code&gt;dev.to?redirectUrl=attacker.site&lt;/code&gt;, similar to reflected XSS.&lt;/p&gt;
&lt;h2&gt;
  
  
  SQL Injection
&lt;/h2&gt;

&lt;p&gt;SQL injection is a vulnerability that allows an attacker to escape the string range using comments and manipulate SQL freely if the user's input is inserted into the query directly.&lt;br&gt;
It is a vulnerability that can lead to fatal damage, such as the theft of all personal information on the server or the deletion of data, but if you use the Prepared Statement function, you can treat all user input as simple strings, so no problems occur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'{id}'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'{pw}'&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;" ' OR 1 == 1 --"&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;--' AND pw = ''&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check permissions on the client side
&lt;/h2&gt;

&lt;p&gt;Web apps are vulnerable to attacks because they allow users to freely execute JavaScript through features like the console, and attackers can intercept communications, send manipulated requests, or receive manipulated responses.&lt;br&gt;
All validation logic should be handled on the server.&lt;br&gt;
Client-side validation is almost useless except for reducing server traffic due to bad requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I have listed various security vulnerabilities and their solutions, but in fact, all of these methods are based on not trusting the user's request.&lt;br&gt;
This also includes business logic processing.&lt;br&gt;
Even when processing basic CRUD, use the data from the database rather than the user's input values.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>security</category>
    </item>
    <item>
      <title>How to write types for better usability</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sun, 15 Oct 2023 14:09:44 +0000</pubDate>
      <link>https://dev.to/artxe2/how-to-write-types-for-better-usability-2b6b</link>
      <guid>https://dev.to/artxe2/how-to-write-types-for-better-usability-2b6b</guid>
      <description>&lt;p&gt;TypeScript is a very popular JavaScript tool with over 94.7k GitHub stars as of the time of writing.&lt;br&gt;
Of course, there are also 5,676 open issues, of which only 1,693 are labeled as bugs.&lt;br&gt;
I will briefly mention the problems with this, but it is still a very useful tool.&lt;br&gt;
The important fact is that the usability of TypeScript is greatly affected by how well the types are written.&lt;br&gt;
In this article, I will introduce some tips for TypeScript and JSDoc that I have used while actually writing simple libraries.&lt;/p&gt;
&lt;h2&gt;
  
  
  More intelligent union type
&lt;/h2&gt;

&lt;p&gt;Let's consider the case of defining Bird and Fish types simply.&lt;br&gt;
The &lt;code&gt;Animal&lt;/code&gt; type has a function called &lt;code&gt;eat&lt;/code&gt;, and &lt;code&gt;Bird&lt;/code&gt; and &lt;code&gt;Fish&lt;/code&gt; have functions called &lt;code&gt;fly&lt;/code&gt; and &lt;code&gt;swim&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;eat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;food&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Bird&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bird&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Fish&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;swim&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above types seem appropriate, but they are not very convenient.&lt;br&gt;
Let's write a function called &lt;code&gt;move&lt;/code&gt;, for example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;)&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;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bird&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="nx"&gt;animal&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Bird&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fish&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="nx"&gt;animal&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Fish&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;swim&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logically, it seems possible to use &lt;code&gt;type&lt;/code&gt; values to use type guards, but it is not actually the case.&lt;br&gt;
The following is how to fix the above types to work logically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BaseAnimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;eat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;food&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Bird&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bird&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;fly&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAnimal&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Fish&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;swim&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAnimal&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bird&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Fish&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use type guards, Animal must be made a union type.&lt;br&gt;
&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/dom-eater/public.d.ts"&gt;Real example: dom-eater&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Support for stronger type checking using &lt;code&gt;infer&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;infer&lt;/code&gt; keyword is a function that can be used to infer types in code using the extends keyword.&lt;br&gt;
By using infer to implement types such as Parameters and ReturnType, or by directly using infer, you can provide even more sophisticated and powerful type support.&lt;br&gt;
For example, to strengthen the type check of &lt;code&gt;setTimeout&lt;/code&gt; using &lt;code&gt;Parameters&lt;/code&gt;, you can write the code as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;any&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;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Parameters&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;

&lt;span class="c1"&gt;// Argument of type 'number' is not assignable to parameter of type 'string'.ts(2345)&lt;/span&gt;
&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// is ok&lt;/span&gt;
&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact, &lt;code&gt;setTimeout&lt;/code&gt; can execute &lt;code&gt;eval&lt;/code&gt; by passing a string as a callback, but we will not consider this part.&lt;br&gt;
&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/async-lube/private.d.ts"&gt;Real example: async-lube&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Avoid &lt;code&gt;d.ts&lt;/code&gt; and optimize the &lt;code&gt;ts.map&lt;/code&gt; by maximizing type inference.
&lt;/h2&gt;

&lt;p&gt;Defining &lt;code&gt;d.ts&lt;/code&gt; files for complex type types is not only a very tedious task, but it also makes IDEs move to &lt;code&gt;d.ts&lt;/code&gt; files instead of actual sources when using the source tracking function using &lt;code&gt;ts.map&lt;/code&gt; files.&lt;br&gt;
If you use the &lt;code&gt;infer&lt;/code&gt; keyword and &lt;code&gt;typeof&lt;/code&gt; keyword introduced above to make the most of the type inference of actual code, you can define types more simply, support strong type checking, and also enjoy the benefits of &lt;code&gt;ts.map&lt;/code&gt; files.&lt;br&gt;
I will only attach actual usage cases on this topic and move on.&lt;br&gt;
&lt;a href="https://github.com/Artxe2/lube-series/blob/master/packages/async-lube/src/src/decorator.js"&gt;Real example: async-lube&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Do not be surprised at the bugs in TypeScript
&lt;/h2&gt;

&lt;p&gt;As mentioned earlier, TypeScript has a lot of bugs.&lt;br&gt;
One of the critical bugs I encountered is that when using the typeof keyword in a generic function when generating &lt;code&gt;d.ts&lt;/code&gt; files using &lt;code&gt;tsc&lt;/code&gt; and JSDoc, the compiler does not reflect it properly and converts it to any type.&lt;br&gt;
However, there are many bugs in TypeScript, and &lt;a href="https://github.com/microsoft/TypeScript/blob/main/CONTRIBUTING.md"&gt;contributing to the project is quite cumbersome&lt;/a&gt;.&lt;br&gt;
Even to report a bug, you need to search the issue list of thousands to see if it is already a known bug.&lt;br&gt;
If you encounter a bug, the best way is to create a PR to fix it, but also consider clunky solutions.&lt;br&gt;
I solved the above bug by &lt;a href="https://github.com/Artxe2/lube-series/blob/work/scripts/async-lube_fix_types.js"&gt;writing a script to convert the returns type of any type JSDoc.&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Artxe2/lube-series/blob/work/packages/async-lube/types/src/decorator.d.ts"&gt;autogenerated d.ts&lt;/a&gt;&lt;br&gt;
I will attach a playground for some of TypeScript's bugs.&lt;br&gt;
&lt;a href="https://www.typescriptlang.org/play?#code/PTAEEsBcHIGdQMYHsBOKCmDIChkDtZJQNYkAbAN3QC5QAFFJAW3FnQB48BXJgI3RQA+UAF56jFmwB0JclQAUDZq3Qz0pSukUSVajQoAMAShPYzAQ1gBPPAlAAzLrcjgkeUAAcU7ACqD5FLQ+RqAA3tigxOiQXCjuFNgAvtggEDDwsAAWSFxkACag-OLKbJw8-EK4boSeOmy0SpIcjSrsLaXcfAKCPaK18l4DKPLGpmb4Nea05nhWfQbYANzy5qCWxU1tdc3bZV1CPUZSkJnoePIRoKkU5mRc6BAZ2bkFRZ0VlwG39w277RzvbqCEIiYShZJGMypcB4PLoAAej1ASA8Ljct2wACJLHlMVIEJlzCgAIKQeRGIA"&gt;TypeScript Bugs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.typescriptlang.org/play?filetype=js#code/PQKhCgAIUgXALAlgZ0gYwPYFssFMB2skKkAJigIYAOVuFATsgHRQwACsuWVANhZ5ADeACiZiGAc2QAuaAG0AugEpIAXgB80AL6QAKq0hsqDCliG6daCjx4AjCmgDWrYOFwAPKhnpFSuAGYUAK48RMJWNvZOKhpCUJCgEJDJMAgkmDgERCTkyNS0DKiwGBgsydCGxvSmQgAKJnicjAA8uuo6FPHQrsmY+MhEQbCIPGqQwhQxmhF2Do4TSuDxiV0wJBjO5SA9kEMjTP74Y8JTQlpLyfS4sEH0R3s84OfgwMDEqBtunt5EfQPoiHoaBC-EQGCOqnGp0E8T+g2Go0hgnOyRWW0MVxud1QggAStdbvhdABPWjNWCk3AYfwAoEg4bg9qrHYPA4QqFqTQPeKYwm7BFPJZo9icbh8ASCAb0RD4CSQAA+kHwQSwtlw9B0+gqRga5h0VBcXy8PnQ4P+aEBwJ4AH0JAR1Yg0McqNDYWb4SMxsjlmBVu8lRgiBR8MS-WxedihPisUTKeTKdTaVbbfbpWhWuomVsWQi2cdTtyfUkUv6NgB+ANiMol8MEyN4uuxskU2iJi10m12-AOtBZlI5-b+IL4J2Qk6c-kjHmNyePLRAA"&gt;JSDoc d.ts Bugs&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Simple tips for using type conversions in JSDoc
&lt;/h2&gt;

&lt;p&gt;The syntax of JSDoc is definitely not as good looking as TypeScript, but the most unique one is the type casting syntax.&lt;br&gt;
&lt;a href="https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#casts"&gt;TypeScript adopted this syntax from Google Closure&lt;/a&gt;, but I think it would have been better to create a syntax like &lt;code&gt;@cast&lt;/code&gt;.&lt;br&gt;
The simple solution I came up with for this problem is to add additional comments after the type casting syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;SomeType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// JSDoc&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/** @type{SomeType} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 

&lt;span class="c1"&gt;// JSDoc with extra comment&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/** @type{SomeType} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="cm"&gt;/**/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may seem even more cumbersome, but I personally recommend this method because the readability of the code was greatly improved when I used it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;TypeScript has become a very convenient tool over the past 10 years.&lt;br&gt;
If you handle it in the right way, as introduced in this article, TypeScript will give you great satisfaction when writing code.&lt;br&gt;
However, the many issues that exist in the TypeScript project have dampened my willingness to contribute and made it difficult to actually contribute to the project.&lt;br&gt;
I commented on the issue, but since the existing issue was reported several years ago, I don't expect it to be resolved soon.&lt;br&gt;
Nevertheless, TypeScript is already a very attractive tool, so I hope you will enjoy the convenience that this tool provides.&lt;br&gt;
Thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Who can overthrow the authority of React?</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Fri, 06 Oct 2023 16:30:28 +0000</pubDate>
      <link>https://dev.to/artxe2/who-can-overthrow-the-authority-of-react-1om5</link>
      <guid>https://dev.to/artxe2/who-can-overthrow-the-authority-of-react-1om5</guid>
      <description>&lt;p&gt;I recently discovered an interesting project called nuejs on GitHub.&lt;br&gt;
The syntax of this front-end framework, which has gained over 3k stars in just a few weeks, is quite interesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"count++"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;:if=&lt;/span&gt;&lt;span class="s"&gt;"!count"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;No clicks yet&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;:else-if=&lt;/span&gt;&lt;span class="s"&gt;"count == 1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First click!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;:else-if=&lt;/span&gt;&lt;span class="s"&gt;"count == 2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nice. Another one.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="err"&gt;:else&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Clicks: { count }&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;count = 0&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/nuejs" rel="noopener noreferrer"&gt;
        nuejs
      &lt;/a&gt; / &lt;a href="https://github.com/nuejs/nue" rel="noopener noreferrer"&gt;
        nue
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The UX Framework for the Web
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Nue  &lt;a href="https://github.com/nuejs/nue/actions/workflows/test.yaml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/nuejs/nue/actions/workflows/test.yaml/badge.svg?branch=master" alt="test"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://nuejs.org/" rel="nofollow noopener noreferrer"&gt;&lt;br&gt;
  &lt;img src="https://camo.githubusercontent.com/b1c1b8c5a2858840518b997ebd2c47adf5ec002f632c83b6b57c36bc49f54e26/68747470733a2f2f6e75656a732e6f72672f696d672f6f672d626c75652d6269672e706e67" width="900"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;What is Nue?&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;Nue is a web framework for UX developers. What used to take a React specialist, and an absurd amount of JavaScript can now be done by a UX developer and a small amount of CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nuejs.org/docs/" rel="nofollow noopener noreferrer"&gt;Learn how it works&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Who is it for?&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;Nue is designed for the following people:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;UX developers&lt;/strong&gt;: who natively jump between &lt;strong&gt;Figma&lt;/strong&gt; and &lt;strong&gt;CSS&lt;/strong&gt; without confusing &lt;a href="https://medium.com/design-warp/5-most-common-designer-developer-handoff-mishaps-ba96012be8a7" rel="nofollow noopener noreferrer"&gt;designer-developer handoff&lt;/a&gt; processes in the way.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Beginner web developers&lt;/strong&gt;: who want to skip the &lt;a href="https://roadmap.sh/frontend" rel="nofollow noopener noreferrer"&gt;redundant frontend layers&lt;/a&gt; and start building websites quickly with HTML, CSS, and JavaScript.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Experienced JS developers&lt;/strong&gt;: frustrated with the absurd amount of layers in the &lt;a href="https://roadmap.sh/react" rel="nofollow noopener noreferrer"&gt;React stack&lt;/a&gt; and look for simpler ways to develop professional websites.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Designers&lt;/strong&gt;: aiming to transfer their design skills to CSS code, but find the React/JavaScript/CSS-in-JS ecosystem impossible to grasp&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Parents &amp;amp; Teachers&lt;/strong&gt;: who wants to educate people &lt;a href="https://www.websitearchitecture.co.uk/resources/examples/web-standards-model/" rel="nofollow noopener noreferrer"&gt;how the web works&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/nuejs/nue" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;The code above is an example of implementing a simple counter, and if we write it in React and Svelte(with Runes), it will look like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;set_count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="nf"&gt;set_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;No clicks yet&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;First click!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Nice. Another one.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Clicks: &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{()&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; count++}&amp;gt;
  {#if !count}
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;No clicks yet&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  {:else if count == 1}
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;First click!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  {:else if count == 2}
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Nice. Another one.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  {:else}
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Clicks: { count }&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  {/if}
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recently, Svelte also released the runes system of Svelte5 through the article &lt;a href="https://svelte.dev/blog/runes" rel="noopener noreferrer"&gt;"Rethinking 'rethinking reactivity'"&lt;/a&gt;, and I thought about what features are necessary for a front-end framework while looking at these things.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the requirements for declaratively embedding data in HTML?
&lt;/h2&gt;

&lt;p&gt;React gained its current popularity by providing a way to write UIs in declarative programming, unlike the traditional methods like jQuery.&lt;br&gt;
React and modern front-end frameworks implement binding between JS data and DOM elements and conditional rendering or list iteration in their own way.&lt;br&gt;
My thoughts on the essential features of modern front-end frameworks&lt;/p&gt;

&lt;p&gt;I believe that the following features are essential for modern front-end frameworks&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JS to Text:&lt;/strong&gt; The value of a JavaScript variable can be displayed - in HTML, and the value will be automatically updated if it changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Components:&lt;/strong&gt; JavaScript and HTML code can be managed as components and used like HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic rendering:&lt;/strong&gt; Conditional rendering and iterative rendering are possible with statements such as if statements and for loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State management:&lt;/strong&gt; Callbacks are called based on the lifecycle of components and changes in JavaScript values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSR support:&lt;/strong&gt; In addition to SSR, there are concepts that I am not familiar with, such as resumability, islands, and server components, but it provides features that support SSR or its superior user experience and SEO optimization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features are so common that they don't even need to be listed. However, I want to make it clear that the controversial methods, such as virtual DOM, state management, and signals, are not that important.&lt;br&gt;
Of course, the most important thing is "What framework does the company that employs us use?" However, the following are the criteria for judging frameworks as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the function be implemented and the code analyzed in a simpler and more convenient way?&lt;/li&gt;
&lt;li&gt;Can it provide faster loading times?&lt;/li&gt;
&lt;li&gt;Does it have a larger ecosystem and how many different features can be implemented?&lt;/li&gt;
&lt;li&gt;To what extent can it be optimized if necessary?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Thoughts on React
&lt;/h2&gt;

&lt;p&gt;jQuery is treated as a relic of the past since its release in 2006, but &lt;a href="https://blog.jquery.com/2023/08/28/jquery-3-7-1-released-reliable-table-row-dimensions/" rel="noopener noreferrer"&gt;it is still being updated regularly&lt;/a&gt;, and surprisingly, &lt;a href="https://w3techs.com/technologies/details/js-jquery" rel="noopener noreferrer"&gt;94.5% of websites that use JavaScript libraries still use jQuery.&lt;/a&gt;&lt;br&gt;
However, if someone asks us what will happen if we use jQuery for a new project, we can confidently say that we should never use it for several reasons.&lt;br&gt;
But what about React?&lt;br&gt;
Of course, React is still a viable library with a huge ecosystem and a variety of third-party libraries.&lt;br&gt;
However, relatively new frameworks such as Svelte and Solid highlight React's shortcomings in some areas such as performance and productivity, and new frameworks such as nue are also joining this competition.&lt;br&gt;
However, React's position is still solid, and it does not seem to change its position even after a few years, according to the state of js survey results.&lt;br&gt;
When I see React, I think of Einstein's quote, "To punish me for my contempt for authority, fate made me an authority myself."&lt;br&gt;
React succeeded in overthrowing the authority of jQuery, but who can overthrow the authority of React?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to create a simple VSCE for CSS Lube</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Thu, 28 Sep 2023 12:12:35 +0000</pubDate>
      <link>https://dev.to/artxe2/how-to-create-a-simple-vsce-for-css-lube-33cf</link>
      <guid>https://dev.to/artxe2/how-to-create-a-simple-vsce-for-css-lube-33cf</guid>
      <description>&lt;p&gt;CSS Lube is a CSS library that I created. I personally use the term "CSS interpreter", but it can also be seen as a general utility-first library.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/artxe2" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1096626%2F93c589ef-99c5-4df8-96ba-ffca79f9e0f1.jpeg" alt="artxe2"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/artxe2/css-lube-highly-optimized-css-interpreter-2nl5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;CSS Lube: Highly-optimized CSS Interpreter&lt;/h2&gt;
      &lt;h3&gt;Yeom suyun ・ Aug 22 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#opensource&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;One of the slogans of this library is "It takes only 3 minutes to learn this".&lt;br&gt;
In order to make this claim a reality, I created a vscode extension.&lt;br&gt;
The features required for VSCE were simple autocompletion and hover messages to prevent the need to memorize shortcuts, and I decided to add code highlighting features as a side benefit.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqtf1m4p4vxxp9l6g3t8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqtf1m4p4vxxp9l6g3t8.gif" alt="IntelliSense CSS Lube"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  VSCE's basic API
&lt;/h2&gt;

&lt;p&gt;First, I looked at the tutorials for VSCE.&lt;br&gt;
&lt;a&gt;The sample repository&lt;/a&gt; I found in the tutorial had many examples, and I copied the source code for autocompletion and code highlighting, and then proceeded with the work by finding additional information through Google search.&lt;br&gt;
I wish the sample code was more helpful, but I was able to learn how to use the VSCE API required for feature implementation with the help of Stack Overflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hover_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MarkdownString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;hover_message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;supportHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;hover_message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;compile_style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to find the class name using AST
&lt;/h2&gt;

&lt;p&gt;After I learned the basic usage of the VSCE API, I needed a way to find where the parts of the code corresponding to the HTML's className are.&lt;br&gt;
At first, I tried to use regular expressions naively.&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;const&lt;/span&gt; &lt;span class="nx"&gt;class_name_regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;=class&lt;/span&gt;&lt;span class="se"&gt;(?:&lt;/span&gt;&lt;span class="sr"&gt;Name&lt;/span&gt;&lt;span class="se"&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;"{&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*/g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, since common front-end frameworks use JavaScript code blocks together when writing HTML, it was necessary to support the functionality of the extension for JavaScript strings used in className.&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="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;{`c=red&lt;/span&gt;
    &lt;span class="na"&gt;bg=&lt;/span&gt;&lt;span class="s"&gt;blue&lt;/span&gt;
    &lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="na"&gt;is_left&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;pr=&lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt; &lt;span class="na"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;pl=&lt;/span&gt;&lt;span class="s"&gt;1"}`}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Hello {name}!&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My solution to this was to implement an HTML AST parser and use it, even if support for JSX would be postponed until later.&lt;br&gt;
Looking at &lt;a href="https://github.com/sveltejs/svelte/issues/4701" rel="noopener noreferrer"&gt;the issues of Svelte&lt;/a&gt;, it seemed that there was no parser that met my requirements, and I created an AST parser for it myself.&lt;br&gt;
The principle is simple.&lt;br&gt;
The starting point of a script block can be identified using &lt;code&gt;{&lt;/code&gt;.&lt;br&gt;
The starting point of a string can be identified using &lt;code&gt;'&lt;/code&gt;, &lt;code&gt;"&lt;/code&gt;, or backtick.&lt;br&gt;
If &lt;code&gt;}&lt;/code&gt; appears outside of a string, it indicates the end of the script block.&lt;br&gt;
The challenge is to determine when a string ends.&lt;br&gt;
For example, in the case of backticks, I used the following regular expression to find the end point of backticks.&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;const&lt;/span&gt; &lt;span class="nx"&gt;stop_backtick_regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;=&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;!&lt;/span&gt;&lt;span class="se"&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;`|&lt;/span&gt;&lt;span class="se"&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;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was able to determine the end point of an unescaped string using &lt;code&gt;(?&amp;lt;=(?&amp;lt;!\\)(\\\\)*)&lt;/code&gt;.&lt;br&gt;
Ultimately, the AST was composed using the types below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ast_syntax_error&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/parse_dom/src/AstSyntaxError.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AstNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;Attribute&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Script&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Style&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AstSyntaxError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ast_syntax_error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Attribute&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Attribute&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Script&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;subType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;subType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;single&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;double&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="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAstNode&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BaseAstNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Attribute&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AstNode&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;subType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;closed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open&lt;/span&gt;&lt;span class="dl"&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;Element&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAstNode&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;strings&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;subType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;template&lt;/span&gt;&lt;span class="dl"&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;Script&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAstNode&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Script&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;subType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backtick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;double&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;single&lt;/span&gt;&lt;span class="dl"&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;String&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAstNode&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Style&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Style&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAstNode&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseAstNode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other than this idea, the code was not very elegant, as it was written in a way that simply wrote and debugged repeatedly until it was completed without a clear design.&lt;br&gt;
Still, if you are curious about the actual code, please refer to the link below.&lt;br&gt;
&lt;a href="https://github.com/Artxe2/dom-eater/tree/main/packages/dom-eater" rel="noopener noreferrer"&gt;dom-eater&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Artxe2/css-lube/tree/main/intellisense" rel="noopener noreferrer"&gt;css-lube/intellisense&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TODO?
&lt;/h2&gt;

&lt;p&gt;Writing Ast test code is very difficult.&lt;br&gt;
I am thinking about how to write test code simply.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj64o2ajcoce5ljrpedyc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj64o2ajcoce5ljrpedyc.png" alt="Test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JSX support seems to be more difficult than expected.&lt;br&gt;
It is necessary to support parsing for code that is being written, but even in the case of acorn, it seems that &lt;code&gt;JSXElement&lt;/code&gt; parsing is not working properly if the &lt;code&gt;loose&lt;/code&gt;(syntax error allowed) option is enabled.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>css</category>
    </item>
    <item>
      <title>A few things about regular expressions in JavaScript</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Thu, 21 Sep 2023 08:21:16 +0000</pubDate>
      <link>https://dev.to/artxe2/a-few-things-about-regular-expressions-in-javascript-41k2</link>
      <guid>https://dev.to/artxe2/a-few-things-about-regular-expressions-in-javascript-41k2</guid>
      <description>&lt;p&gt;Regular expressions are a powerful tool for matching and manipulating text in JavaScript. They have been supported since the ES3 specification in 1999, as JavaScript was originally designed for processing HTML strings.&lt;br&gt;
While complex regular expressions can be slower than optimized JavaScript logic, in general, using regular expressions to process strings is faster than not using them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Processing order of regular expressions
&lt;/h2&gt;

&lt;p&gt;JavaScript regular expressions work in three steps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When we declare a regular expression, the JavaScript engine compiles it.&lt;/li&gt;
&lt;li&gt;When we call a function on the regular expression or the string, the compiled regular expression program is passed the string, and match data is returned.&lt;/li&gt;
&lt;li&gt;The function that was called returns the appropriate result using the string and regular expression match data.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. A regex that matches all n~n ranges behind or in ahead of "AAA"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;=AAA&lt;/span&gt;&lt;span class="se"&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;AAA&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;

&lt;span class="c1"&gt;// 2. A total of 6 ranges from 0 ~ 0, 1 ~ 1... 5 ~ 5 are matched by the regex.&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AAAAA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// 3. The result is "BABABABABAB" because the ranges are replaced with "B".&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Reading order of regular expressions
&lt;/h2&gt;

&lt;p&gt;JavaScript regular expressions can use backtracking to find a match, which can lead to &lt;a href="https://javascript.info/regexp-catastrophic-backtracking"&gt;catastrophic backtracking problems&lt;/a&gt; if there is a mismatch.&lt;br&gt;
For example, the number of backtracking attempts of a regular expression can be represented by a function, depending on the number of a's in a regular expression of the form &lt;code&gt;/(a+)+b/.test("aaac")&lt;/code&gt;.&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;cases&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&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;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="o"&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;acc&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;cases&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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;a+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;+b/&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ac&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;// 1: (a)c&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aac&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 3: (aa)c, (a)(a)c, a(a)c&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aaac&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 7: (aaa)c, (aa)(a)c, (a)(aa)c, (a)(a)(a)c, a(aa)c, a(a)(a)c, aa(a)c&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aaaac&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 14: ...&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaac&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 4525&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lookaround's evaluation method
&lt;/h2&gt;

&lt;p&gt;Lookaround in regular expressions can be considered a kind of conditional statement.&lt;br&gt;
It evaluates the condition at the current position.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Matches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;X(?=Y)&lt;/td&gt;
&lt;td&gt;Positive lookahead&lt;/td&gt;
&lt;td&gt;X if followed by Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X(?!Y)&lt;/td&gt;
&lt;td&gt;Negative lookahead&lt;/td&gt;
&lt;td&gt;X if not followed by Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?&amp;lt;=Y)X&lt;/td&gt;
&lt;td&gt;Positive lookbehind&lt;/td&gt;
&lt;td&gt;X if after Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?&amp;lt;!Y)X&lt;/td&gt;
&lt;td&gt;Negative lookbehind&lt;/td&gt;
&lt;td&gt;X if not after Y&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example, the regular expression &lt;code&gt;/a(b)c(?=.*\1)/g&lt;/code&gt; first matches the string "abc", then checks if the first group, "b", is present in the following characters.&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abczb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;b&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;c&lt;/span&gt;&lt;span class="se"&gt;(?=&lt;/span&gt;&lt;span class="sr"&gt;.*&lt;/span&gt;&lt;span class="se"&gt;\1)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; ["abc"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly to how positive lookahead assertions test all possible cases until a match is found, negative lookahead assertions also test all possible cases until a match is found.&lt;br&gt;
This can be used to determine if a string does not contain a specific character, even without using the &lt;code&gt;$&lt;/code&gt; symbol.&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;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;log&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;a&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcdef&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; true&lt;/span&gt;
  &lt;span class="nx"&gt;log&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;a&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcdefa&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; false&lt;/span&gt;
  &lt;span class="nx"&gt;log&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;.*a&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcdef&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; true&lt;/span&gt;
  &lt;span class="nx"&gt;log&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;.*a&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcdefa&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I personally like regular expressions very much. This is because it is a way to improve the performance and simplify the code of JS, while reducing the number of characters, unlike WASM, which increases the number of characters due to glue code and its own size. I hope you will check and use some of the precautions of regular expressions.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>JSDoc in TS and JS</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Mon, 18 Sep 2023 01:08:37 +0000</pubDate>
      <link>https://dev.to/artxe2/jsdoc-in-ts-and-js-1p6j</link>
      <guid>https://dev.to/artxe2/jsdoc-in-ts-and-js-1p6j</guid>
      <description>&lt;p&gt;Two days ago, I wrote a post about JSDoc.&lt;br&gt;
The post was about using JSDoc for type checking, and it received over 60 comments, including my own replies.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/artxe2" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1096626%2F93c589ef-99c5-4df8-96ba-ffca79f9e0f1.jpeg" alt="artxe2"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/artxe2/throw-away-the-script-from-typescript-mn5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Throw away the "Script" from "Type""Script".&lt;/h2&gt;
      &lt;h3&gt;Yeom suyun ・ Sep 16 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#typescript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
Some of the comments were critical of JSDoc's type checking capabilities, while others defended JSDoc's ability to provide complete type checking.&lt;br&gt;
I was curious about the repetition of the same question and answer, and I realized that we were talking about different JSDoc.

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69e3phr5oasxsxevxk0k.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69e3phr5oasxsxevxk0k.gif" alt="TS JSDoc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In TypeScript, JSDoc is a pure comment.&lt;br&gt;
Although it provides some information when we hover over the code, it does not support type checking at all.&lt;br&gt;
But it's different in JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd6k1mu1dduq6tkk4mec.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd6k1mu1dduq6tkk4mec.gif" alt="JS JSDoc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By adding a few settings to &lt;code&gt;tsconfig.json&lt;/code&gt;, TypeScript can read JSDoc in JavaScript and support the same level of type checking as TypeScript.&lt;br&gt;
This is in stark contrast to the incompetent JSDoc of TypeScript.&lt;br&gt;
Also, even in cases where JSDoc is written but not used with TypeScript, such as in an eslint project, JSDoc is simply a comment.&lt;br&gt;
I agree to some extent that JSDoc can be aesthetically horrible, and it is hard to argue against that.&lt;br&gt;
However, I hope that the misunderstanding that JSDoc does not support adequate type checking will be cleared up, and I will leave an example below of how TypeScript and JSDoc can be used to perform the same type checking.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgArQM4HsTIN4BQyyMwUGYAcnALYQBcyFUoA5gNxHIA2cF1dRszadicVg2QgArjQBG0UcgQALYNwAmUCCAD8jdORwBtALqcAvgQKhIsRCgBitdQE98XAA5xt4DAcwTcy5WKDgQDW9fMAx9D2JibzsQOG4AoxAzJWIaOGTU9OxM4OILS2sEHAoSF25XRmcaN2QAXnjkKJ0YxmMuYjwSMn5aSQAiACksFRBRgBoePioRxlGAESwIOeRxSQAWAAZkC1m+-EHyJcFkCfDN+d5hq7WNrZ3GAGYADiOT4lNf5ChcKRHxdfztRJ5aApNLIXoJBIDUgXARjVBQqAwgDiYQi8DAKmgWwelzG6zu2wkjAA7Idjqd+udHmiMdjcRoaFgCUT7otUStya8qcgAGzfekI-6nXL5WHwhFnZHMlYAWVZqRxwPxhKgxL5y2uAGUmgShZJqQBWH4MxVDUmq9XcTURTnc3W85VGk0qM00gBM1slAKsZWsYFcnhQqwgEE8ACUIHANDg6gAeAAqAD5WsgE0mU65U4RiMYANLIUDIADWEFcWBgyHTpkYpwA9K3kABJDAVsDbDosE3AABuEF0jcJuFyNd7yG0+ZAdVO6bLpmQEAAHpAIj2ABQyeTQZAAHyYYBYIFYJ6YrnkWG4AEpkOO88nF4WV6XTNm2x3u7Pwm2KAwncetewgGhYgnHRkGnFBuSAkC50TN86m2CJkAQ4BIBobYewAdwgbhuFORhPzXTdtw0HsAEFgLgQtQBgI8aOzF8UILVM6JA1No1jV9ONYzMfwRdsuz7YAe2wOhkC5HVZLkAArCAEDAeY4NnedUPcPhkEI4jSOQPj4w498M1XTNLEzCoqj7eAmjqP1GGMgSzMaNxszaYsOlBPwelOJE7X5a5JmmPVPWeCk3mQA5A0RJl7RC25wsSyLfWQL44qlYggQiTo-IhHzZX8hVbRRA1RnRWVnQ0bUeQWCLBXmaLaTihFAvKp4quhDV2VdHUUuCtLmuFMU2uQbKEhlHq5RtDqIrVar2Tq90GtS41sJ9EbzStCUFXm1LFpmmr+vqkkho201tv9cbJpDTgCHstwADp8piHMsmQMSsCrR7alcP1Xt8962k+sToCgLAoGsJ66iB6IMGMfZTGenYcwARnYL6Ox+v6HIB+GwSRlG0baTHsfXYCoesb7fth1xCb8V7pAwFRd286KDgBJVEoAckmDBYxUXmAXOg1efJXmCAsB8HvBqnofpwG3owZnWfZrhOf2bmgvFgWhZFrgxauCWNilmWHsqEBqnp95nJjEyFzTdy6k8mp8fYIA" rel="noopener noreferrer"&gt;TypeScript DeepReadonly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?filetype=js#code/PQKhCgAIUgBAXAngBwKYBNUDNIAVUBOAzgPYB2UMsyBJaBSkA3kfAQJZkDmAvpFu2LwAcgEMAtqkpwadQoxZtOvSABtRrMZOnVa9BWQCu4gEaE+orlOgy98xM3zFyAbQC6fFwGMAFu1XoBKhkbpTA4OCgEDYIKBjYkABiEv6IOrL6DkxOpGTufMiiQWTwROl2DFlM0pCQhfCEZKKqAFx4hLnuNZDiog0ETa3tznmhNjx8XASiZOiFxaVhEVFwSGjMyeKpfCDhXuSs-CmqDgC8zFB1RcGlbS6XtUz8gpoSqG0ARABSJD5kHwAaNQaERvT4AERIqEBkEs70gABYAAyQHgAh7MZ5CLTw74zaFA9SvSQQqEwuFtADMAA5Uejam56ZApjM5tcSkQ2tVarV6o1mncMY8scTcbg+vzVABxaazLB9HyEGFE0EkyAfSEE2FWNoAdhRaKFmIE2LB6vF-UGMtZ4hI8EVBGVIJxpK1FMgADZaYaeZBGRjepaBZB7r7hSbRZ8ALISgbNa1yhVKwnOs0fADKW3t5J1kF1AFY6UanhHVbiY0HpbL0Lb7cngZH1Zn2Nmge7dQAmIu+-21HjgHgAbmWYB0DXEyHUDUgABUx3FMDgmAAlVCidDkE4AHm5MFqLgA0pBOJAANaoRAkHAztxtbq1GeHtyQVAADwasyIkAAFEZTIRIAAH0gVgOG4ICQMQUwSFUABKe8eQAfkgVd103RAt0fA83AAPkgBDajaLDnzfD90C-ABBAhpgwzgsAAiicIIpCULXDcyG3KiaK3cFUFQZBUPYzicJE-CbDDHk2l4-jBPQzCnyY8YcL4aSBLY9ClkiMBVjiZhVNkjiMM2VJlOgPYDngI4thOLtzm5K4Fk5EMMRLF4y0+H4-idRsNTJNtc2RbseVc001TxMgtRVF11U1HN4RpILe2Zat5huJz7N5WNBkFCSQp8i1JQTdB5TrR0Ux82L-PhfUgt9PL3PNLL42rWsHW8hrfLdXMvVqv0mVqQNJRysN6uij4K0K6sSra8qOubVttWqwsfRGkUOomuMqxtO0ZobOasx8OK9S7FaGSZfshwieVrMQAA6VKOUgc53EHSBgGASASFPcBrtSDt7vZUonpDNxXvel9qJIAgruOO6HtKFwkTcW64WBgBGMGPq+n7Yf++GiER5HUfODG3o+whaGhyIse+36TgBxz7sMIgfG-ez3WRJlS2igByH4iH4nweaZKKzR5zUeYHWDh2piHKZxm68cBogmZZtnLg5pEubc3n+cF4XLlFtVxahSWeGlkcqDWVA9L4tS0MMrdjJOUzdnAfYyEOOnEEpYHvcHIA" rel="noopener noreferrer"&gt;JSDoc DeepReadonly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?filetype=js#code/PQKhCgAIUgBB7AbgUwE4Bt4EMAmUawAOWqWAtpAN4B2ArmQEZoC+kALgJZnIDOb5hfHFTI2tVNR5UAIljbJm+YKAjQ4SNJlxCiJclTqMWkMjuKkKNek1Ss8a3RYPXjATx0ixEqZVnzF0MpgZnqWhjasZADyqAAqXLz8ZISQIU5WRraQANo4ALpp+hkROa4FDp7ikjJyCkrgAGa01ADGnPDUJlgA1sh+yAAU0XEJfAIANJA4k64AlFRQkBwNkAM4kACEALxbkM04yA0c1MjrAGRnkK6bO3vUB0cnOPOUi5CQlRKQJwDukP0DVyTYbxbhjZKTZ4AbkWrGQ6B4yAW73en06v3+tSGMVBiQEsxh70UihaHT4UwAjJBdmQen0sRSAEwAZgALABWABsAHYABwE8CkyRsKaM6ldXoA9mTaWQdkCoXknDM8W0yUMybMglAA" rel="noopener noreferrer"&gt;JSDoc function overloads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?filetype=js#code/PQKhAIAEBcE8AcCmATRAzcBvTAocFwBrASwDtkAucAIgGNiAnWgG0WrwIYENliBXAM5VSfALYAjRAw7gAvrPABhRi0T5gOHKAgwEKdFlz5wRMpRoCAjny4M2M8AOKoAMolIBzaAAthYydLG8uAAyta2aiAaWmBQcEioGJjKTKzgAD6h4XYKId5cSOqa2lDwtlyiWHkFiAoC+YVROGh8pLTQxAD2pOAeiNAAgnZcABT1NQCUWHiOAO7E0LTe4GMNiAB0JORTRibgtFwCanQqrNQUM3vgdtB8DD0Aslw+6wAKAJLG40jr3LyC+AgACZLvtDscrDY7OdQSYbncet8Nk5XO4vMtYiCTLIcLIgA" rel="noopener noreferrer"&gt;JSDoc discriminated unions&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Throw away the "Script" from "Type""Script".</title>
      <dc:creator>Yeom suyun</dc:creator>
      <pubDate>Sat, 16 Sep 2023 14:03:01 +0000</pubDate>
      <link>https://dev.to/artxe2/throw-away-the-script-from-typescript-mn5</link>
      <guid>https://dev.to/artxe2/throw-away-the-script-from-typescript-mn5</guid>
      <description>&lt;p&gt;Before writing this article, I will first attach a post that was posted on a community a few days ago.&lt;br&gt;
&lt;a href="https://world.hey.com/dhh/turbo-8-is-dropping-typescript-70165c01" rel="noopener noreferrer"&gt;Turbo 8 is dropping TypeScript&lt;/a&gt;&lt;br&gt;
After seeing the title of the above article, I thought it was about the library turbo8 migrating from TypeScript to JSDoc.&lt;br&gt;
However, it was not.&lt;br&gt;
The team removed the type annotations from their codebase, changed the file extensions to js, but did not add comments.&lt;br&gt;
Yes, what they wanted was freedom from types.&lt;br&gt;
At this point, I will attach the post that was posted the day after the above post.&lt;br&gt;
&lt;a href="https://world.hey.com/dhh/open-source-hooliganism-and-the-typescript-meltdown-a474bfda" rel="noopener noreferrer"&gt;Open source hooliganism and the TypeScript meltdown&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  TypeScript is not productive.
&lt;/h2&gt;

&lt;p&gt;I mostly agree with DHH's post, and I think that some of the older JavaScript-based libraries that support &lt;code&gt;@types&lt;/code&gt; are supporting TypeScript simply because they don't have the courage to stand up to the TypeScript zealots.&lt;br&gt;
There are many cases where libraries support &lt;code&gt;@types&lt;/code&gt; because TypeScript users demand it, even if they think TypeScript is unproductive.&lt;br&gt;
However, I am very positive about types.&lt;br&gt;
I am a fan of the JSDoc tool, to be exact.&lt;br&gt;
Therefore, in this article, I will introduce how convenient JSDoc is.&lt;/p&gt;
&lt;h2&gt;
  
  
  JSDoc's type is just a comments.
&lt;/h2&gt;

&lt;p&gt;JSDoc is a tool that provides type hints for JavaScript using comments.&lt;br&gt;
Some TypeScript programmers criticize this, arguing that comments should only be comments and should not affect code.&lt;br&gt;
However, TypeScript does not have runtime type checking, and JSDoc types are only used for IntelliSense, linting, and code summarization.&lt;br&gt;
Therefore, comments are a very appropriate place to write types.&lt;br&gt;
JSDoc does not affect the source code in any way. It also skips the unnecessary compilation step of TypeScript, allowing you to enjoy the freedom of JavaScript to the fullest.&lt;br&gt;
Of course, there are a few exceptions.&lt;br&gt;
For example, if the type is incorrectly declared or &lt;a href="https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing" rel="noopener noreferrer"&gt;shadowing&lt;/a&gt; is attempted, I had to use &lt;code&gt;@ts-ignore&lt;/code&gt; to work around the issue.&lt;br&gt;
I have never studied TypeScript separately, so there may be other elegant solutions that I am not aware of.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// lib.es5.d.ts&lt;/span&gt;
&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// js-source&lt;/span&gt;
&lt;span class="c1"&gt;// @ts-ignore: index -&amp;gt; index?&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @type {RegExp} */&lt;/span&gt;&lt;span class="c1"&gt;// @ts-ignore: string -&amp;gt; RegExp&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.[:=].&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;// @ts-ignore: string -&amp;gt; RegExp&lt;/span&gt;
&lt;span class="k"&gt;for &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;key&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;  &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;
&lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Do types make JavaScript harder?
&lt;/h2&gt;

&lt;p&gt;Let's reverse the question.&lt;br&gt;
How can types make JavaScript difficult?&lt;br&gt;
Could it be a long learning curve, adding verbose syntax, or difficult types?&lt;br&gt;
Here, it seems that the only thing that can be established for JSDoc is difficult types.&lt;br&gt;
I had no problem using JSDoc even with a basic knowledge of Java and a quick glance at a Svelte codebase written in JSDoc.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. How to set up JSDoc
&lt;/h3&gt;

&lt;p&gt;For more information, please see my article titled &lt;a href="https://dev.to/artxe2/how-to-set-up-jsdoc-for-npm-packages-1jm1"&gt;How to configure JSDoc instead of TypeScript&lt;/a&gt;.&lt;br&gt;
I have made several improvements to make it possible to apply JSDoc to library code concisely and to use it in both JS and TS projects.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Applying types to code with JSDoc
&lt;/h3&gt;

&lt;p&gt;This is also all covered in the &lt;a href="https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html" rel="noopener noreferrer"&gt;TypeScript - JSDoc Reference&lt;/a&gt;.&lt;br&gt;
The important points can be summarized as follows.&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="cm"&gt;/**
 * @template T
 * @param {T|import("../../private.js").SomeType} my_parameter
 * @returns {Map&amp;lt;T, number&amp;gt;}
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;my_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;my_parameter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/** @type {[T, number][]} */&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="cm"&gt;/** @type {T} */&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;my_parameter&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="p"&gt;]&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;my_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;my_map&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript has excellent type inference, so JSDoc only requires a few additional syntaxes.&lt;br&gt;
Here is an example of my actual code.&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="cm"&gt;/**
 * @param {Map&amp;lt;*[], Function&amp;gt;} nodes
 * @param {number} index
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run_dag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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="cm"&gt;/** @type {Map&amp;lt;*[], Function&amp;gt;} */&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="cm"&gt;/** @type {Map&amp;lt;Function, *[][]&amp;gt;} */&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dependents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="cm"&gt;/** @type {[number]} */&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

      &lt;span class="k"&gt;for &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;dependencies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&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;clone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="nx"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for &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;p&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;clone&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dependents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&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;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;dependents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;clone&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;for &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;dependencies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;jobs&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;dependencies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&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="nf"&gt;run_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dependents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reject&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSDoc is used in the above code to specify the types of parameters, the generic type of a Map object, and the length of a number[] used as a pointer.&lt;br&gt;
The rest of the code is typed with type inference.&lt;br&gt;
JSDoc also supports auto-completion, making it easy to write function parameters.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni9tru9w93q39f0lvf2p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni9tru9w93q39f0lvf2p.gif" alt="JSDoc auto-completion"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How to write complex and challenging types
&lt;/h2&gt;

&lt;p&gt;So, there is one reason left why we should not use JSDoc.&lt;br&gt;
The reason why DHH said "Things that should be easy become hard, and things that are hard become &lt;code&gt;any&lt;/code&gt;. No thanks!" is probably because defining complex and challenging types is literally complex and challenging.&lt;br&gt;
Adding types to JavaScript provides several improvements to the developer experience, such as autocompletion support and better syntax highlighting.&lt;br&gt;
However, in the case of complex types, typing can be cumbersome, and features like type checking may not work properly.&lt;br&gt;
I will use the types of eslint that I recently worked on as an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Property&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;BaseNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Property&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Expression&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PrivateIdentifier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Expression&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Pattern&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Could be an AssignmentProperty&lt;/span&gt;
    &lt;span class="nl"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;init&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;set&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;shorthand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NodeMap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;AssignmentProperty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AssignmentProperty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;CatchClause&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CatchClause&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="nx"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Property&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NodeMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;NodeMap&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Identifier&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;BaseNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BaseExpression&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BasePattern&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NodeParentExtension&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;Identifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Identifier&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;NodeParentExtension&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Identifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&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;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Property&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&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;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&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;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// TS error here&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;eslint's &lt;code&gt;Rule.RuleListener.Identifier&lt;/code&gt; generates a lot of type errors in normal JS code, making autocompletion impossible.&lt;br&gt;
This is despite the incredibly verbose and detailed &lt;code&gt;d.ts&lt;/code&gt; files of eslint and estree.&lt;br&gt;
My initial solution was to make things that are hard become &lt;code&gt;any&lt;/code&gt;, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// private.d.ts&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Pattern&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;imported&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="nx"&gt;shorthand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @param {import("../private").ASTNode} node */&lt;/span&gt;
&lt;span class="nc"&gt;Identifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was a "No Thanks" solution, but I finished coding by fixing type errors and getting some Intellisense support.&lt;br&gt;
After that, I considered how to use the verbose types of estree, and the result is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// private.d.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ASTNode&lt;/span&gt;
  &lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ArrayExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ArrayPattern&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ArrowFunctionExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AssignmentExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AssignmentPattern&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AwaitExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BinaryExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BlockStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BreakStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CallExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CatchClause&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ChainExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ClassBody&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ClassDeclaration&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ClassExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ConditionalExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ContinueStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DebuggerStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DoWhileStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EmptyStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExportAllDeclaration&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExportDefaultDeclaration&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExportNamedDeclaration&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExportSpecifier&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExpressionStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ForInStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ForOfStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ForStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FunctionDeclaration&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FunctionExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Identifier&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IfStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ImportDeclaration&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ImportDefaultSpecifier&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ImportExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ImportNamespaceSpecifier&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ImportSpecifier&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LabeledStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Literal&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LogicalExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MemberExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MetaProperty&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MethodDefinition&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NewExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ObjectExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ObjectPattern&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PrivateIdentifier&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Program&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Property&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Identifier&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PropertyDefinition&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RestElement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReturnStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SequenceExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SpreadElement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StaticBlock&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Super&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SwitchCase&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SwitchStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TaggedTemplateExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TemplateElement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TemplateLiteral&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ThisExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ThrowStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TryStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UnaryExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UpdateExpression&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VariableDeclaration&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VariableDeclarator&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WhileStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WithStatement&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;estree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;YieldExpression&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @param {import("../private").ASTNode &amp;amp; import("estree").Identifier} node */&lt;/span&gt;
&lt;span class="nc"&gt;Identifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second solution works amazingly well, and I was able to find and fix errors in my first solution's code using typecheck.&lt;br&gt;
The type error was caused by incorrect NodeMap, Identifier, and NodeParentExtension types.&lt;br&gt;
I think that almost all of the unpleasantness of using JSDoc comes from incorrect type declarations.&lt;br&gt;
However, I think it would be difficult to have incorrect type declarations if you coded using JSDoc from the beginning.&lt;br&gt;
This is because &lt;strong&gt;you can use JS code as a type directly.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting the most out of type inference
&lt;/h2&gt;

&lt;p&gt;JavaScript has implicit types, which allow TypeScript to perform type inference.&lt;br&gt;
We can use JavaScript's basic types without declaring separate types.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;string_array&lt;/span&gt; &lt;span class="o"&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;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// string[]&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// { key: string }&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt; &lt;span class="c1"&gt;// Map&amp;lt;any, any&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// class Class&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// function (): Set&amp;lt;any&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, it is also possible to use the inferred types from JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./export.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;string_array&lt;/span&gt; &lt;span class="c1"&gt;// string[]&lt;/span&gt;
&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="c1"&gt;// { key: string }&lt;/span&gt;
&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="c1"&gt;// Map&amp;lt;any, any&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Class&lt;/span&gt; &lt;span class="c1"&gt;// Class&lt;/span&gt;
&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="c1"&gt;// function (): Set&amp;lt;any&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// Set&amp;lt;any&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see from the above examples, TypeScript is able to infer the complex types that occur in JavaScript, so we can simply use them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Are you using TypeScript?&lt;br&gt;
Use JSDoc.&lt;br&gt;
Are you using JavaScript?&lt;br&gt;
Use JSDoc.&lt;br&gt;
Does TypeScript's unnecessary compilation harm the developer experience?&lt;br&gt;
Use JSDoc.&lt;br&gt;
Does JavaScript's lack of IntelliSense harm the developer experience?&lt;br&gt;
Use JSDoc.&lt;br&gt;
Does TypeScript's typecheck harm JavaScript's freedom?&lt;br&gt;
Make use of type inference.&lt;br&gt;
Is it cumbersome to write d.ts to support TypeScript for a JavaScript library?&lt;br&gt;
Use JSDoc to generate it automatically.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
