<?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>Forem: Pacharapol Withayasakpunt</title>
    <description>The latest articles on Forem by Pacharapol Withayasakpunt (@patarapolw).</description>
    <link>https://forem.com/patarapolw</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%2F260982%2F69638b66-0638-4136-859c-5c87f8e9562a.jpeg</url>
      <title>Forem: Pacharapol Withayasakpunt</title>
      <link>https://forem.com/patarapolw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/patarapolw"/>
    <language>en</language>
    <item>
      <title>Multiple page Vite on Github Pages with HTML5 History Mode</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Wed, 20 Apr 2022 08:10:16 +0000</pubDate>
      <link>https://forem.com/patarapolw/vite-on-github-pages-with-html5-history-mode-283j</link>
      <guid>https://forem.com/patarapolw/vite-on-github-pages-with-html5-history-mode-283j</guid>
      <description>&lt;p&gt;Indeed, one of the way is simply &lt;a href="https://vitejs.dev/guide/ssr.html"&gt;pre-render&lt;/a&gt; (e.g. with &lt;a href="https://vite-plugin-ssr.com/"&gt;vite-plugin-ssr&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Nonetheless, it is possible to enable fallback (without redirect settings, which doesn't exist in Github Pages), if you don't want to pre-render, and sacrifice JavaScript-ness yet. The way is, to clone &lt;code&gt;dist/index.html&lt;/code&gt; to &lt;code&gt;dist/sub/route/index.html&lt;/code&gt;. (SSG's also have multple &lt;code&gt;**/index.html&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;existsSync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mkdirSync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;copyFileSync&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;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;resolve&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pathResolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;join&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pathJoin&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;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;cloneIndexHtmlPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;PluginOption&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CloneIndexHtmlPlugin&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;outDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// config's `build.outDir`&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pathJoin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;closeBundle&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="c1"&gt;// routes.push(...)&lt;/span&gt;

      &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pathResolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outDir&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;existsSync&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="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;mkdirSync&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;recursive&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="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pathJoin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outDir&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// It is possible to edit HTML here, too.&lt;/span&gt;
        &lt;span class="nx"&gt;copyFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dst&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="nx"&gt;log&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: Copied &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dst&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="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;And put the plugin in &lt;code&gt;vite.config.ts&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="c1"&gt;// https://vitejs.dev/config/&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;base&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;GITHUB_REPO_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cloneIndexHtmlPlugin&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;
  
  
  Integrating with Vue 3 and Vue Router 4
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;VueRouter&lt;/code&gt; makes navigating easier, without full page reload; however, it does need a little extra config - &lt;code&gt;baseURL&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createWebHistory&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;vue-router&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;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;createWebHistory&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;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Define your routes 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;&lt;a href="https://vitejs.dev/guide/features.html#glob-import"&gt;Route names can be glob&lt;/a&gt; dynamically with &lt;code&gt;import.meta.glob&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createWebHistory&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;vue-router&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;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;createWebHistory&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;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Does not allow string templating - `${PAGE_DIR}/**/*${PAGE_EXT}` does not work.&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&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;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../pages/**/*.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="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="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PAGE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../pages&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;PAGE_EXT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.vue&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;PAGE_INDEX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PAGE_DIR&lt;/span&gt;&lt;span class="p"&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;p&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="nx"&gt;PAGE_EXT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PAGE_INDEX&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;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;substring&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="nx"&gt;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="nx"&gt;PAGE_INDEX&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="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="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;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;path&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&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;component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="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;&lt;code&gt;cloneIndexHtmlPlugin&lt;/code&gt; should also glob - &lt;code&gt;fast-glob&lt;/code&gt; is what &lt;code&gt;import.meta.glob&lt;/code&gt; uses, so copy it.&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sync&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;glob&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;fast-glob&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PAGE_EXT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.vue&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;PAGE_INDEX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

      &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;glob&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;PAGE_EXT&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="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/pages&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;map&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="o"&gt;=&amp;gt;&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;=&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substring&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="nx"&gt;p&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="nx"&gt;PAGE_EXT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endsWith&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="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;PAGE_INDEX&lt;/span&gt;&lt;span class="p"&gt;))&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;=&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substring&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="nx"&gt;p&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="nx"&gt;PAGE_INDEX&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="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="k"&gt;return&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;filter&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;PAGE_INDEX&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;



</description>
      <category>vite</category>
      <category>vue</category>
      <category>webdev</category>
      <category>github</category>
    </item>
    <item>
      <title>Why do I even need favicon to prevent server errors? And, why the default is .ico?</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Wed, 13 Oct 2021 02:02:58 +0000</pubDate>
      <link>https://forem.com/patarapolw/why-do-i-even-need-favicon-to-prevent-server-errors-and-why-the-default-is-ico-3gbd</link>
      <guid>https://forem.com/patarapolw/why-do-i-even-need-favicon-to-prevent-server-errors-and-why-the-default-is-ico-3gbd</guid>
      <description>&lt;p&gt;Do I even need &lt;code&gt;/favicon.ico&lt;/code&gt; for &lt;code&gt;http://localhost&lt;/code&gt; or Electron?&lt;/p&gt;

&lt;p&gt;Right now? I use 1px PNG (not ICO) at &lt;code&gt;/f/favicon.png&lt;/code&gt; (not at &lt;code&gt;/&lt;/code&gt;, but at &lt;code&gt;/f/&lt;/code&gt;). I think it is at least better than using a a short string of data URI (where Fastify Helmet or Express Helmet won't allow).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pillow
python &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'from PIL import Image;Image.new("RGBA", (1,1), color=(0,0,0,0)).save("favicon.ico", sizes=[(1,1)])'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>favicon</category>
      <category>webdev</category>
      <category>discuss</category>
      <category>electron</category>
    </item>
    <item>
      <title>Do we need two version-locking files? (Pipfile = "*" vs pypoetry.toml vs venv + requirements.txt)</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Tue, 05 Oct 2021 05:29:47 +0000</pubDate>
      <link>https://forem.com/patarapolw/do-we-need-two-version-locking-files-pipfile-vs-pypoetry-toml-vs-venv-requirements-txt-3675</link>
      <guid>https://forem.com/patarapolw/do-we-need-two-version-locking-files-pipfile-vs-pypoetry-toml-vs-venv-requirements-txt-3675</guid>
      <description>&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; I am also confused about &lt;code&gt;.venv/bin/python&lt;/code&gt;'s location - in-project &lt;code&gt;$PROEJCT_ROOT/.venv/bin/python&lt;/code&gt; or global (e.g. &lt;code&gt;~/.pyenv/versions/$PROJECT_IDENTIFIER/.venv/bin/python&lt;/code&gt;)?&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipenv's defaults
&lt;/h2&gt;

&lt;p&gt;I feels odd to me that my &lt;code&gt;Pipfile&lt;/code&gt; looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[[source]]&lt;/span&gt;
&lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://pypi.org/simple"&lt;/span&gt;
&lt;span class="py"&gt;verify_ssl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"pypi"&lt;/span&gt;

&lt;span class="nn"&gt;[packages]&lt;/span&gt;
&lt;span class="py"&gt;fastapi&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="py"&gt;aiofiles&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="py"&gt;uvicorn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="py"&gt;gunicorn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="nn"&gt;gtts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;git&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/patarapolw/gTTS.git"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;wordfreq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;extras&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["cjk"]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nn"&gt;[dev-packages]&lt;/span&gt;

&lt;span class="nn"&gt;[requires]&lt;/span&gt;
&lt;span class="py"&gt;python_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"3.9"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To say that, if you know lock files in other programming languages' package managers; this looks &lt;strong&gt;VERY OPINIONATED&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Of course, there is &lt;code&gt;Pipfile.lock&lt;/code&gt;, but it doesn't look very readable to me, unlike &lt;code&gt;package.json&lt;/code&gt; or &lt;code&gt;go.mod&lt;/code&gt; (which, of course, have &lt;code&gt;package.lock&lt;/code&gt; and &lt;code&gt;go.sum&lt;/code&gt; to pair with).&lt;/p&gt;

&lt;p&gt;Another problem is, Pipenv IS NOT VERY VERBOSE at all...&lt;/p&gt;

&lt;p&gt;Personally, I also add &lt;code&gt;export PIPENV_VENV_IN_PROJECT="enabled"&lt;br&gt;
&lt;/code&gt; to &lt;code&gt;~/.zshrc&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;python -m venv .venv&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This path typically creates only one version-locking - &lt;code&gt;requirements.txt&lt;/code&gt;; and it can be readable, if not compiled directly from &lt;code&gt;pip freeze &amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have seen some projects with multiple &lt;code&gt;requirements.txt&lt;/code&gt; (e.g. &lt;code&gt;.prod.txt&lt;/code&gt;, &lt;code&gt;.dev.txt&lt;/code&gt;); but I have seen &lt;strong&gt;NONE&lt;/strong&gt; with &lt;code&gt;requirements.lock&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But of course, it is as easy as &lt;code&gt;pip freeze &amp;gt; requirements.lock&lt;/code&gt;; even perhaps adding to git pre-commit hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt; ~/.git/hooks/pre-commit
#!/usr/bin/env bash
source .venv/bin/activate
pip freeze &amp;gt; requirements.lock
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ~/.git/hooks/pre-commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Personally, I don't really use this option much.&lt;/p&gt;

&lt;h2&gt;
  
  
  Poetry's opinionatedness
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;poetry add &amp;lt;PACKAGES&amp;gt;&lt;/code&gt; actually pin versioning into TWO lock files, one with exact, another with &lt;code&gt;&amp;gt;=&lt;/code&gt;; but I distaste this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ poetry init
...
Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, you wanted me to answer YES, huh?&lt;/p&gt;

&lt;p&gt;Personally, I am add config,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;poetry config set virtualenvs.in-project true&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  semver syntax I learnt from JavaScript Node.js
&lt;/h2&gt;

&lt;p&gt;So, in Node.js, we have something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;=2.0.1
^2.0.1
~2.0.1
2.0.1
2.0
2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not sure about these syntaxes in Python, and whether it is just &lt;code&gt;requirements.txt&lt;/code&gt; (TXT file), &lt;code&gt;setup.py&lt;/code&gt; (Python file), or whatever &lt;code&gt;*.toml&lt;/code&gt; files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do we still need &lt;code&gt;setup.py&lt;/code&gt;; if we are not publishing to PyPI or local repository?
&lt;/h2&gt;

&lt;p&gt;I don't know the answer to this either...&lt;/p&gt;

&lt;p&gt;But of course, it can help with py2app or py2exe; which I don't need when I already have PyInstaller.&lt;/p&gt;

&lt;h2&gt;
  
  
  A thought
&lt;/h2&gt;

&lt;p&gt;Why can't we just go back to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt; requirements.txt
fastapi
aiofiles
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
pip freeze | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;requirements.txt&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.lock
python &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .python-version

&lt;span class="c"&gt;# Then, hand-edit requirements.txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is YOUR decision?
&lt;/h2&gt;

&lt;p&gt;For me, even though I like Poetry, I don't like some of the defaults; but the general defaults of other options are even more insane.&lt;/p&gt;

&lt;p&gt;How would you deviate from the default settings?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>python</category>
      <category>healthydebate</category>
      <category>programming</category>
    </item>
    <item>
      <title>Customizable PDF viewer with self-built PDF.js</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Sun, 03 Oct 2021 06:53:20 +0000</pubDate>
      <link>https://forem.com/patarapolw/customizable-pdf-viewer-with-self-built-pdf-js-194o</link>
      <guid>https://forem.com/patarapolw/customizable-pdf-viewer-with-self-built-pdf-js-194o</guid>
      <description>&lt;p&gt;At first glances, PDF viewer seems to be as easy as opening a PDF URL in an Iframe; however, not only uncustomizable, but also, if some browsers doesn't support PDF browsing, it could be a problem.&lt;/p&gt;

&lt;p&gt;A solution to this would be &lt;a href="https://github.com/mozilla/pdf.js" rel="noopener noreferrer"&gt;Mozilla's PDF.js&lt;/a&gt;. However, the PDF viewer isn't prebuilt for you in &lt;a href="https://github.com/mozilla/pdfjs-dist" rel="noopener noreferrer"&gt;pdf.js-dist&lt;/a&gt;, only some minimal JavaScript files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building PDF.js by yourself
&lt;/h2&gt;

&lt;p&gt;By this way, it will also build the PDF viewer (which is normally used in Mozilla Firefox). You can also customize HTML, CSS and JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
npm i gulp-cli
git submodule add https://github.com/mozilla/pdf.js.git
&lt;span class="nb"&gt;cd &lt;/span&gt;pdf.js
npm i

&lt;span class="c"&gt;# Edit web/app_options.js (for default PDF); and `web/viewer.html or CSS files (for UI) to your liking&lt;/span&gt;

npx gulp generic
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; build/generic ../pdf.js-dist
&lt;span class="nb"&gt;cd&lt;/span&gt; -
npx http-server pdf.js-dist &lt;span class="nt"&gt;-o&lt;/span&gt; /web/viewer.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  I already built it for you
&lt;/h2&gt;

&lt;p&gt;This is here. Just copy the &lt;a href="https://github.com/patarapolw/pdf.js-viewer/tree/main/dist" rel="noopener noreferrer"&gt;&lt;code&gt;/dist&lt;/code&gt;&lt;/a&gt; folder.&lt;/p&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/patarapolw" rel="noopener noreferrer"&gt;
        patarapolw
      &lt;/a&gt; / &lt;a href="https://github.com/patarapolw/pdf.js-viewer" rel="noopener noreferrer"&gt;
        pdf.js-viewer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Example of how to build example viewer of Mozilla's PDF.js
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  My example project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ly.polv.cc" rel="noopener noreferrer"&gt;This online Lilypond compiler / playground&lt;/a&gt; is made using this, using the endpoint &lt;code&gt;/pdf.js/web/viewer.html?file=&amp;lt;FILEPATH&amp;gt;#pagemode=none&lt;/code&gt;. It's a quick project of mine to compile MIDI and WAV files, and share it.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>`docker compose` (v2) vs `docker-compose` (v1) vs `podman-compose` - which one to choose?</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Thu, 30 Sep 2021 13:22:27 +0000</pubDate>
      <link>https://forem.com/patarapolw/docker-compose-v2-vs-docker-compose-v1-vs-podman-compose-which-one-to-choose-19nl</link>
      <guid>https://forem.com/patarapolw/docker-compose-v2-vs-docker-compose-v1-vs-podman-compose-which-one-to-choose-19nl</guid>
      <description>&lt;h2&gt;
  
  
  Latest Docker Compose (v2)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/compose/cli-command/"&gt;https://docs.docker.com/compose/cli-command/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the command is no longer &lt;code&gt;docker-compose&lt;/code&gt; (although there is &lt;a href="https://github.com/docker/compose-switch"&gt;compose-switch&lt;/a&gt;), but rather, a Docker plugin, &lt;code&gt;docker compose&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For some reasons, it had to rebuild my Dockerfile image again, even though I have built (and tagged) it before.&lt;/p&gt;

&lt;p&gt;I saw that there that are releases for Windows and macOS (darwin, including arm64) as well; &lt;a href="https://docs.docker.com/compose/cli-command/#install-on-mac-and-windows"&gt;and it is already installed by default on Windows and macOS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legacy Docker Compose (v1)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/compose/install/"&gt;https://docs.docker.com/compose/install/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one has absolutely my expected behavior. Nothing special. No surprise dangers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://wiki.archlinux.org/title/Podman#Docker_Compose"&gt;podman-compose&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This one uses &lt;a href="https://podman.io/"&gt;podman&lt;/a&gt;, which is probably only available in Linux (&lt;a href="https://podman.io/blogs/2021/09/06/podman-on-macs.html"&gt;and macOS&lt;/a&gt;), and requires &lt;code&gt;podman.service&lt;/code&gt; user unit; so, probably cannot be started in Windows' WSL.&lt;/p&gt;

&lt;p&gt;Goodies, other than can be &lt;strong&gt;rootless&lt;/strong&gt; podman (i.e. no root privileges, nor &lt;code&gt;usermod -aG docker $USER&lt;/code&gt;); is that it actually create a "pod" containing multiple containers.&lt;/p&gt;

&lt;p&gt;So, what are unexpected behaviors I have found?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cannot attach to virtual volumes, nor attach to non-existent folders (will not create a new folder)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;podman-compose up $SERVICE_NAME&lt;/code&gt; does not work, unlike &lt;code&gt;docker-compose&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Ctrl+C&lt;/code&gt; does not destroy pod, nor "down", so &lt;code&gt;podman-compose up&lt;/code&gt; &amp;gt;&amp;gt; &lt;code&gt;Ctrl+C&lt;/code&gt; &amp;gt;&amp;gt; &lt;code&gt;podman-compose up&lt;/code&gt; will give some friendly(?) errors

&lt;ul&gt;
&lt;li&gt;In contrast, &lt;code&gt;docker-compose up&lt;/code&gt; &amp;gt;&amp;gt; &lt;code&gt;Ctrl+C&lt;/code&gt; &amp;gt;&amp;gt; &lt;code&gt;docker-compose up&lt;/code&gt; throws no error; also noticeably, logs  continue (just like &lt;code&gt;Ctrl+X&lt;/code&gt; &amp;gt;&amp;gt; &lt;code&gt;kill -CONT&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;So, is Podman better than Docker, or is Docker itself getting better than alternatives?&lt;/p&gt;

</description>
      <category>docker</category>
      <category>discuss</category>
      <category>devops</category>
      <category>podman</category>
    </item>
    <item>
      <title>Debugging in Rust</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Wed, 29 Sep 2021 05:03:32 +0000</pubDate>
      <link>https://forem.com/patarapolw/debugging-in-rust-2j6n</link>
      <guid>https://forem.com/patarapolw/debugging-in-rust-2j6n</guid>
      <description>&lt;p&gt;How do you go for debugging in Rust, without proprietary software, like CLion or IntelliJ Ultimate?&lt;/p&gt;

</description>
      <category>help</category>
      <category>rust</category>
      <category>debug</category>
      <category>discuss</category>
    </item>
    <item>
      <title>What are some Linux distros you spent significant time on?</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Tue, 28 Sep 2021 01:41:47 +0000</pubDate>
      <link>https://forem.com/patarapolw/what-are-some-linux-distros-you-spent-significant-time-on-1g40</link>
      <guid>https://forem.com/patarapolw/what-are-some-linux-distros-you-spent-significant-time-on-1g40</guid>
      <description>&lt;p&gt;Not counting distros you only tried off curiosity.&lt;/p&gt;

&lt;p&gt;Only the distro you used long enough that you see real problems.&lt;/p&gt;

&lt;p&gt;And what are the problems?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>linux</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Noticeable differences between podman and docker</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Thu, 23 Sep 2021 08:31:29 +0000</pubDate>
      <link>https://forem.com/patarapolw/noticeable-differences-between-podman-and-docker-1gf5</link>
      <guid>https://forem.com/patarapolw/noticeable-differences-between-podman-and-docker-1gf5</guid>
      <description>&lt;p&gt;Anyone used podman for a while should notice differences between podman and docker; especially rootless podman&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Permission issues on folder mounting?&lt;/li&gt;
&lt;li&gt;Subtle differences in command? (&lt;code&gt;podman-compose build db&lt;/code&gt; doesn't work)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;podman-compose down&lt;/code&gt; is required to kill pods.&lt;/li&gt;
&lt;li&gt;VSCode Docker extension doesn't work properly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in all, is it even worthy to switch to podman? Is extra security worth it? I am also not sure if the concept of pod is useful.&lt;/p&gt;

&lt;p&gt;Furthermore, &lt;a href="https://silverblue.fedoraproject.org/"&gt;Fedora Silverblue&lt;/a&gt; specifically uses &lt;code&gt;podman&lt;/code&gt;. (Preinstalled with podman, and the system is immutable.)&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>VSCode word wrap for very very long base64 image datauri? (Generate no more than 5 lines.)</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Wed, 01 Sep 2021 07:29:09 +0000</pubDate>
      <link>https://forem.com/patarapolw/vscode-word-wrap-for-very-very-long-base64-image-datauri-generate-no-more-than-5-lines-48lc</link>
      <guid>https://forem.com/patarapolw/vscode-word-wrap-for-very-very-long-base64-image-datauri-generate-no-more-than-5-lines-48lc</guid>
      <description>&lt;p&gt;Is this even possible? Limiting the markdown to enable internal base64 image datauri, and keeping sanity.&lt;/p&gt;

</description>
      <category>help</category>
      <category>vscode</category>
      <category>markdown</category>
    </item>
    <item>
      <title>How do you calculate 3^3^3^3? (What algo / struct?)</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Mon, 16 Aug 2021 03:22:40 +0000</pubDate>
      <link>https://forem.com/patarapolw/how-do-you-calculate-3-3-3-3-what-algo-struct-1847</link>
      <guid>https://forem.com/patarapolw/how-do-you-calculate-3-3-3-3-what-algo-struct-1847</guid>
      <description>&lt;p&gt;At first glance, it seems to be very straight forward. However, when you look at the sample calculation from Wolfram Alpha.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.wolframalpha.com/input/?i=3%5E3%5E3%5E3"&gt;https://www.wolframalpha.com/input/?i=3%5E3%5E3%5E3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This breaks both &lt;code&gt;long long&lt;/code&gt; (integer, 18-19 digits) and &lt;code&gt;double&lt;/code&gt; (float / IEEE 754, up to e+308 digits, with 17 digits' precision).&lt;/p&gt;

&lt;p&gt;However, I can cheat a little with Python, as it will automatically allocate more bytes for integer.&lt;/p&gt;

&lt;p&gt;Still, 3^(7.625e+13) takes abnormally very long time... (3^3^3 = 7.625e+13).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;MAX_LEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;exp3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tetrate3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&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="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exp3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_LEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_LEN&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="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&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="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;e+&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)"&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>help</category>
      <category>algorithms</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Does Google Docs really support non-English speakers? (Thai, specifically) And, any alternatives?</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Sun, 27 Jun 2021 10:25:17 +0000</pubDate>
      <link>https://forem.com/patarapolw/does-google-docs-really-support-non-english-speakers-thai-specifically-and-any-alternatives-31f4</link>
      <guid>https://forem.com/patarapolw/does-google-docs-really-support-non-english-speakers-thai-specifically-and-any-alternatives-31f4</guid>
      <description>&lt;p&gt;Something like, long word breaking... no, much longer than German words. AFAIK, auto-hyphenation is missing for some reasons.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--73VDiZRq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media.discordapp.net/attachments/712015468965134346/858645961516253184/unknown.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--73VDiZRq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media.discordapp.net/attachments/712015468965134346/858645961516253184/unknown.png" alt="Thai paragraph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Something like, language specific fonts. Sometimes, there are also be Above and Under.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aMV65l7A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1xbmpmmfdw5x3ghpewq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aMV65l7A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1xbmpmmfdw5x3ghpewq.png" alt="Complex fonts"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>help</category>
      <category>google</category>
      <category>googlesuite</category>
      <category>googledocs</category>
    </item>
    <item>
      <title>Please ELI5 what Parquet is for, and NOT for</title>
      <dc:creator>Pacharapol Withayasakpunt</dc:creator>
      <pubDate>Mon, 14 Jun 2021 00:14:55 +0000</pubDate>
      <link>https://forem.com/patarapolw/please-eli5-what-parquet-is-for-and-not-for-1o8c</link>
      <guid>https://forem.com/patarapolw/please-eli5-what-parquet-is-for-and-not-for-1o8c</guid>
      <description>&lt;p&gt;I am trying to understand how good is &lt;a href="https://parquet.apache.org/"&gt;Apache Parquet&lt;/a&gt; for&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data storage format (when you DO NOT have a Hadoop; only on your local computer)

&lt;ul&gt;
&lt;li&gt;How big is the size?&lt;/li&gt;
&lt;li&gt;How reliable is it?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Query-able format

&lt;ul&gt;
&lt;li&gt;Do I have to index first? (Probably unique indices are not possible?)&lt;/li&gt;
&lt;li&gt;Speed?&lt;/li&gt;
&lt;li&gt;Resource usage?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As far as I understand, Parquet may not be good for frequent writes or updates; but is it good enough for a &lt;strong&gt;static database&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;You can compare to the always popular SQLite, as a benchmark; disregarding SQLite features, such as foreign keys, unique indices, full text search and multiple tables.&lt;/p&gt;

&lt;p&gt;BTW, I have seen SQLite file size goes to 700 MB for a few megabytes for final CSV data, and not sure if it is &lt;a href="https://www.quora.com/What-are-the-problems-associated-with-using-SQLite-as-a-data-storage-and-sharing-format"&gt;reliable as a storage&lt;/a&gt; anymore...&lt;/p&gt;

</description>
      <category>explainlikeimfive</category>
      <category>datascience</category>
      <category>sqlite</category>
      <category>help</category>
    </item>
  </channel>
</rss>
