<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[MDWorld]]></title><description><![CDATA[MDWorld, a webdevelopment blog]]></description><link>https://mdworld.nl/mdworld-jackson/</link><image><url>https://mdworld.nl/mdworld-jackson//logos/logo-512.png</url><title>MDWorld</title><link>https://mdworld.nl/mdworld-jackson/</link></image><generator>GatsbyJS Material Starter</generator><lastBuildDate>Sat, 20 May 2023 19:02:03 GMT</lastBuildDate><atom:link href="https://mdworld.nl/mdworld-jackson//rss.xml" rel="self" type="application/rss+xml"/><author><![CDATA[M.D. van Es]]></author><copyright><![CDATA[MDWorld]]></copyright><item><title><![CDATA[Polymer 2 and Redux]]></title><description><![CDATA[The coming time I will be spending a lot of time developing in  Polymer 2.0 , so I've done some research and made a small project to test…]]></description><link>https://mdworld.nl/mdworld-jackson//polymer-2-and-redux</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//polymer-2-and-redux</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;p&gt;The coming time I will be spending a lot of time developing in &lt;a href=&quot;https://www.polymer-project.org/&quot;&gt;Polymer 2.0&lt;/a&gt;, so I&apos;ve done some research and made a small project to test some aspects of setting up a real-world application with it. It is in &lt;a href=&quot;https://github.com/mdvanes/polygram/&quot;&gt;this repo&lt;/a&gt;. It contains two basic elements (&lt;em&gt;polygram-searchbox&lt;/em&gt; and &lt;em&gt;polygram-details&lt;/em&gt;) that share state via Redux and also I&apos;ve separated the UI from the API with a container element (&lt;em&gt;polygram-ui-details&lt;/em&gt; vs &lt;em&gt;polygram-details&lt;/em&gt;). This separation of concerns simplifies reuse (I reuse &lt;em&gt;polygram-ui-details&lt;/em&gt; in &lt;em&gt;polygram-marvel-details&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Polymer CLI provides convenient utilities (project scaffolding, building), but the linter and WCT (web component tester) are lacking because they are too limited compared to e.g. ESLint and Karma and in fact it is &lt;a href=&quot;https://www.polymer-project.org/2.0/docs/tools/polymer-cli-commands#lint&quot;&gt;encouraged to use an separate linter&lt;/a&gt;. For that reason, I would have preferred that the Polymer linter would have been provided as an ESLint plugin.&lt;/p&gt;
&lt;p&gt;In the examples I use ES6 syntax without a transpiler, but I will soon have to investigate if bundling can be enriched with transpilation because I would at least like to try to use TypeScript. Of course we&apos;re losing the module imports (&lt;code class=&quot;language-text&quot;&gt;import x from &amp;#39;./x&amp;#39;&lt;/code&gt;) in favor of html imports of elements (&lt;code class=&quot;language-text&quot;&gt;&amp;lt;link rel=&amp;quot;import&amp;quot; href=&amp;quot;x.html&amp;quot;&amp;gt;&lt;/code&gt;). I think it&apos;s a loss, we finally have a standard for imports, why not stick to it?&lt;/p&gt;
&lt;p&gt;I would also still like to look at the possibility of adding &lt;a href=&quot;https://github.com/gaearon/redux-thunk&quot;&gt;Redux Thunk&lt;/a&gt; and/or &lt;a href=&quot;http://reactivex.io/rxjs/&quot;&gt;RxJS&lt;/a&gt; for async event handling. It seems that at least certain features of RxJS are already available in Polymer, e.g. &lt;em&gt;observers&lt;/em&gt; on properties and the &lt;em&gt;debounce&lt;/em&gt; attribute on &lt;a href=&quot;https://www.webcomponents.org/element/PolymerElements/iron-ajax&quot;&gt;iron-ajax&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On a side track I&apos;ve also done a small comparative case between Polymer and &lt;a href=&quot;https://html.spec.whatwg.org/multipage/custom-elements.html&quot;&gt;native web components&lt;/a&gt;, currently on version 1. This example is in the same repo, in the &lt;a href=&quot;https://github.com/mdvanes/polygram/tree/master/demo/HelloWorld&quot;&gt;HelloWorld demo&lt;/a&gt;. Polymer builds on web components and implements of component driven development&lt;/p&gt;
&lt;p&gt;So far the syntax is very similar, but Polymer is opinionated on certain design decisions (the HTML format, for instance) and adds some convience functions, and more importantly polyfills for wider support (see &lt;a href=&quot;https://www.webcomponents.org/polyfills/&quot;&gt;webcomponents-lite&lt;/a&gt;) and a &lt;a href=&quot;https://www.webcomponents.org/&quot;&gt;catalog&lt;/a&gt; of reusable web components.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dop SSD update]]></title><description><![CDATA[30-2-2015 I'm replacing the 128GB SSD (Samsung 840 pro) by a 500GB SSD (Samsung 850 EVO) so I have enough space to move the /home partition…]]></description><link>https://mdworld.nl/mdworld-jackson//dop-ssd-update</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//dop-ssd-update</guid><category><![CDATA[mypc]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;p&gt;30-2-2015&lt;/p&gt;
&lt;p&gt;I&apos;m replacing the 128GB SSD (Samsung 840 pro) by a 500GB SSD (Samsung 850 EVO) so I have enough space to move the /home partition to the SSD as well. I also had &lt;a href=&quot;../dop-wont-boot-and-usb-issues/&quot;&gt;the problem&lt;/a&gt; that suddenly my SSD is no longer booting, without using super grub disk, so I might solve this as well.&lt;/p&gt;
&lt;p&gt;Currently, I have the SSD with the boot and root partitions on it, a 320GB HDD with the /home (ext3) and swap partitions and a 1,5 TB HDD for storage. I will replace the SSD and the 320GB by the 500GB SSD.&lt;/p&gt;
&lt;p&gt;Booting a Ubuntu 13.04 live CD already gives some problems. Right after loading the desktop the system freezes. After multiple reboots it works normally. Using gparted to make exact copies of all partitions from the old SSD to the new SSD (just using copy/paste in gparted). I use a GPT partition table instead of msdos.&lt;/p&gt;
&lt;p&gt;Now I disconnect the old SSD and reboot with the super grub disk, like I was doing before. This boots as expected. No I try to fix the boot issue.&lt;/p&gt;
&lt;h2 id=&quot;making-bootable&quot;&gt;&lt;a href=&quot;#making-bootable&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Making bootable&lt;/h2&gt;
&lt;p&gt;After BIOS initialization the message &quot;no bootable partition found&quot; is displayed. Using F12 before boot to select the SSD manually doesn&apos;t work either, only super grub disk. I try to follow the official &lt;a href=&quot;https://help.ubuntu.com/community/Boot-Repair&quot;&gt;Boot Repair instructions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Following the second option &quot;install Boot-Repair in Ubuntu&quot; I first login to Ubuntu normally (still booting with super grub disk) to install boot-repair:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair &amp;amp;&amp;amp; boot-repair&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;But when I try to run it (&lt;code class=&quot;language-text&quot;&gt;boot-repair&lt;/code&gt; and selecting &quot;recommended repair&quot;) I get a message:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Please create a BIOS-Boot partition: (&amp;gt;1MB, unformatted filesystem, bios_grub flag). This can be performed by tools like gparted, then try again.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;So, let&apos;s follow these detailed instructions!&lt;/p&gt;
&lt;p&gt;The current situation is:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/dev/sdc1 fat32       249MiB    label EFI   flags msftdata
/dev/sdc2 ext4        118.98GiB             flags msftdata
/dev/sdc3 linux-swap   15.62GiB&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The fat32 partition was copied from the old SSD. I manually removed the fat32 partition and replaced it with an unformatted BIOS-boot partition and then I rebooted as instructed by gparted. Surprisingly, the partition still shows up as a fat32 partition so I select it and choose &gt; format &gt; cleared. Know the partion is listed as &quot;unknown&quot;.&lt;/p&gt;
&lt;p&gt;Setting the flag &quot;bios_grub&quot; gives this result for /dev/sdc1:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/dev/sdc1 unknown 249MiB, flags bios_grub&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I rerun boot-repair &gt; recommended repair, but get another error:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;The boot of your PC is in EFI mode, but no EFI partition was deteced. You may want to retry after creating a EFI partiiton (FAT32, 100~250MB, start of disk, boot flag). Do you want to continue.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;So I cancel and try to create the EFI partition from a part of the bios-boot partition with gparted:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/dev/sdc4 fat32      244Mib    label EFI   flags boot, esp
/dev/sdc1 unknown      5MiB                flags bios_grub
/dev/sdc2 ext4       118.98GiB             flags msftdata
/dev/sdc3 linux-swap  15.62GiB&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Now I close gparted and run boot-repair &gt; recommended repair for the third time, just to get this error again:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;The boot of your PC is in EFI mode, but no EFI partition was deteced. You may want to retry after creating a EFI partiiton (FAT32, 100~250MB, start of disk, boot flag). Do you want to continue.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Now I see no other choice then to continue and I get a progress window telling me that &quot;repair file systems sdb1 this may require several minutes&quot;. That&apos;s odd, because sdb1 is not the new ssd. Anyway, after 30 minutes of running, I cancelled it and rebooted. And of course it still doesn&apos;t work.&lt;/p&gt;
&lt;p&gt;Apparently this was all futile and I switch to the &lt;a href=&quot;(https://help.ubuntu.com/community/RecoveringUbuntuAfterInstallingWindows)&quot;&gt;non-graphical instructions to restore grub&lt;/a&gt;. Now I&apos;m trying:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sudo grub-install /dev/sdc&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;This is done instantly. After rebooting and using F12 to select the boot device, I can now select the new SSD partition and boot Ubuntu. Progress!&lt;/p&gt;
&lt;p&gt;Unfortunately, booting still requires me to select the correct drive manually. This should be easy, just go into the BIOS and change the boot order. But where the boot order is listed, only 2 devices show up: the 1,5TB HDD and the optical drive. After frantic searching in the BIOS and online, I realize something like this might be mentioned in the manual (it is a Gigabyte Z87-HD3 motherboard), and indeed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;go to BIOS, switch to classic mode &lt;/li&gt;
&lt;li&gt;go to tab BIOS features&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;now below boot order there is something like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DVD bbs priorities&lt;/li&gt;
&lt;li&gt;hard disk bbs priorities&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;click hard disk bbs priorities and here I can change the order.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now it boots directly into Ubuntu! It&apos;s using legacy boot and not EFI, but that&apos;s fine.&lt;/p&gt;
&lt;h2 id=&quot;moving-home&quot;&gt;&lt;a href=&quot;#moving-home&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Moving /home&lt;/h2&gt;
&lt;p&gt;Copying data from one disk to another is easy, but I want to change the formatting from ext3 to ext4 at the same time and of course it contains /home, so I need to update the mount point.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use gparted to create new partition on the new SSD:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/dev/sdc5 ext4 330.91GiB&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use rsync to copy from the old to the new partition. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The syntax is &lt;code class=&quot;language-text&quot;&gt;rsync --progress -a source dest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;from /dev/sda3 -&gt; /media/ubuntu/9af1dc04-72d9-43a9-a67c-c11f2118dfa6&lt;/li&gt;
&lt;li&gt;to /dev/sdc5 -&gt; /media/ubuntu/211c3ec1-1314-492d-946e-8cb3d24888a9&lt;/li&gt;
&lt;li&gt;so using &lt;code class=&quot;language-text&quot;&gt;rsync --progress -a /media/ubuntu/9af1dc04-72d9-43a9-a67c-c11f2118dfa6 /media/ubuntu/211c3ec1-1314-492d-946e-8cb3d24888a9&lt;/code&gt; (WARNING: this is a minor mistake because it creates a dir 9af1dc04-72d9-43a9-a67c-c11f2118dfa6 on the new drive, see below)&lt;/li&gt;
&lt;li&gt;I also run &lt;code class=&quot;language-text&quot;&gt;watch -n30 df --type=ext4 --type=ext3 -BG&lt;/code&gt; to have an indication of the progress&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I immediately see that plenty of dirs give the error &quot;rsync: open dir: permission denied&quot;, so I run the same instruction but with sudo. Now it runs much longer. In a couple of hours everything is copied. Running it again logs nothing copied, so it seems to have been successful.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now the reference of the /home mount point needs to be &lt;a href=&quot;https://help.ubuntu.com/community/Partitioning/Home/Moving&quot;&gt;fixed&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the contents of /media/ubuntu/1ea18a24-56eb-4a89-9f54-f9d547c88e35/etc/fstab list as (only relevant parts):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# / was on /dev/sda1 during installation
UUID=1ea18a24-56eb-4a89-9f54-f9d547c88e35 /       ext4   errors=remount-ro  0  1
# /home was on /dev/sdb3 during installation
UUID=9af1dc04-72d9-43a9-a67c-c11f2118dfa6 /home   ext3   defaults           0  2
# swap was on /dev/sdb2 during installation
UUID=079723eb-16f6-487f-b5bb-588d48ce0d55 none    swap   sw                 0  0&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;listing all UUID with &lt;code class=&quot;language-text&quot;&gt;sudo blkid&lt;/code&gt; (only relevant parts):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/dev/sda2: UUID=&amp;quot;079723eb-16f6-487f-b5bb-588d48ce0d55&amp;quot; TYPE=&amp;quot;swap&amp;quot;
/dev/sda3: UUID=&amp;quot;9af1dc04-72d9-43a9-a67c-c11f2118dfa6&amp;quot; SEC_TYPE=&amp;quot;ext2&amp;quot; TYPE=&amp;quot;ext3&amp;quot;
/dev/sdc2: UUID=&amp;quot;1ea18a24-56eb-4a89-9f54-f9d547c88e35&amp;quot; TYPE=&amp;quot;ext4&amp;quot;
/dev/sdc3: UUID=&amp;quot;fbac86d0-4f93-4d8e-a762-dda9c2a61105&amp;quot; TYPE=&amp;quot;swap&amp;quot;
/dev/sdc5: UUID=&amp;quot;211c3ec1-1314-492d-946e-8cb3d24888a9&amp;quot; TYPE=&amp;quot;ext4&amp;quot;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;changed fstab to (only relevant parts:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# / was on /dev/sdc2 after move to new SSD
UUID=1ea18a24-56eb-4a89-9f54-f9d547c88e35 /       ext4   errors=remount-ro 0  1
# /home was on /dev/sdc5 after move to new SSD
UUID=211c3ec1-1314-492d-946e-8cb3d24888a9 /home   ext4   defaults          0  2
# swap was on /dev/sdc3 after move to new SSD
UUID=fbac86d0-4f93-4d8e-a762-dda9c2a61105 none    swap   sw                0  0&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;after rebooting, login failed. Relogged with live CD and found that the /home was copied to a subdir of the new drive. Copied it to the main dir and rebooted. Login in worked normally and is very fast! (How fast? 30 seconds from pressing the power button to seeing the homepage in Firefox)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And finally, when removing the old HDD from the case, I accidentally broke off a system fan pin from the motherboard. The other system fan pins are too far away and the other system fan already died some time ago. Now the only fan is the CPU fan, but so far it seems to be managing with a coretemp of max. 35°C and a CPU temp of max 26°C.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Micro Frontends In A Nutshell]]></title><description><![CDATA[Micro Frontends In A Nutshell You may have heard of a Micro Frontends recently and felt it a bit difficult to grasp what exactly it is and…]]></description><link>https://mdworld.nl/mdworld-jackson//micro-frontends-in-a-nutshell</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//micro-frontends-in-a-nutshell</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;h1 id=&quot;micro-frontends-in-a-nutshell&quot;&gt;&lt;a href=&quot;#micro-frontends-in-a-nutshell&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Micro Frontends In A Nutshell&lt;/h1&gt;
&lt;p&gt;You may have heard of a Micro Frontends recently and felt it a bit difficult to grasp what exactly it is and if it is something you should get involved in. I&apos;ll try to give a summary of the what, why, how, and when of the current state. To provide a high-over summary, I&apos;ll also add some recommended reading if you would like to get more details.&lt;/p&gt;
&lt;h2 id=&quot;why-use-micro-frontends&quot;&gt;&lt;a href=&quot;#why-use-micro-frontends&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;em&gt;Why&lt;/em&gt; use Micro Frontends?&lt;/h2&gt;
&lt;p&gt;Do you have a very large front-end code-base? &lt;/p&gt;
&lt;p&gt;And by large, I&apos;m talking about 50+ developers in a dozen of teams or more, probably cross-department, working on the same code-base in some manner.
Do you have enterprise-scale continuous integration with e.g. GitLab, Bamboo running so many pipelines that the bottleneck is no longer a matter of adding more pods?
Do you employ configuration managers or an Ops department to make sure deployments won&apos;t affect each other too much?
Do you have considerable codebases in incompatible front-end stacks, e.g. because of a migration from AngularJS to Angular &gt;2?&lt;/p&gt;
&lt;p&gt;Then chances are you need to use Micro Frontends. Or actually, you most probably are &lt;em&gt;already&lt;/em&gt; using Micro Frontends.&lt;/p&gt;
&lt;h2 id=&quot;what-are-micro-frontends&quot;&gt;&lt;a href=&quot;#what-are-micro-frontends&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;em&gt;What&lt;/em&gt; are Micro Frontends?&lt;/h2&gt;
&lt;p&gt;How is it possible you would not know you are using Micro Frontends? And why are we just now hearing so much about them? The truth is that although the term is relatively new it actually covers &lt;strong&gt;any range of solutions to integrate a collection of smaller frontends into one application&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Similar to Micro Service architectures, Micro Frontends facilitate large codebases by breaking them up into manageable pieces. This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Technological stack across Micro Frontends in the same application may differ&lt;/li&gt;
&lt;li&gt;A Micro Frontend has a clear and concise purpose, following the SOLID principles&lt;/li&gt;
&lt;li&gt;Teams of developers maintain one or more Micro Frontend that are isolated in runtime from the rest of the code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The term is now popularized because of the advent of &lt;em&gt;Module Federation&lt;/em&gt; in Webpack 5. Webpack 5 has been released towards the end of 2020, but this new major release is taking some time to be integrated in relevant tooling, e.g. Nx and Ng CLI.&lt;/p&gt;
&lt;p&gt;Note that Micro Frontends (MFEs) are sometimes also referred to as &lt;em&gt;Micro Apps&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;how-do-you-build-micro-frontends&quot;&gt;&lt;a href=&quot;#how-do-you-build-micro-frontends&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;em&gt;How&lt;/em&gt; do you build Micro Frontends?&lt;/h2&gt;
&lt;p&gt;Since Micro Frontends as a concept are not new, some solutions that can be classified as Micro Frontends are ancient, considering the speed of development in the frontend ecosystem. Here are some of them, to give an idea of how broad Micro Frontends can be interpreted:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run several frontend applications on different URLs and cross refer them with plain &lt;strong&gt;hyperlinks&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Run several frontend applications on different URLs on the same page in &lt;strong&gt;iframes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Develop frontend components in separate teams and integrate them at build time to be deployed as a &lt;strong&gt;deployment monolith&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Use macro &lt;strong&gt;Web Components&lt;/strong&gt; as an abstraction layer for components&lt;/li&gt;
&lt;li&gt;Develop frontend components in separate teams and integrate them at runtime with &lt;strong&gt;Module Federation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I won&apos;t go into all the details about the pros and cons of each of these solutions. Instead I refer you to the recommended reading list below.&lt;/p&gt;
&lt;p&gt;Note that solutions can be combined: you can have a deployment monolith (that expects components that are all using the same stack) but wrap components in Web Components to provide an abstraction layer and use different stacks to produce the Web Components. Additionally, you can use Web Components in combination with Module Federation for instance if you are migrating towards Module Federation as a Micro Frontends solution.
Consider this schematic representation of a web application:&lt;/p&gt;
&lt;p&gt;&lt;simple-light-box img-path=&quot;/lightbox/mfe/page.svg&quot; img-title=&quot;Overview of a page&quot;&gt;&lt;/simple-light-box&gt;&lt;/p&gt;
&lt;p&gt;This could be implemented with different platforms like Angular and React by wrapping them in Web Components:&lt;/p&gt;
&lt;p&gt;&lt;simple-light-box img-path=&quot;/lightbox/mfe/web-components.svg&quot; img-title=&quot;Web Components&quot;&gt;&lt;/simple-light-box&gt;&lt;/p&gt;
&lt;p&gt;Module Federation is the newest solution and many libraries are still adapting to it. Last year, Nx 12 released with support for Webpack 5 and Module Federation. See a real working example here &lt;a href=&quot;https://code-star.github.io/nx-reference-shell/&quot;&gt;https://code-star.github.io/nx-reference-shell/&lt;/a&gt; or its source in &lt;a href=&quot;https://github.com/code-star/nx-reference&quot;&gt;https://github.com/code-star/nx-reference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Because Micro Frontends break up a codebase into smaller, more manageable fragments, they are often mentioned in combination with Monorepo solutions like Nx or yarn/npm workspaces. However, it is perfectly possible to implement Micro Frontends without monorepos!&lt;/p&gt;
&lt;h2 id=&quot;when-to-use-micro-frontends&quot;&gt;&lt;a href=&quot;#when-to-use-micro-frontends&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;em&gt;When&lt;/em&gt; to use Micro Frontends?&lt;/h2&gt;
&lt;p&gt;New technology inspires developers to experiment, but Micro Frontends and with that Module Federation are not worth the upkeep for small to medium applications. All-in solutions like Next or Gatsby are great fits for smaller applications and custom Angular applications, when well organized, scale very well up to enterprise level.&lt;/p&gt;
&lt;p&gt;However, no framework inherently supports older versions of itself. So if a big bang migration from AngularJS to Angular or any other framework for that matter, you&apos;ll end up with some kind of Micro Frontends solution. Plenty of enterprise codebases currently use some combination of hyperlinks and deployment monoliths.&lt;/p&gt;
&lt;p&gt;This could look like a bank that offers a set of public pages (e.g. the general home page, and the landing pages of its departments) referencing each other with hyperlinks and a protected monolith app with many components (e.g. checking account, subscriptions to bank products, investments on one page).&lt;/p&gt;
&lt;p&gt;&lt;simple-light-box img-path=&quot;/lightbox/mfe/hyperlinks-and-monolith.svg&quot; img-title=&quot;Hyperlinks and Monolith&quot;&gt;&lt;/simple-light-box&gt;&lt;/p&gt;
&lt;p&gt;Exploring Module Federation can be worth it if continuous integration is slowed down too much because of the large amounts of tests and compilation of all the involved components. But note that there are other approaches, such as using Nx monorepos with properly set up hierarchy and running only affected tests.&lt;/p&gt;
&lt;p&gt;Another reason to use Module Federation can be the need to support multiple frameworks. Compared to Web Components, Module Federation improves the runtime isolation of components while simultaneously reducing isolation of shared dependencies to reduce the overall footprint of the application.&lt;/p&gt;
&lt;p&gt;Compare to the diagram for the earlier example using macro Web Components, you can see that lodash, Angular and React are only loaded once, despite being used by multiple isolated components:&lt;/p&gt;
&lt;p&gt;&lt;simple-light-box img-path=&quot;/lightbox/mfe/module-federation.svg&quot; img-title=&quot;Module Federation&quot;&gt;&lt;/simple-light-box&gt;&lt;/p&gt;
&lt;h2 id=&quot;want-to-know-more&quot;&gt;&lt;a href=&quot;#want-to-know-more&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Want to know more?&lt;/h2&gt;
&lt;p&gt;If you want to know more about Micro Frontends, Module Federation or Monorepos, you can contact met at &lt;a href=&quot;https://twitter.com/mdworldNL&quot;&gt;@mdworldNL&lt;/a&gt; on Twitter. We have experience with enterprise frontend at all the major banks and many governmental departments in the Netherlands.&lt;/p&gt;
&lt;p&gt;When you want more background information as a developer, you can also read the articles provided below.&lt;/p&gt;
&lt;h2 id=&quot;recommended-in-depth-reading&quot;&gt;&lt;a href=&quot;#recommended-in-depth-reading&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Recommended in-depth reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Introduction to Micro Frontends: &lt;a href=&quot;https://micro-frontends.org/&quot;&gt;https://micro-frontends.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Introduction to Micro Frontends: &lt;a href=&quot;https://martinfowler.com/articles/micro-frontends.html&quot;&gt;https://martinfowler.com/articles/micro-frontends.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Angular Architects &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Micro Frontends introduction: &lt;a href=&quot;https://www.angulararchitects.io/en/aktuelles/a-software-architects-approach-towards/&quot;&gt;https://www.angulararchitects.io/en/aktuelles/a-software-architects-approach-towards/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Micro Frontends series: &lt;a href=&quot;https://www.angulararchitects.io/en/aktuelles/micro-apps-with-web-components-using-angular-elements/&quot;&gt;https://www.angulararchitects.io/en/aktuelles/micro-apps-with-web-components-using-angular-elements/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Module Federation series: &lt;a href=&quot;https://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-module-federation-in-webpack-5/&quot;&gt;https://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-module-federation-in-webpack-5/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;By my colleague Peter Eijgermans:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Micro Frontends by Example: &lt;a href=&quot;https://dzone.com/articles/micro-frontends-by-example-8&quot;&gt;https://dzone.com/articles/micro-frontends-by-example-8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;(Video) Micro Frontends: The What, the Why and the How by Peter Eijgermans &lt;a href=&quot;https://youtu.be/TWcoziCdPkE&quot;&gt;https://youtu.be/TWcoziCdPkE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[On Reactive]]></title><description><![CDATA[There are a lot of terms in webdevelopment that have some connection to the word "reactive". I found myself mixing them up, so I want to…]]></description><link>https://mdworld.nl/mdworld-jackson//on-reactive</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//on-reactive</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;style&gt;
.paradigm {
    background-color: #ffb525;
    color: black;
}
.language {
    background-color: #25ff7c;
    color: black;
}
.library {
    background-color: #2581ff;
    color: black;
}
&lt;/style&gt;
&lt;p&gt;There are a lot of terms in webdevelopment that have some connection to the word &quot;reactive&quot;. I found myself mixing them up, so I want to clarify it here. &lt;/p&gt;
&lt;p&gt;For the sake of simplicity I will classify libraries &amp;#x26; frameworks as a &quot;library&quot; and anything conceptual as a &quot;paradigm&quot;.&lt;/p&gt;
&lt;h2 id=&quot;reactive-programming&quot;&gt;&lt;a href=&quot;#reactive-programming&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Reactive Programming&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;paradigm&quot;&gt;paradigm&lt;/span&gt; | url: &lt;a href=&quot;http://www.reactivemanifesto.org&quot;&gt;http://www.reactivemanifesto.org&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;A modern software architecture that fits the current demand for real-time updates. Quote from the Reactive Manifesto: &quot;We want systems that are Responsive, Resilient, Elastic and Message Driven. ... Systems built as Reactive Systems are more flexible, loosely-coupled and scalable.&quot; This is all explained in great detail in the manifesto.&lt;/p&gt;
&lt;h2 id=&quot;functional-reactive-programming&quot;&gt;&lt;a href=&quot;#functional-reactive-programming&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Functional Reactive Programming&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;paradigm&quot;&gt;paradigm&lt;/span&gt; | &lt;a href=&quot;http://engineering.silk.co/post/80056130804/reactive-programming-in-javascript&quot;&gt;Read more&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Functional Reactive Programming (FRP) is a way to do reactive programming using concepts from functional programming, such as map, reduce and filter. &lt;a href=&quot;http://silk.co&quot;&gt;Silk&lt;/a&gt; explains FRP as &quot;[something that] allows us to declaratively set up bindings between data in different parts of our product that keep in sync automatically&quot;, making it a way to handle maintainability issues. In short, updating &quot;reactive&quot; variables will also update their values where used in the DOM. Silk has a reactive jQuery plugin which illustrates this quite elegantly. Taken from their site:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;var header = new Reactive(&amp;quot;initial string&amp;quot;);
$(&amp;quot;h1&amp;quot;).first().rText(header);

// Setting the reactive value now automatically updates
// the text contents of our header element:
header.set(&amp;quot;New Header Text!&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I feel this can be compared with two-way binding in JavaScript MVCs.&lt;/p&gt;
&lt;p&gt;Also Jafar Husain from Netflix, with 6 years of FRP experience, has an &lt;a href=&quot;https://www.youtube.com/watch?v=XRYN2xt11Ek&quot;&gt;interesting presentation&lt;/a&gt; bringing many of the concepts in this article together.&lt;/p&gt;
&lt;h2 id=&quot;react&quot;&gt;&lt;a href=&quot;#react&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;React&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;library&quot;&gt;library&lt;/span&gt; | url: &lt;a href=&quot;http://facebook.github.io/react/&quot;&gt;http://facebook.github.io/react/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Short version: Facebook&apos;s MVC implementation like Angular is Google&apos;s MVC implementation.&lt;/p&gt;
&lt;p&gt;Focused on the UI (the &quot;View&quot; in MVC). Used on Facebook.com and Instagram.com. Fast because of the use of a virtual DOM and it can be run server-side too.&lt;/p&gt;
&lt;p&gt;The use of JSX is optional. JSX is a syntax for using pseudo HTML in JavaScript, more or less like HTML templating. React offers the JSXTransformer library to enable JSX support in JavaScript.&lt;/p&gt;
&lt;h2 id=&quot;ractivejs&quot;&gt;&lt;a href=&quot;#ractivejs&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Ractive.js&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;library&quot;&gt;library&lt;/span&gt; | url: &lt;a href=&quot;http://www.ractivejs.org&quot;&gt;http://www.ractivejs.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Short version: A simpeler MVC than Angular.&lt;/p&gt;
&lt;p&gt;The learning curve of Angular is quite high. In contrast Ractive.js is designed to be as simple as possible. It was created at theguardian.com and it uses &lt;a href=&quot;https://github.com/janl/mustache.js&quot;&gt;Mustache templates&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These blog posts really goes in depth about Ractive.js &lt;a href=&quot;http://blog.ractivejs.org/posts/whats-the-difference-between-react-and-ractive/&quot;&gt;vs React&lt;/a&gt; and &lt;a href=&quot;http://blog.ractivejs.org/posts/whats-the-difference-between-angular-and-ractive/&quot;&gt;vs Angular&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;reactive-extensions-aka-rxjs&quot;&gt;&lt;a href=&quot;#reactive-extensions-aka-rxjs&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Reactive Extensions (a.k.a. RxJS)&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;library&quot;&gt;library&lt;/span&gt; | url: &lt;a href=&quot;http://reactive-extensions.github.io/RxJS/&quot;&gt;http://reactive-extensions.github.io/RxJS/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Short version: Observables + LINQ + Schedulers, Library for reactive programming in JS.&lt;/p&gt;
&lt;p&gt;Reactive extensions exist for several platforms and RxJs is the implementation for JavaScript. The RxJs is incredibly abstract:&lt;/p&gt;
&lt;p&gt;&quot;Using RxJs, developers represent asynchronous data streams with Observables, query asynchronous data streams using LINQ operators, and parameterize the concurrency in the asynchronous data streams using Schedulers.&quot;&lt;/p&gt;
&lt;p&gt;It is modeled after LINQ, which is part of Microsoft .NET and is used for native data querying.&lt;/p&gt;
&lt;p&gt;My understanding is that RxJs goes beyond Promises, because it combines Promises, callbacks, DOM input, web workers (threads in JS), and web sockets.&lt;/p&gt;
&lt;p&gt;For clarification I tried to find a compelling use case. In theory, this would be anything with events, no matter if it is drag &amp;#x26; drop or AJAX calls. An example from their site is an autocomplete that doesn&apos;t flood the backend with request because of the reactive programming paradigm. See the &lt;a href=&quot;http://jsfiddle.net/mattpodwysocki/AL8Mj/&quot;&gt;autocomplete example&lt;/a&gt; on the &lt;a href=&quot;https://github.com/Reactive-Extensions/RxJS/tree/master/examples&quot;&gt;RxJS examples pages&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;flapjax&quot;&gt;&lt;a href=&quot;#flapjax&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Flapjax&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;language&quot;&gt;language&lt;/span&gt; | url: &lt;a href=&quot;http://www.flapjax-lang.org&quot;&gt;http://www.flapjax-lang.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Short version: Functional Reactive Programming implementation in JavaScript&lt;/p&gt;
&lt;p&gt;It has been around since 2006, and the site looks really outdated. Fortunally, there are many such initiatives at the moment, in different stages of implementation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://baconjs.github.io/&quot;&gt;Bacon.js&lt;/a&gt; The site shows this simple example of a counter implemented with Bacon.js. It interprets the data as a stream of clicks on the up or down button:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;var up   = $(&amp;#39;#up&amp;#39;).asEventStream(&amp;#39;click&amp;#39;);
var down = $(&amp;#39;#down&amp;#39;).asEventStream(&amp;#39;click&amp;#39;);

var counter =
  // map up to 1, down to -1
  up.map(1).merge(down.map(-1))
  // accumulate sum
    .scan(0, function(x,y) { return x + y });

// assign observable value to jQuery property text
counter.assign($(&amp;#39;#counter&amp;#39;), &amp;#39;text&amp;#39;);&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://proactjs.github.io/&quot;&gt;ProAct.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pozadi.github.io/kefir/&quot;&gt;Kefir.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;functional-javascript&quot;&gt;&lt;a href=&quot;#functional-javascript&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Functional JavaScript&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;paradigm&quot;&gt;paradigm&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Short version: implementation of functional programming in JavaScript&lt;/p&gt;
&lt;p&gt;The idea is that functional programming should make larger projects easier to understand. Books have been written on why you should want this. &lt;a href=&quot;http://eloquentjavascript.net/1st_edition/chapter6.html&quot;&gt;Literally&lt;/a&gt;, &lt;a href=&quot;http://www.functionaljavascript.com/&quot;&gt;books&lt;/a&gt;. There is also a really neat node based &lt;a href=&quot;https://github.com/timoxley/functional-javascript-workshop&quot;&gt;workshop, by timoxley&lt;/a&gt;. This workshop uses no external libraries.&lt;/p&gt;
&lt;h2 id=&quot;lodash&quot;&gt;&lt;a href=&quot;#lodash&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;LoDash&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;library&quot;&gt;library&lt;/span&gt; | url: &lt;a href=&quot;https://lodash.com&quot;&gt;https://lodash.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;According to the site, it is a drop-in replacement for &lt;a href=&quot;http://underscorejs.org/&quot;&gt;Underscore&lt;/a&gt;. Both are libraries with helpers for functional programming. They add functions for typical FP concepts like e.g. map, reduce, and filter. According to the long list of features &quot;not in Underscore&quot; on the LoDash site, it might be considered the better alternative.&lt;/p&gt;
&lt;p&gt;Alternative libraries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://danieltao.com/lazy.js/&quot;&gt;Lazy.js&lt;/a&gt;, adding lazy evaluation. Actively under development.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://osteele.com/sources/javascript/functional/&quot;&gt;Functional Javascript&lt;/a&gt;, last updated in 2007.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;real-time-web&quot;&gt;&lt;a href=&quot;#real-time-web&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Real-time web&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;paradigm&quot;&gt;paradigm&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Short version: pushing information from the server to the client&lt;/p&gt;
&lt;p&gt;Any combination of libraries, technologies or practices that allow server-side push of information to the browser instead of relying on client-side polling. It&apos;s basically the new name for the &lt;a href=&quot;http://en.wikipedia.org/wiki/Comet_%28programming%29&quot;&gt;Comet&lt;/a&gt; model of programming. By far the most obvious example is &lt;a href=&quot;http://www.html5rocks.com/en/tutorials/websockets/basics/&quot;&gt;web sockets&lt;/a&gt;, which is &lt;a href=&quot;http://caniuse.com/#feat=websockets&quot;&gt;widely supported (e.g. IE 10+)&lt;/a&gt;. I made a &lt;a href=&quot;https://github.com/mdvanes/mdworld-stox&quot;&gt;demo for web sockets&lt;/a&gt; implemented in Node recently, but it is based on a earlier implementation in PHP that I did somewhere in March 2013. There are plenty of frameworks that make real-time web easier to develop with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.firebase.com/&quot;&gt;Firebase&lt;/a&gt;, web app framework that allows three-way binding when &lt;a href=&quot;https://www.firebase.com/docs/web/libraries/angular/index.html&quot;&gt;combined with e.g. Angular&lt;/a&gt;. This means it syncs database updates straight to the browser.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pusher.com&quot;&gt;Pusher&lt;/a&gt;, multi platform server side and client side library providing plenty of documentation for implementing common real-time applications, like push notification or a chat client. Provides standardized fallbacks for web sockets.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;responsiveadaptive-design&quot;&gt;&lt;a href=&quot;#responsiveadaptive-design&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Responsive/Adaptive design&lt;/h2&gt;
&lt;p&gt;type: &lt;span class=&quot;paradigm&quot;&gt;paradigm&lt;/span&gt; | &lt;a href=&quot;http://www.liquidapsive.com/&quot;&gt;Read more&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Short version: has nothing to do with reactive, but it sounds like it...&lt;/p&gt;
&lt;p&gt;I feel that I should mention this because the first time I heard about reactive, I assumed it classified as a design method, like responsive or adaptive design. It obviously has nothing to do with design, but to clarify:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;responsive design is a set of liquid designs, one for each breakpoint.&lt;/li&gt;
&lt;li&gt;adaptive design is a set of static designs, one for each breakpoint. E.g. the current design of mdworld.nl is adaptive. Try changing the window width from 700px to 900px, 1000px, 1300px, and 1700px.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[NBI Quickscan app]]></title><description><![CDATA[Handige tool voor financieel adviseurs om op eenvoudige wijze eventuele hiaten bloot te leggen.  In een oogopslag doorrekenen van de…]]></description><link>https://mdworld.nl/mdworld-jackson//nbi-quickscan-app</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//nbi-quickscan-app</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Handige tool voor financieel adviseurs om op eenvoudige wijze eventuele hiaten bloot te leggen. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In een oogopslag doorrekenen van de gebruikelijke scenario’s (langleven, kortleven, AO WW) op basis van besteedbaar inkomen. Op deze manier kan op een simpele en snelle manier een inzicht gegeven worden van het netto besteedbaar inkomen bij verschillende scenario’s.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bepalen van verzekeringsbehoefte bij verschillende gebeurtenissen (Woonlastenverzekering, ORV)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Voor vragen of opmerkingen ben ik bereikbaar via &lt;a href=&quot;https://twitter.com/mdworldnl&quot;&gt;Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please address any questions or remarks to my &lt;a href=&quot;https://twitter.com/mdworldnl&quot;&gt;Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is my first real privately produced Android app, although I&apos;ve worked on several apps through my employer before.&lt;/p&gt;
&lt;p&gt;The app was built with the &lt;a href=&quot;http://ionicframework.com/&quot;&gt;Ionic framework&lt;/a&gt; and contains many &lt;a href=&quot;http://karma-runner.github.io/&quot;&gt;Karma unit tests&lt;/a&gt; for the calculations. It also provided me with an interesting source of working with &lt;a href=&quot;http://gulpjs.com/&quot;&gt;Gulp&lt;/a&gt; and &lt;a href=&quot;https://cordova.apache.org/docs/en/dev/guide/appdev/hooks/&quot;&gt;Cordova hooks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/mdworld-jackson/static/nbi-quickscan-71a305a23e7302f9fbc7fc44e49df44d-98cad.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 360px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 177.77777777777777%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAkCAIAAAAGkY33AAAACXBIWXMAAA7DAAAOwwHHb6hkAAADaklEQVRIx6VVWU+TQRSdIiT0ASNGFKNIEB8Q2VIWfdSg4JtPgBCQRfZNQEEUaVlLRQhFXIhAIjEm+OKj/0GoiqhAYspSSlv2At1biqfflJaClFZvDpc7M/fM3HNnvpQQd8zT80hUZERoaIi//8mAgLMkKjYhMvYG53KiDVFxCWGc+IiY6+HR8eHRjOfER8ZYcqKv3ExKK76VlHstMflqQjK5X9/LFQym5fPTCwUZRYLUPH7hg+e9bz+1CYcE3R8o+MKh6oa+1LxW5CRlN6bcbUYMgPyihveqrKar/KEQQFD5uIfXNlDX8oYnGKjn93P5/RjWNvbSnHu13UB5rRAgGq0O0Or0dmj1KpVGrdbCqyxeu4khknSGPSBm8xawbd7eMfPWlgl/MMsS9ZZ/JszvATEajRKJZHh4eHx8XCQSTU5OqtVqlQuGNAt5c3NzdXVVqVSurKzAaw8zjUZDA5Rtr9gtA5FAGyJshsOXl5dxMgIMD+KgUrFYzHRkhwwBS0tL6+vrlAwhB52GfaemphzIJpOJafCWiTEnWmxLSLaSceDi4iIOVygU8/PzKMS5WgfyxsYGqsUFwMvlcnTy0IZZydjJYDDo9XrE6Afi/WWb95mdDI6OMQNjNNbvGGIk/J2MjVEw1KJgKIeH+IWFBUjAs8H9YYn2f3dFdjIuaW1tDR5kEFx5JHYylYpLgkd8kE6b7W0YOkw1U5G0f0749pNRs1QqhU6ZTIbKIRJD589+r2b6bbn4YThoRp3wkO0GmTaJvm36sI0uG9ndAOcd2m/Wsv/BHD4M+qogwW0ynif6jC3QdvQczXO1YYjwdHFV4CiV6yhBp9M6f2EwEMn2fxiZnVNI55d+/vr9eWR0dGxC9PXHyJexb98nxNOyqRnZ9Kyc+jnp4m5IpAszEjlJL2jOKGhOzW1IyeHeZpCU+SS/4ml9S19VXU/Fo+5q7svKup70/KYMJhMAJbOoNbuET7JKnwHZZR0MOnPKOu8Ut1fz+rpef2zqeN/Q/q5VOFQvGMwsaadpWaUdiPMquvKrhCQwONyGgKBLtuB0QAhwJvAig1A6j5jmnDsfBjj88HM4UWw2GwGLxYL38ztxITiILtGZuNgYf/9TtiFheXhQYMLX97inl5dlhRl6e7N9fI7SoWWGkGO+vt7YnWVl/QEzF7nP1YPb9QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;screenshot&quot;
        title=&quot;&quot;
        src=&quot;/mdworld-jackson/static/nbi-quickscan-71a305a23e7302f9fbc7fc44e49df44d-98cad.png&quot;
        srcset=&quot;/mdworld-jackson/static/nbi-quickscan-71a305a23e7302f9fbc7fc44e49df44d-db6ec.png 300w,
/mdworld-jackson/static/nbi-quickscan-71a305a23e7302f9fbc7fc44e49df44d-98cad.png 360w&quot;
        sizes=&quot;(max-width: 360px) 100vw, 360px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Elm for front-end developers]]></title><description><![CDATA[Elm for front-end developers - how we dove into Elm to rebuild part of our site. Why Elm? The benefits of  Elm  (no runtime errors, typing…]]></description><link>https://mdworld.nl/mdworld-jackson//elm-for-front-end-developers</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//elm-for-front-end-developers</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;p&gt;Elm for front-end developers - how we dove into Elm to rebuild part of our site.&lt;/p&gt;
&lt;h1 id=&quot;why-elm&quot;&gt;&lt;a href=&quot;#why-elm&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Why Elm?&lt;/h1&gt;
&lt;p&gt;The benefits of &lt;a href=&quot;http://elm-lang.org/&quot;&gt;Elm&lt;/a&gt; (no runtime errors, typing) is what makes it accessible to our back-end developers. They are used to the functional style of Scala and in general to a workflow with a compiler. &lt;/p&gt;
&lt;p&gt;On the other hand, this workflow is also what makes the learning curve enormously steep to front-end developers; if you are used to the front-end workflow, working with a compiler is very different. Back-end (e.g. Scala) developers iterate by writing code and seeing if it compiles. Because of (unpredictable) runtime errors and intransparent state in conventional front-end projects, front-end developers have another kind of iterative workflow: write a small bit of code, see what the result is in the browser. And this means leaving the IDE, navigating your app and opening your browser devtools.&lt;/p&gt;
&lt;p&gt;The popularisation of live reloaders and the emphasis on a fast build chain (linters, precompilers) originates from this workflow. Although ultimately developing in a strongly typed and compiled language will have less errors, it does require a different programming style.&lt;/p&gt;
&lt;p&gt;Besides adapting to this workflow, the functionally pure coding style is infamously difficult to grasp for the uninitiated (See &lt;a href=&quot;http://dave.fayr.am/posts/2011-08-19-lets-go-shopping.html&quot;&gt;Functional Programming Is Hard,
That&apos;s Why It&apos;s Good&lt;/a&gt;, also just Google “functional programming is difficult”). You think you are comfortable with functional concepts (e.g. immutable state, pure functions, higher order functions, currying) and operators (e.g. map, filter, reduce) in JavaScript? This will be of very little help in Elm, because it is not possible to combine functional style with an OO style (or to fall back to OO when you are completely lost).&lt;/p&gt;
&lt;p&gt;Objects have no meaning in Elm, Elm is a true functional language, like Haskell and Scheme. JavaScript on the other hand is flexible, multi-paradigm (&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript&quot;&gt;imperative, functional, prototype-based&lt;/a&gt;) and scales from development by absolute beginners to enterprise.&lt;/p&gt;
&lt;h2 id=&quot;immutability&quot;&gt;&lt;a href=&quot;#immutability&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Immutability&lt;/h2&gt;
&lt;p&gt;Take for instance immutability. In JavaScript (without libraries) the meaning of immutability is limited to the const keyword, which prevents you from reassigning to declared variables.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;foo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// prevented&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;It is still possible to change the contents of a constant however, with property reassignment.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;bar&apos;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// value of x is now {val: &apos;bar&apos;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://elmprogramming.com/immutability.html&quot;&gt;Immutability in Elm&lt;/a&gt; is much more invasive: there are no variables, only constants. Assignment can be written inline or take a chained style for clarity:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- inline&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;myVar&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;myVar&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello, &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;\&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- chained&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;myVar&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;myVar&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;\&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;toString&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;String.append&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello, &quot;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Note that the order is reversed to what you may expect in this chained notation, it reads from bottom to top.&lt;/p&gt;
&lt;p&gt;This is similar to chaining (functional) operators without storing intermediate state in JavaScript, e.g.:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; retweetAuthors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; listOfTweets
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tweet &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; tweet&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isRetweet&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tweet &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; tweet&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Although the order here is from top to bottom.&lt;/p&gt;
&lt;p&gt;If a value can be changed (e.g. by user input or server updates) you need to use “update” functions in Elm. These will update the entire or partial application state by creating a new state and updating the part of the model that is relevant for this event.
Example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;updateModel &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Msg &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; Model &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; Model
updateModel msg model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; msg &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;
       Name name &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
           &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; model &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Which means that in the case the message is “Name”, create a new “model” where model.name is set to the supplied name.&lt;/p&gt;
&lt;p&gt;An advantage is that over the course of use of the application a list of states is recorded, which enables time travel debugging (like in &lt;a href=&quot;https://github.com/reduxjs/redux-devtools&quot;&gt;this GIF&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This might look familiar if you have used &lt;a href=&quot;https://redux.js.org/&quot;&gt;Redux&lt;/a&gt;. Redux is partially &lt;a href=&quot;https://redux.js.org/introduction/prior-art#elm&quot;&gt;inspired by Elm&lt;/a&gt; and you might recognize the [dispatch, action] cycle in the way Elm updates the model. In that respect, it is is also similar to &lt;a href=&quot;http://reactivex.io/rxjs/manual/tutorial.html#state-stores&quot;&gt;state stores in RxJS&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; increase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Rx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Observable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fromEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;increaseButton&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// We map to a function that will increase the count&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Here you can see that a new state object is created, and only the count property is updated.&lt;/p&gt;
&lt;p&gt;Another familiar aspect of Elm is the use of &lt;a href=&quot;http://elmprogramming.com/virtual-dom.html&quot;&gt;Virtual DOM&lt;/a&gt;. Instead of manipulating the DOM directly, an in-memory representation of the UI (the virtual DOM) is modified, and that is synchronized to the real DOM. This improves performance dramatically and is one of &lt;a href=&quot;https://reactjs.org/docs/faq-internals.html&quot;&gt;the selling points of React&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With all of this in mind, we set out to rewrite &lt;a href=&quot;https://www.codestar.nl&quot;&gt;our company site&lt;/a&gt; in Elm. The current implementation of the site is outdated and has all content stored locally. We want to migrate to a &lt;a href=&quot;https://jamstack.org/&quot;&gt;JAMstack&lt;/a&gt; approach, with the content stored in cloud services (Youtube, Twitter, and photos in &lt;a href=&quot;https://cloudinary.com/&quot;&gt;Cloudinary&lt;/a&gt;) and to pull the data in through the respective APIs with Elm. The idea is that Elm should be more accessible to our Scala devs, while still providing a mature environment for our front-end devs so maintenance can be done by either.&lt;/p&gt;
&lt;p&gt;Of course, all devs try to dive right in and soon are discouraged when this approach does not seem to work here. So maybe let&apos;s read the Elm docs. There actually are quite a bit of docs. Maybe first finish the tutorials. Actually now I am even more confused…. &lt;/p&gt;
&lt;h1 id=&quot;toolchainworkflow&quot;&gt;&lt;a href=&quot;#toolchainworkflow&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Toolchain/workflow&lt;/h1&gt;
&lt;p&gt;No matter if it is Elm, &lt;a href=&quot;https://mdworld.nl/polymer-2-and-type-script&quot;&gt;Polymer&lt;/a&gt;, or any other New Solution that does not use ES6 modules, it means you can’t use the tools you are probably used to as a front-end developer, like ESLint. You are now at the mercy of the maturity of the ecosystem of the New Solution. Fortunately, it looks like Elm has a very active community and covers &lt;a href=&quot;https://www.elm-tutorial.org/en/04-starting/03-webpack-1.html&quot;&gt;Webpack integration&lt;/a&gt;, for instance, right in the documentation.&lt;/p&gt;
&lt;h2 id=&quot;elm-reactor-and-external-css&quot;&gt;&lt;a href=&quot;#elm-reactor-and-external-css&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Elm-reactor and external CSS&lt;/h2&gt;
&lt;p&gt;When starting out with Elm, you usually use elm-reactor to compile and serve Elm files. This offers a web interface that lets you navigate Elm files and when opening them serves them as HTML. Quite soon, you will find out that this presents a problem when you want to add external global resources, like CSS.
The Elm app served by elm-reactor is compiled to JavaScript and wrapped in an HTML. But you can’t specify what that HTML should look like, so you can’t add e.g.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;style.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;You can (and eventually will) create your own HTML and build with e.g. webpack, but there is an intermediate solution if you want to get to know Elm better first, while keeping the benefits of elm-reactor, such as live reloading and the time travel debugger. It is &lt;a href=&quot;https://github.com/elm-lang/elm-reactor/issues/199#issuecomment-279250207&quot;&gt;not very well documented&lt;/a&gt;, but you can create an HTML file that directly loads an Elm file. Elm-reactor will automatically compile and live update it. The HTML would contain:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;script type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt; 
    src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/_compile/app/src/Main.elm&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;script&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;script type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;runElmProgram&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;script&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;We did notice that local custom fonts that were added while serving this way were not loaded. Custom fonts from a CDN will probably work.&lt;/p&gt;
&lt;h2 id=&quot;webpack&quot;&gt;&lt;a href=&quot;#webpack&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Webpack&lt;/h2&gt;
&lt;p&gt;First I set up a Webpack config conforming to &lt;a href=&quot;https://www.elm-tutorial.org/en/04-starting/04-webpack-2.html&quot;&gt;this guide&lt;/a&gt;. Before, I loaded an image in my Elm code, but now this image gives a 404 when I use the webpack-dev-server. It is also not copied to /dist when building. Webpack does not seem to resolve the image as an asset, which is a &lt;a href=&quot;https://github.com/elm-community/elm-webpack-loader/issues/54&quot;&gt;known issue&lt;/a&gt;.
There are workarounds, like setting the image as a CSS background and have the image dependency resolved by the css-loader, but that does &lt;a href=&quot;https://mdworld.nl/polymer-2-and-type-script&quot;&gt;not conform to a11y guidelines&lt;/a&gt; for informative images.&lt;/p&gt;
&lt;p&gt;The suggested solution is to use &lt;a href=&quot;https://github.com/NoRedInk/elm-assets-loader&quot;&gt;elm-assets-loader&lt;/a&gt;. Additional to the instructions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I had to add ../ as a prefix to the image path&lt;/li&gt;
&lt;li&gt;It was helpful to run webpack instead of webpack-dev-server, it gave more informative errors&lt;/li&gt;
&lt;li&gt;I had to remove this line from the webpack config: &lt;code class=&quot;language-text&quot;&gt;noParse: /\.elm$/,&lt;/code&gt; because it failed on an SVG import without a compile error, but with a runtime error: &quot;Uncaught ReferenceError: require is not defined&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This last issue arose because it &lt;a href=&quot;https://github.com/elm-community/elm-webpack-loader#noparse&quot;&gt;is suggested in elm-webpack-loader&lt;/a&gt; to set &lt;code class=&quot;language-text&quot;&gt;noParse: /\.elm$/,&lt;/code&gt; conflicting with elm-css-webpack-loader, which I added later.&lt;/p&gt;
&lt;p&gt;The cause of the error and the workaround to set &lt;code class=&quot;language-text&quot;&gt;noParse: /^((?!Stylesheet).)*\.elm.*$/,&lt;/code&gt; instead, is explained in &lt;a href=&quot;https://github.com/tcoopman/elm-css-webpack-loader&quot;&gt;elm-css-webpack-loader&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;getting-the-debugger-back&quot;&gt;&lt;a href=&quot;#getting-the-debugger-back&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Getting the debugger back&lt;/h1&gt;
&lt;p&gt;When using Webpack, you don&apos;t use elm-reactor so you don’t have the time travel debugger. This seems obvious: there is no Elm code anymore, it has been compiled to JS. It is very difficult to find documentation that mentions this. However, when using &lt;a href=&quot;https://github.com/elm-community/elm-webpack-starter&quot;&gt;elm-webpack-starter&lt;/a&gt; it actually runs with the debugger!&lt;/p&gt;
&lt;p&gt;It seems this is actually an option for the elm-webpack-loader in the webpack.config.js. First we used this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;#39;elm-webpack-loader?verbose=true&amp;amp;warn=true&amp;#39;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Which is equivalent to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   loader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &apos;elm-webpack-loader&apos;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
       verbose&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
       warn&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;And here the option &quot;debug&quot; can be added:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   loader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &apos;elm-webpack-loader&apos;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
       verbose&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
       warn&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
       debug&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I had trouble finding this option, because I had looked at the &lt;a href=&quot;https://github.com/elm-community/elm-webpack-loader&quot;&gt;elm-webpack-loader readme&lt;/a&gt;, but I searched for “debug” in the readme, and there is actually only a reference to all the options &lt;a href=&quot;https://github.com/rtfeldman/node-elm-compiler/blob/3fde73d/index.js#L12-L23&quot;&gt;in the source&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;unit-tests&quot;&gt;&lt;a href=&quot;#unit-tests&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Unit tests&lt;/h1&gt;
&lt;p&gt;We set up unit tests (see test/Assets.elm) and modified the npm tasks such that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Postinstall runs elm package install for / and also for /tests/&lt;/li&gt;
&lt;li&gt;The new task &lt;code class=&quot;language-text&quot;&gt;npm format-validate&lt;/code&gt; validates /app/src and /tests/*.elm (as a quick way of excluding /tests/elm-stuff)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;npm test&lt;/code&gt; runs &lt;code class=&quot;language-text&quot;&gt;format-validate&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;elm-test&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;npm run build&lt;/code&gt; first runs &lt;code class=&quot;language-text&quot;&gt;npm test&lt;/code&gt; and then starts webpack-dev-server&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;speeding-up-the-build-on-travis&quot;&gt;&lt;a href=&quot;#speeding-up-the-build-on-travis&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Speeding up the build on Travis&lt;/h1&gt;
&lt;p&gt;After adding a unit test (i.e. elm-test) the build speed is taking over 45 minutes on Travis CI.
One suggestion is to &lt;a href=&quot;https://8thlight.com/blog/rob-looby/2016/04/07/caching-elm-builds-on-travis-ci.html&quot;&gt;cache the elm artifacts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Add this to travis.yml:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-yml&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;cache:
  directories:
    - elm-stuff/build-artifacts
    - tests/elm-stuff/build-artifacts&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The first build after adding this should be still slow, because the build-artifacts will have to be cached, but the second build should be faster:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;build #23 (first build with cache on): 46 minutes 48 seconds&lt;/li&gt;
&lt;li&gt;build #24: 5 minutes 53 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So it is worth the trouble!&lt;/p&gt;
&lt;p&gt;It would be possible to cache &lt;code class=&quot;language-text&quot;&gt;elm-stuff&lt;/code&gt; (where Elm dependencies are installed) instead of &lt;code class=&quot;language-text&quot;&gt;elm-stuff/build-artifacts&lt;/code&gt;, but this would require manually clearing the cache when new Elm dependencies are added.&lt;/p&gt;
&lt;h1 id=&quot;combining-several-components-in-one-elm-app&quot;&gt;&lt;a href=&quot;#combining-several-components-in-one-elm-app&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Combining several components in one Elm app&lt;/h1&gt;
&lt;p&gt;We started out with several proofs of concept, so we have a separate TwitterFeed app and DiceRoller app that need to be integrated into the site app.
I’ve followed my refactoring attempt (for splitting up one huge Elm file) that I did in &lt;a href=&quot;https://github.com/mdvanes/elmsta/tree/refactoring&quot;&gt;my first Elm experiment&lt;/a&gt;, which helped integrating the models and update functions.&lt;/p&gt;
&lt;p&gt;The TwitterFeed has an initial Cmd. This must somehow be called by the initial Cmd of the main page app.&lt;/p&gt;
&lt;p&gt;This is the init of the Model and Cmd of the main page app. The TwitterFeed model has been added, but the initial Cmd is still &quot;none&quot;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Cmd&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Msg&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Elm&quot;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;Material.model&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;initialDiceRoller&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;TwitterFeed.State.initialModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;Cmd.none&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I want a custom init cmd to be called:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Cmd&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Msg&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Elm&quot;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;Material.model&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;initialDiceRoller&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;TwitterFeed.State.initialModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;initCmd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;On init, I want to call a service to get Twitter messages. In the standalone TwitterFeed app this looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;initTwitterFeedCmd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Cmd&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;TwitterFeedMsg&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;initTwitterFeedCmd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
   &lt;span class=&quot;token hvariable&quot;&gt;Task.attempt&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;NewTweets&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fetchTweets&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;It is not possible to create an initCmd in the main page app that calls initTwitterFeedCmd directly:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;initCmd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Cmd&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Msg&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;initCmd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
   &lt;span class=&quot;token hvariable&quot;&gt;initTwitterFeedCmd&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Because initTwitterFeedCmd is of the type Cmd TwitterFeedMsg. However, after adding TwitterFeedMsg to the union type for Msg, i.e.:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Msg&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Mdl&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Material.Msg&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Msg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MsgForDiceRoller&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;DiceRollerMsg&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MsgForTwitterFeed&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;TwitterFeedMsg&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Then it is possible to map from Cmd TwitterFeedMsg to Cmd Msg:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-elm&quot;&gt;&lt;code class=&quot;language-elm&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;initCmd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Cmd&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Msg&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;initCmd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
   &lt;span class=&quot;token hvariable&quot;&gt;initTwitterFeedCmd&lt;/span&gt;
       &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;Cmd.map&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MsgForTwitterFeed&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In the end we simply do not have a strong enough use case for Elm. There is too little state to manage and interaction between components. The TwitterFeed component does have state for instance, but it is so straight forward that Elm offers no advantage over JavaScript alternatives like RxJS state stores
or Redux. In this sense Elm would be a good fit for an advanced web app or component with UI controls or complex logic. &lt;/p&gt;
&lt;p&gt;Also the steep learning curve for most developers remains, and although this was anticipated for front-end developers it proves more challenging to Scala devs than we first thought.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Fronteers 2014: CSS]]></title><description><![CDATA[After my visit to Fronteers 2014 I was surprised to see that the proportion of strictly development related talks seemed lower compared to…]]></description><link>https://mdworld.nl/mdworld-jackson//fronteers-2014-css</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//fronteers-2014-css</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;style rel=&quot;stylesheet&quot;&gt;
.pad &gt; div {
    display: inline-block;
    vertical-align: middle;
}

.pad pre {
    margin: 0 10px;
}

.pad .pad-out,
.pad .pad-in {
    background: #267826;
    padding: 20px;
    height: 80px;
    width: 80px;
}
.pad .pad-in {    
    box-sizing: border-box; /* exception */
}
.pad .pad-out {
    margin-right: 20px;
    box-sizing: content-box; /* default */
}
.pad span {
    background-color: white;
    /* css checkerboard: http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/ 
    uses overlaying multiple backgrounds with triangles to simulate squares
    squares will be 20x20
    */
    background-image:
      linear-gradient(-45deg, #303030 25%, transparent 25%), 
      linear-gradient(-135deg, #303030 25%, transparent 25%),
      linear-gradient(-45deg, transparent 75%, #303030 75%),
      linear-gradient(-135deg, transparent 75%, #303030 75%);
    background-size: 40px 40px;
    background-position:0 0, 20px 0, 20px -20px, 0px 20px;
    display: block;
    height: 100%;
    width: 100%;
}

.pad .pad-simple {
    background-color: #267826;
    height: 80px;
    padding: 20px;
    width: 80px;
}
.pad .css pre {
    background-color: transparent;
    border: none;
    color: white;
}
.pad .css label {
    font-family: monospace;
    font-size: 13px;
    font-weight: normal;
}



.float-test .float-box {
    background: white;
    display: inline-block;
    height: 100px;
    margin-right: 5px;
    vertical-align: top;
    width: 150px;
}
.float-test i, .float-test b {
    background-color: #636363;
    border: 1px solid white;
    display: block;
    font-size: 40px;
    height: 48px;
    text-align: center;
    width: 48px;
}
.float-test b {
    background-color: #267826;
}
.float-test .float-box-left i,
.float-test .float-box-left b {
    float: left;
}
.float-test .float-box-right i,
.float-test .float-box-right b {
    float: right;
}
.float-test-inline {
    display: inline-block;
    margin-right: 10px;
    vertical-align: top;
}

&lt;/style&gt;
&lt;p&gt;After my visit to Fronteers 2014 I was surprised to see that the proportion of strictly development related talks seemed lower compared to previous years. Although most talks were of the highest quality, there were quite some talks about &lt;a href=&quot;https://fronteers.nl/congres/2014/sessions/meri-williams-using-agile-to-bake-in-accessibility&quot;&gt;management&lt;/a&gt;, &lt;a href=&quot;https://fronteers.nl/congres/2014/sessions/daniel-espeset-making-maps-the-role-of-frontend-infrastructure-at-etsy&quot;&gt;infrastructure&lt;/a&gt;, &lt;a href=&quot;https://fronteers.nl/congres/2014/sessions/petro-salema-dream-big-think-small&quot;&gt;etc&lt;/a&gt;. Great talks, just not applicable to my work.&lt;/p&gt;
&lt;p&gt;In fact, I was secretly hoping for some new tools (e.g. &lt;a href=&quot;https://github.com/google/traceur-compiler&quot;&gt;Traceur&lt;/a&gt;) or maybe &lt;a href=&quot;../on-reactive/&quot;&gt;FRP Javascript&lt;/a&gt;. I was introduced to both Sass and Grunt at Fronteers once, and they changed my life!&lt;/p&gt;
&lt;p&gt;Also, no talk on CSS by Lea Verou this year, but there was a very interesting talk about &lt;a href=&quot;https://fronteers.nl/congres/2014/sessions/rachel-nabors-state-of-the-animation-2014&quot;&gt;CSS Animation&lt;/a&gt; by Rachel Nabors. I can recommend watching the presentation, but I don&apos;t want to go deeper into CSS animations here.&lt;/p&gt;
&lt;h2 id=&quot;icon-font&quot;&gt;&lt;a href=&quot;#icon-font&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Icon Font&lt;/h2&gt;
&lt;p&gt;The talk about the Etsy Infrastructure did give me the idea to build a custom icon font for a client that required a lot of custom icons in their web app. Because these are all flat icons, it was possible to use an icon font (considering that you&apos;re basically stuck with 1 color per glyph). Unfortunately, the source has a closed license, but I can give the generic outlines of my approach.&lt;/p&gt;
&lt;p&gt;The core is the Grunt module &lt;a href=&quot;https://github.com/twolfson/grunt-fontsmith&quot;&gt;grunt-fontsmith&lt;/a&gt;, the documentation is a bit sparse, but in the end I used a simple configuration to convert my directory of SVGs to font files and a JSON file with the mapping from icon name to a unicode character. This unicode character can be used to reference the icon in the CSS, exactly like e.g. &lt;a href=&quot;http://glyphicons.com&quot;&gt;Glyphicons&lt;/a&gt; does. Although grunt-fontsmith can generate SCSS (and CSS, Less, stylus), I eventually opted not to use it. Instead I wrote a small Node script that converts the JSON directly into an SCSS file with the class names that I need, and also sorts all of the variables and class names alphabetically (which grunt-fontsmith can&apos;t do for as far as I know).&lt;/p&gt;
&lt;p&gt;Also, I patched grunt-fontsmith to have a significantly higher timeout when generating the fonts. It uses PhantomJS to call the Icomoon font generator in the browser (although I have my reservations about this approach, I don&apos;t have the time to do it better, so I&apos;ll kindly shut up). In my case this might take up to 15 seconds, which is not a problem, because I only run it when an icon is added. Unfortunately the internal timeout in grunt-fontsmith is lower, so I changed it in &lt;code class=&quot;language-text&quot;&gt;grunt-fontsmith/node_modules/fontsmith/node_modules/icomoon-phantomjs/lib/icomoon-phantom.js&lt;/code&gt;, in the function &lt;code class=&quot;language-text&quot;&gt;waitFor(checkFn, timeout, cb)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;basic-css&quot;&gt;&lt;a href=&quot;#basic-css&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Basic CSS&lt;/h2&gt;
&lt;p&gt;At the end of the talk by Nathan Ford about &lt;a href=&quot;https://fronteers.nl/congres/2014/sessions/nathan-ford-do-we-need-to-write-markup&quot;&gt;Markup&lt;/a&gt;, he includes two examples of basic CSS that I thought where quite clever to have a visual representation of. It seems to clarify much more than the written documentation. I&apos;ve elaborated on these examples and made two demos that I will use for teaching and personal reference.&lt;/p&gt;
&lt;h3 id=&quot;visual-representation-of-the-css-feature-box-sizing&quot;&gt;&lt;a href=&quot;#visual-representation-of-the-css-feature-box-sizing&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Visual Representation of the CSS feature box-sizing&lt;/h3&gt;
&lt;p&gt;Chrome, Firefox, and IE8+ all support the feature box-sizing. The value padding-box for this property is only supported in Firefox, so I will leave it out of scope for this demo. Border-box is the boxmodel IE uses in quirks mode.&lt;/p&gt;
&lt;p&gt;Below are two divs. Both divs have the same height, width, and padding.&lt;/p&gt;
&lt;p&gt;By default (content-box), the padding is not included in the box height/width. Height/width is set on the content of the box. The div is 80 + (2*20)px wide.&lt;/p&gt;
&lt;p&gt;When using border-box, the padding and border are included in the box height/width. Height/width is set on the border of the box, and the border is outside the padding. Margin is still added to the box height/width. &lt;/p&gt;
&lt;div class=&quot;pad&quot;&gt;
    &lt;div&gt;
        &lt;pre&gt;
.pad-out {
  /* default */
  box-sizing: content-box; 
  height: 80px;
  width: 80px;
  padding: 20px;
}
        &lt;/pre&gt;
    &lt;/div&gt;
    &lt;div class=&quot;pad-out&quot;&gt;
        &lt;span&gt;&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;pad-in&quot;&gt;
        &lt;span&gt;&lt;/span&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;pre&gt;
.pad-in {
  /* exception */
  box-sizing: border-box; 
  height: 80px;
  width: 80px;
  padding: 20px;
}
        &lt;/pre&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The checkerboard pattern is a div with 100% height and width. The squares are exactly 20px x 20px. It&apos;s purpose is to show the relative dimensions between the two boxes.&lt;/p&gt;
&lt;p&gt;Compare also these minimal examples of a div, one with border-box and one with content-box box-sizing.&lt;/p&gt;
&lt;div class=&quot;pad&quot;&gt;
    &lt;div style=&quot;height: 130px; width: 130px;&quot;&gt;
&lt;div class=&quot;pad-simple&quot; style=&quot;box-sizing: content-box;&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;css&quot;&gt;
&lt;pre style=&quot;color: black&quot;&gt;.pad-simple {
   box-sizing: content-box;
   height: 80px;
   width: 80px;
   padding: 20px;
}&lt;/pre&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;pad&quot;&gt;
    &lt;div style=&quot;height: 130px; width: 130px;&quot;&gt;
&lt;div class=&quot;pad-simple&quot; style=&quot;box-sizing: border-box;&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;css&quot;&gt;
&lt;pre style=&quot;color: black&quot;&gt;.pad-simple {
   box-sizing: border-box;
   height: 80px;
   width: 80px;
   padding: 20px;
}&lt;/pre&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Sources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/artequalswork/do-we-need-to-write-markup&quot;&gt;https://speakerdeck.com/artequalswork/do-we-need-to-write-markup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing#Browser_compatibility&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing#Browser_compatibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/box_model&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/box_model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Checkerboard: &lt;a href=&quot;http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/&quot;&gt;http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;visual-representation-of-the-css-features-float-and-clear&quot;&gt;&lt;a href=&quot;#visual-representation-of-the-css-features-float-and-clear&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Visual Representation of the CSS features float and clear&lt;/h3&gt;
&lt;p&gt;I have often used the CSS properties &lt;code class=&quot;language-text&quot;&gt;float&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;clear&lt;/code&gt;, but mostly just for putting two block elements inline. This means I usually stick with &lt;code class=&quot;language-text&quot;&gt;float: left&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;clear: both&lt;/code&gt;. Now, I would rather use &lt;code class=&quot;language-text&quot;&gt;display: inline-block&lt;/code&gt;. But how exactly do floats and clear work? I will show some examples.&lt;/p&gt;
&lt;p&gt;For all the following examples, the numbers indicate the order of the blocks in the HTML.&lt;/p&gt;
&lt;p&gt;All elements float left, but the green element clears left. Clear both would have the same result, because &lt;code class=&quot;language-text&quot;&gt;left&lt;/code&gt; is included in &lt;code class=&quot;language-text&quot;&gt;both&lt;/code&gt;. The blocks are essentially broken off to the next line at the green element.&lt;/p&gt;
&lt;pre class=&quot;float-test-inline&quot;&gt;
float: left;
float: left;
float: left; clear:left;
&lt;/pre&gt;
&lt;div class=&quot;float-test float-test-inline&quot;&gt;
    &lt;div class=&quot;float-box float-box-left&quot;&gt;
        &lt;i&gt;1&lt;/i&gt;
        &lt;i&gt;2&lt;/i&gt;
        &lt;b style=&quot;clear: left;&quot;&gt;3&lt;/b&gt;
    &lt;/div&gt;
    &lt;div class=&quot;float-box float-box-left&quot;&gt;
        &lt;i&gt;1&lt;/i&gt;
        &lt;b style=&quot;clear: left;&quot;&gt;2&lt;/b&gt;
        &lt;i&gt;3&lt;/i&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;All float left, but green clears none (default). No elements are broken off to the next line, although they can still break off if they exceed the width of the parent element.&lt;/p&gt;
&lt;div class=&quot;float-test float-test-inline&quot;&gt;
    &lt;div class=&quot;float-box float-box-left&quot;&gt;
        &lt;i&gt;1&lt;/i&gt;
        &lt;i&gt;2&lt;/i&gt;
        &lt;b style=&quot;clear: none;&quot;&gt;3&lt;/b&gt;
    &lt;/div&gt;
    &lt;div class=&quot;float-box float-box-left&quot;&gt;
        &lt;i&gt;1&lt;/i&gt;
        &lt;b style=&quot;clear: none;&quot;&gt;2&lt;/b&gt;
        &lt;i&gt;3&lt;/i&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;float-test-inline&quot;&gt;
float: left;
float: left; clear: none;
float: left;
&lt;/pre&gt;
&lt;p&gt;All float right, but green clears right. Again, clear both has the same effect, because &lt;code class=&quot;language-text&quot;&gt;right&lt;/code&gt; is included in &lt;code class=&quot;language-text&quot;&gt;both&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;float-test-inline&quot;&gt;
float: right;
float: right;
float: right; clear: right;
&lt;/pre&gt;
&lt;div class=&quot;float-test float-test-inline&quot;&gt;
    &lt;div class=&quot;float-box float-box-right&quot;&gt;
        &lt;i&gt;1&lt;/i&gt;
        &lt;i&gt;2&lt;/i&gt;
        &lt;b style=&quot;clear: right;&quot;&gt;3&lt;/b&gt;
    &lt;/div&gt;
    &lt;div class=&quot;float-box float-box-right&quot;&gt;
        &lt;i&gt;1&lt;/i&gt;
        &lt;b style=&quot;clear: right;&quot;&gt;2&lt;/b&gt;
        &lt;i&gt;3&lt;/i&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Element 1 and 3 float left. Element 2 floats right. Element 3 explicitly clears none. The other two elements implicitly clear none, because it&apos;s the default. Clear none is only to override elements that are set to clear left, right or both.&lt;/p&gt;
&lt;div class=&quot;float-test float-test-inline&quot;&gt;
    &lt;div class=&quot;float-box&quot;&gt;
        &lt;i style=&quot;float: left;&quot;&gt;1&lt;/i&gt;
        &lt;i style=&quot;float: right;&quot;&gt;2&lt;/i&gt;
        &lt;b style=&quot;float: left; clear: none;&quot;&gt;3&lt;/b&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;float-test-inline&quot;&gt;
float: left;
float: right;
float: left; clear: none;
&lt;/pre&gt;
&lt;p&gt;Like the previous example, both element 1 and 3 float left. Element 2 floats right. This time, element 3 clears left.&lt;/p&gt;
&lt;div class=&quot;float-test float-test-inline&quot;&gt;
    &lt;div class=&quot;float-box&quot;&gt;
        &lt;i style=&quot;float: left;&quot;&gt;1&lt;/i&gt;
        &lt;i style=&quot;float: right;&quot;&gt;2&lt;/i&gt;
        &lt;b style=&quot;float: left; clear: left;&quot;&gt;3&lt;/b&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;float-test-inline&quot;&gt;
float: left;
float: right;
float: left; clear: left;
&lt;/pre&gt;
&lt;p&gt;These examples might come in handy for reference. The next post will be a linkdump of interesting subjects/tools from Fronteers 2014.&lt;/p&gt;
&lt;script&gt;

    //document.querySelectorAll(&apos;[name=toggle-pad-simple][value=border]&apos;).closest(&apos;label&apos;).css({
    //        &apos;text-decoration&apos;: &apos;line-through&apos;
    //});

    // const toggleButtons = document.querySelectorAll(&apos;[name=toggle-pad-simple]&apos;)
    // for(button of toggleButtons) {
    //   console.log(button);
    // }
    // .click(function() {
    //     $(&apos;[name=toggle-pad-simple]&apos;).closest(&apos;label&apos;).css({
    //         &apos;text-decoration&apos;: &apos;line-through&apos;
    //     });
    //     $(this).closest(&apos;label&apos;).css({
    //         &apos;text-decoration&apos;: &apos;none&apos;
    //     });
    //     if($(this).val()===&apos;border&apos;) {
    //         $(&apos;.pad-simple&apos;).css(&apos;box-sizing&apos;,&apos;border-box&apos;);
    //     } else {
    //         $(&apos;.pad-simple&apos;).css(&apos;box-sizing&apos;,&apos;content-box&apos;);
    //     }
    // });
&lt;/script&gt;</content:encoded></item><item><title><![CDATA[Discourse on Ubuntu 14.04]]></title><description><![CDATA[I wanted to try and use  Docker  after hearing such great things about it. Since I might want to roll out a decent forum at some point, I…]]></description><link>https://mdworld.nl/mdworld-jackson//discourse-on-ubuntu-14-04</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//discourse-on-ubuntu-14-04</guid><category><![CDATA[mypc]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;p&gt;I wanted to try and use &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt; after hearing such great things about it. Since I might want to roll out a decent forum at some point, I wanted to look into installing &lt;a href=&quot;http://www.discourse.org/&quot;&gt;Discourse&lt;/a&gt;. For the moment, this will be done on my desktop.&lt;/p&gt;
&lt;p&gt;I start with the &lt;a href=&quot;http://docs.docker.com/installation/ubuntulinux/&quot;&gt;installation instructions&lt;/a&gt; for Docker on Ubuntu 14.04.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For Discourse it&apos;s needed to follow the instructions for the newest version of Docker and not to use the default Ubuntu package.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I proceed with &lt;a href=&quot;http://www.howtoinstalldiscourse.com/how-to-install-discourse-on-ubuntu/&quot;&gt;this tutorial&lt;/a&gt; that specifies to run:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;wget -qO- https://get.docker.io/ | sh
mkdir /var/docker
git clone https://github.com/discourse/discourse_docker.git /var/docker
cd /var/docker
cp samples/standalone.yml containers/app.yml&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I modify /var/docker/containers/app.yml (all relevant changes to app.yml are at the bottom)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;DISCOURSE_HOSTNAME: &amp;#39;localhost&amp;#39;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;but on running start &lt;code class=&quot;language-text&quot;&gt;sudo ./launcher start app&lt;/code&gt; I get:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;2014/11/16 10:46:31 Error response from daemon: Cannot start container 270d47cd8401c50f13e0a1e51428f5b9833a9480b53bc98735df55b425a70b6d: Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;This could be expected, because Apache runs on port 80.&lt;/p&gt;
&lt;p&gt;in /var/docker/containers/app.yml there is an entry:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;expose:
  - &amp;quot;80:80&amp;quot;   # fwd host port 80   to container port 80 (http)
  - &amp;quot;2222:22&amp;quot; # fwd host port 2222 to container port 22 (ssh)&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;After using &lt;code class=&quot;language-text&quot;&gt;netstat -antp&lt;/code&gt; to confirm port 8080 is unused, I change 80:80 to 8080:80 in the app.yml.&lt;/p&gt;
&lt;p&gt;Now I rebuild and restart the container:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;cd /var/docker
sudo ./launcher rebuild app # this applies the changes
sudo ./launcher start app&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;When I use the browser to go to &lt;a href=&quot;http://localhost:8080/&quot;&gt;http://localhost:8080/&lt;/a&gt;, it immediately gives me Discourse page!&lt;/p&gt;
&lt;p&gt;Now I notice, when creating the admin account, that the activation mail is not send. Thinking back I did skip over the mail settings in the app.yml.&lt;/p&gt;
&lt;p&gt;Here I had to experiment a bit with my mail settings and this turned out in the end what took most of the time for getting Discourse up and running. One thing I learned is that it&apos;s not neccesary to stop the app with &lt;code class=&quot;language-text&quot;&gt;sudo ./launcher stop app&lt;/code&gt; before making changes or rebuilding.&lt;/p&gt;
&lt;p&gt;Soon I find that running &lt;code class=&quot;language-text&quot;&gt;sudo ./launcher mailtest app&lt;/code&gt; gives much more useful information, thanks to &lt;a href=&quot;https://meta.discourse.org/t/discourse-new-install-registration-emails-not-sent-because-from-address-cant-be-changed/16663/11&quot;&gt;this thread&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I configure the app.yml to use the Google smtp server (settings are below), but &lt;code class=&quot;language-text&quot;&gt;sudo ./launcher mailtest app&lt;/code&gt; still gives an error:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ERROR: python yaml module not installed - run the following and try again:

sudo apt-get install python3-yaml&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;After installing this package mailtest tells me there is an authentication problem and apparently I need to allow &quot;less secure apps&quot; access to my gmail account. After setting this up at Google accounts, I can send mail with mailtest. &lt;/p&gt;
&lt;p&gt;The activate mail link is now send and I can access the admin panel in Discourse.&lt;/p&gt;
&lt;p&gt;I have also tried to set up mail with the SMTP settings of my own ISP, but this gave an error that I could not find any solutions to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Traceback (most recent call last):
  File &amp;quot;/var/docker/scripts/mailtest&amp;quot;, line 138, in &amp;lt;module&amp;gt;
    smtp = smtplib.SMTP(smtp_addr, smtp_port, timeout=5)
  File &amp;quot;/usr/lib/python3.4/smtplib.py&amp;quot;, line 242, in __init__
    (code, msg) = self.connect(host, port)
  File &amp;quot;/usr/lib/python3.4/smtplib.py&amp;quot;, line 321, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File &amp;quot;/usr/lib/python3.4/smtplib.py&amp;quot;, line 292, in _get_socket
    self.source_address)
  File &amp;quot;/usr/lib/python3.4/socket.py&amp;quot;, line 509, in create_connection
    raise err
  File &amp;quot;/usr/lib/python3.4/socket.py&amp;quot;, line 500, in create_connection
    sock.connect(sa)
OSError: [Errno 113] No route to host&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Since I never use my ISP&apos;s mail server, it might simply be that I use the wrong SMTP address or something.&lt;/p&gt;
&lt;p&gt;In the end, I use these setting in my app.yml (these are just the edited fragments):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;expose:
  - &amp;quot;8080:80&amp;quot;  # fwd host port 80   to container port 80 (http)
  - &amp;quot;2222:22&amp;quot;  # fwd host port 2222 to container port 22 (ssh)

  DISCOURSE_DEVELOPER_EMAILS: &amp;#39;myemail@example.com&amp;#39;

  DISCOURSE_HOSTNAME: &amp;#39;localhost&amp;#39;

  DISCOURSE_SMTP_ADDRESS: smtp.gmail.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: mygmail@gmail.com
  DISCOURSE_SMTP_PASSWORD: ******&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I wonder now, since I&apos;m starting discourse now with &lt;code class=&quot;language-text&quot;&gt;./launcher start app&lt;/code&gt; if I should have renamed the containers/app.yml to discourse.yml to be able to start Discourse with &lt;code class=&quot;language-text&quot;&gt;./launcher start discourse&lt;/code&gt;? I don&apos;t know how difficult (or easy?) it will be to change this afterwards, but I will leave it for another time to figure this out.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Fronteers 2014: A Glossary]]></title><description><![CDATA[As I noted in  my previous post about Fronteers 2014  there were not as many talks about usable new techniques or tools as I would have…]]></description><link>https://mdworld.nl/mdworld-jackson//fronteers-2014-a-glossary</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//fronteers-2014-a-glossary</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;p&gt;As I noted in &lt;a href=&quot;../fronteers-2014-css/&quot;&gt;my previous post about Fronteers 2014&lt;/a&gt; there were not as many talks about usable new techniques or tools as I would have liked. This doesn&apos;t mean that no interesting new terms were mentioned. That&apos;s why I will supply a list of the subjects that were new to me.&lt;/p&gt;
&lt;style&gt;
.gloss {
  margin-bottom: 1rem;
}
.gloss h3 {
    display: inline-block;
}
.gloss i {
    display: inline-block;
    margin-left: 0.5em;
}
.gloss p {
    margin-top: 0;
}
.gloss h3::after {
    border: 1px solid transparent;
    border-radius: 2px;
    color: #303030;
    display: inline-block;
    font-size: 80%;
    line-height: 60%;
    margin-left: 0.5em;
    padding: 2px;
}
.css h3::after {
    content: &apos;CSS&apos;;
    background-color: #006DB8;
}
.tool h3::after {
    content: &apos;Tool&apos;;
    background-color: #028134;
}
.js h3::after {
    content: &apos;JS&apos;;
    background-color: #F0DB4F;
}
&lt;/style&gt;
&lt;div class=&quot;gloss&quot;&gt;
    &lt;h3&gt;A Spacecraft for All&lt;/h3&gt;
&lt;p&gt;An &lt;a href=&quot;https://www.chromeexperiments.com/experiment/a-spacecraft-for-all&quot;&gt;interactive documentary&lt;/a&gt; about the ISEE-3 spacecraft. A Chrome experiment using WebGL.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;BlobAPI&lt;/h3&gt;
    &lt;i&gt;from the lecture by Paul Kinlan&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Blob&quot;&gt;Blobs&lt;/a&gt; (Binary Large OBjects) are common in most programming languages but relatively new in JavaScript. The File API is based on Blob and Blob content can be read with a FileReader object.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss css&quot;&gt;
    &lt;h3&gt;CSS Animate&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nathan Ford&lt;/i&gt;
&lt;p&gt;CSS generator for CSS 3 keyframe animations at &lt;a href=&quot;http://cssanimate.com/&quot;&gt;http://cssanimate.com/&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss&quot;&gt;
    &lt;h3&gt;Dialog&lt;/h3&gt;
    &lt;i&gt;from the lecture by Paul Kinlan&lt;/i&gt;
&lt;p&gt;The experimental Dialog HTML element is a semantic element that can be used for e.g. modal dialogs. It&apos;s only supported in Chrome 37+ at the moment. Naming conventions around this common component are very unclear (modal, dialog, &quot;popup&quot; and backdrop, fade, &quot;fog&quot;, overlay) so it would make a very useful addition, in my opinion. Check out this &lt;a href=&quot;http://jsfiddle.net/mdvanes/k7t22u5h/&quot;&gt;jsfiddle (Chrome only)&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;ES6 Compatibility Table&lt;/h3&gt;
&lt;p&gt;An &lt;a href=&quot;https://kangax.github.io/compat-table/es6/&quot;&gt;overview&lt;/a&gt; of supported ES6 features for different platforms (polyfills, browsers, runtimes).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss css&quot;&gt;
    &lt;h3&gt;Flexy Boxes&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nathan Ford&lt;/i&gt;
&lt;p&gt;CSS generator for flexbox at &lt;a href=&quot;http://the-echoplex.net/flexyboxes/&quot;&gt;http://the-echoplex.net/flexyboxes/&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;getUserMedia&lt;/h3&gt;
    &lt;i&gt;from the lecture by Swetank Dixit&lt;/i&gt;
&lt;p&gt;API for accessing video/audio devices from the browser. See many demos &lt;a href=&quot;http://shinydemos.com/getusermedia/&quot;&gt;here&lt;/a&gt;, e.g. a real-life color-picker. As noted in the talk, using https will allow for the browser to store the permission to access the multimedia devices. A very detailed tutorial can be found on &lt;a href=&quot;http://www.html5rocks.com/en/tutorials/getusermedia/intro/&quot;&gt;html5rocks&lt;/a&gt;. In this tutorial getUserMedia is also combined with CSS filters to apply real-time effects to a video stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;Intern&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nicholas Gallagher&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;https://theintern.github.io/&quot;&gt;The Intern&lt;/a&gt; is a test framework for JavaScript like &lt;a href=&quot;http://karma-runner.github.io/0.12/index.html&quot;&gt;Karma&lt;/a&gt; and &lt;a href=&quot;https://github.com/airportyh/testem&quot;&gt;Testem&lt;/a&gt;, focused on compatibility.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;Istanbul&lt;/h3&gt;
    &lt;i&gt;from the lecture by Kyle Simpson&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;https://gotwarlost.github.io/istanbul/&quot;&gt;Istanbul&lt;/a&gt; is a JavaScript code coverage tool. Of course, there is a &lt;a href=&quot;https://www.npmjs.com/package/grunt-istanbul&quot;&gt;grunt plugin&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;JSComplexity&lt;/h3&gt;
    &lt;i&gt;from the lecture by Kyle Simpson&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;http://jscomplexity.org&quot;&gt;JSComplexity&lt;/a&gt; is an online tool for complexity analysis of JavaScript projects. Fortunately, it has a &lt;a href=&quot;https://www.npmjs.com/package/grunt-complexity&quot;&gt;grunt plugin&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss&quot;&gt;
    &lt;h3&gt;Line-mode browser&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nathan Ford&lt;/i&gt;
&lt;p&gt;Rebuild by CERN of the original line-mode browser from 1992. &lt;a href=&quot;http://line-mode.cern.ch/&quot;&gt;See the line-mode browser&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss css&quot;&gt;
    &lt;h3&gt;Penthouse&lt;/h3&gt;
    &lt;i&gt;from the lecture by Dave Olson&lt;/i&gt;
&lt;p&gt;A &lt;a href=&quot;https://www.npmjs.com/package/penthouse&quot;&gt;node module&lt;/a&gt; (with a &lt;a href=&quot;https://www.npmjs.com/package/grunt-penthouse&quot;&gt;grunt plugin&lt;/a&gt; and an &lt;a href=&quot;http://jonassebastianohlsson.com/criticalpathcssgenerator/&quot;&gt;online tool&lt;/a&gt;) to generate the critical path of CSS to speed up page rendering. The browser waits with displaying any page until the CSS is loaded or times out eventually, resulting in a blank page. Of course it is always recommendable to have the CSS combined and minified (and gzipped), but if performance is important it might be an option to load it inline (!) to prevent failing on bad connections. &lt;/p&gt;
&lt;p&gt;Instead of loading all the CSS inline, you can convert the critical CSS for the first page (the above-the-fold CSS) to inline CSS in the document head and load the full CSS in the bottom of the body, where the JavaScript sources should be as well. Extracting this critical CSS is what Penthouse does.&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;Phaser&lt;/h3&gt;
    &lt;i&gt;from the lecture by Thomas Palef&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;http://phaser.io&quot;&gt;Phaser&lt;/a&gt; is an open source framework for building browser based games. See also &lt;a href=&quot;http://www.lessmilk.com/&quot;&gt;the games&lt;/a&gt; that Thomas built.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;Plato&lt;/h3&gt;
    &lt;i&gt;from the lecture by Kyle Simpson&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/es-analysis/plato&quot;&gt;Plato&lt;/a&gt; is a JavaScript source code visualization, static analysis, and complexity tool. And yes, it has a &lt;a href=&quot;https://www.npmjs.com/package/grunt-plato&quot;&gt;grunt plugin&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;ServiceWorker&lt;/h3&gt;
    &lt;i&gt;from the lecture by Paul Kinlan&lt;/i&gt;
&lt;p&gt;A ServiceWorker is a type of JavaScript Worker. A Worker is a solution to run background processes by spawning isolated threads. Service Workers run separately from a web page (just like an OS level service) but still runs in the browser. It can be used to improve the off-line experience of an app. See &lt;a href=&quot;http://www.html5rocks.com/en/tutorials/service-worker/introduction/&quot;&gt;this introduction&lt;/a&gt; and &lt;a href=&quot;https://github.com/slightlyoff/ServiceWorker&quot;&gt;this implementation&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss css&quot;&gt;
    &lt;h3&gt;Shadow DOM&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nicholas Gallagher&lt;/i&gt;
&lt;p&gt;The Shadow DOM lets you manipulate parts of an HTML document that are normally invisibly encapsulated within another HTML element. An example is styling the controls (play, rewind) of the video tag with CSS. This &lt;a href=&quot;http://webcomponents.org/articles/introduction-to-shadow-dom/&quot;&gt;introduction&lt;/a&gt; shows some examples. It&apos;s part of webcomponents, allowing you to create custom components and hiding the contents in a shadow DOM. It also enables scoping of styles. I also made an &lt;a href=&quot;https://jsfiddle.net/mdvanes/oy8dxpka/&quot;&gt;example in this fiddle&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss tool&quot;&gt;
    &lt;h3&gt;Spritesmith&lt;/h3&gt;
    &lt;i&gt;from the lecture by Dave Olson&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Ensighten/grunt-spritesmith&quot;&gt;Grunt plugin&lt;/a&gt; to create a spritesheet. I use Compass&apos; magic sprites to do this in Sass, but it might be useful if you want to use libsass or LESS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss css&quot;&gt;
    &lt;h3&gt;SUIT CSS&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nicholas Gallagher&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;https://suitcss.github.io/&quot;&gt;SUIT CSS&lt;/a&gt; is a reliable and testable styling methodology for component-based UI development. It offers a.o. a naming convention, a pre-processor and CSS testing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;SVGInjector&lt;/h3&gt;
    &lt;i&gt;from the lecture by Sara Soueidan&lt;/i&gt;
&lt;p&gt;A &lt;a href=&quot;https://github.com/iconic/SVGInjector&quot;&gt;library&lt;/a&gt; for inlining SVGs with client-side JavaScript. This combines the benefits of storing the resource in an external file with the benefit of using CSS (normally only for inline SVGs).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;Traceur&lt;/h3&gt;
    &lt;i&gt;from the lecture by Kyle Simpson&lt;/i&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/google/traceur-compiler&quot;&gt;Traceur compiler&lt;/a&gt; lets you write in ES6 syntax and compile it back to ES5 so you can use ES6 features in today&apos;s browers. According to &lt;a href=&quot;https://kangax.github.io/compat-table/es6/&quot;&gt;the ES6 compatibility table&lt;/a&gt; it supports 63% of ES6 features at this moment.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss css&quot;&gt;
    &lt;h3&gt;Ultimate CSS Gradient Generator&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nathan Ford&lt;/i&gt;
&lt;p&gt;CSS generator for CSS 3 linear and radial gradients at &lt;a href=&quot;http://www.colorzilla.com/gradient-editor/&quot;&gt;http://www.colorzilla.com/gradient-editor/&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;Webpack Module Bundler&lt;/h3&gt;
    &lt;i&gt;from the lecture by Nicholas Gallagher&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;http://webpack.github.io/&quot;&gt;Webpack Module Bundler&lt;/a&gt; is an alternative to &lt;a href=&quot;http://requirejs.org/&quot;&gt;RequireJS&lt;/a&gt; that isn&apos;t necessarily optimized for async loading like RequireJS but supports the much simpeler CommonJS syntax.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss tool&quot;&gt;
    &lt;h3&gt;WebPageTest&lt;/h3&gt;
    &lt;i&gt;from the lecture by Dave Olson&lt;/i&gt;
&lt;p&gt;&lt;a href=&quot;http://www.webpagetest.org&quot;&gt;Very powerful tool&lt;/a&gt; for testing performance of sites. The Chrome plugin &lt;a href=&quot;https://chrome.google.com/webstore/detail/spof-o-matic/plikhggfbplemddobondkeogomgoodeg?hl=en-US&quot;&gt;SPOF-O-Matic&lt;/a&gt; helps to test how sites react when external CDNs are unavailable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;WebRTC&lt;/h3&gt;
    &lt;i&gt;from the lecture by Swetank Dixit&lt;/i&gt;
&lt;p&gt;Peer-to-peer connections in the browser, supported in &lt;a href=&quot;http://caniuse.com/#feat=rtcpeerconnection&quot;&gt;FF and Chrome&lt;/a&gt; at the moment. Using the data channels, it was even possible to create a client-side streaming torrent client.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss css&quot;&gt;
    &lt;h3&gt;will-change&lt;/h3&gt;
    &lt;i&gt;from the lecture by Rachel Nabors&lt;/i&gt;
&lt;p&gt;The CSS property &quot;will-change&quot; is a new feature (Chrome 36, FF 36) that can inform the browser beforehand that certain CSS animation may be applied to an element, helping with optimization. See the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/will-change&quot;&gt;docs&lt;/a&gt; or this in-depth &lt;a href=&quot;http://www.sitepoint.com/introduction-css-will-change-property/&quot;&gt;article on Sitepoint&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss js&quot;&gt;
    &lt;h3&gt;Xibalba&lt;/h3&gt;
    &lt;i&gt;from the lecture by Dominic Szablewski.&lt;/i&gt;
&lt;p&gt;A web based 3D shooter by &lt;a href=&quot;http://phoboslab.org/&quot;&gt;phoboslab.org&lt;/a&gt; build with the &lt;a href=&quot;http://impactjs.com/&quot;&gt;Impact&lt;/a&gt; Game Engine. Play it &lt;a href=&quot;http://phoboslab.org/xibalba/&quot;&gt;here&lt;/a&gt;. It now even offers &lt;a href=&quot;http://phoboslab.org/log/2015/02/xibalba-webvr&quot;&gt;WebVR&lt;/a&gt; support.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;gloss tool&quot;&gt;
    &lt;h3&gt;Yeast&lt;/h3&gt;
    &lt;i&gt;from the lecture by Arnout Kazemier&lt;/i&gt;
&lt;p&gt;&quot;Tiny but linear growing unique id generator.&quot; A function to create better cachebusting variables, now formalized as &lt;a href=&quot;https://github.com/unshiftio/yeast&quot;&gt;an NPM package&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Dop Beeping HDD]]></title><description><![CDATA[Recently I replaced the 1,5 TB HDD that is used as an archive in Dop by a 3TB Seagate Barracuda ST3000DM001. Silly choice apparently…]]></description><link>https://mdworld.nl/mdworld-jackson//dop-beeping-hdd</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//dop-beeping-hdd</guid><category><![CDATA[mypc]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Invalid Date</pubDate><content:encoded>&lt;p&gt;Recently I replaced the 1,5 TB HDD that is used as an archive in Dop by a 3TB Seagate Barracuda ST3000DM001. Silly choice apparently, because it is known to have some defects. Imagine my horror when it started beeping at certain intervals. &lt;/p&gt;
&lt;p&gt;The time in between is large enough to seem random, but it apparently only happens after awaking from hibernate. After looking up &lt;a href=&quot;http://lime-technology.com/forum/index.php?topic=29076.msg259784&quot;&gt;some forums&lt;/a&gt; this seems to be a problem with Advanced Power Management with Seagate drives.&lt;/p&gt;
&lt;p&gt;By disabling APM with &lt;code class=&quot;language-text&quot;&gt;sudo hdparm -B 255 /dev/sdb&lt;/code&gt; the sound indeed disappeared. This setting is not maintained after reboots, but it should be possible to configure it in the &lt;code class=&quot;language-text&quot;&gt;/etc/hdparm.conf&lt;/code&gt; e.g. like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/dev/sdb {
    apm=255
}&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;</content:encoded></item><item><title><![CDATA[npm workaround]]></title><description><![CDATA[EDIT  The issue concerning the compilation of npm for ARM seems to have been fixed, which would outdate this post. The latest builds should…]]></description><link>https://mdworld.nl/mdworld-jackson//npm-workaround</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//npm-workaround</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Sun, 06 Dec 2015 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt; The issue concerning the compilation of npm for ARM seems to have been fixed, which would outdate this post. The latest builds should be available at &lt;a href=&quot;https://nodejs.org/dist/&quot;&gt;https://nodejs.org/dist/&lt;/a&gt;. For RPi 1 look for the builds with &quot;armv6l&quot;, for RPi2B &quot;armv7l&quot;, and for RPi3 I assume you would need &quot;arm64&quot;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Although it&apos;s relatively easy to install &lt;a href=&quot;http://nodejs.org&quot;&gt;Node.js&lt;/a&gt; on a Raspberry Pi, getting npm to work is a bit more challenging. &lt;/p&gt;
&lt;p&gt;It seems there is &lt;a href=&quot;http://redandwhite.herokuapp.com/#/post/5516eba439156a0e00cad4f6&quot;&gt;an issue with compiling npm&lt;/a&gt;, at least for ARM. As long as this remains unfixed, there is no npm with the node 0.12.x ARM installation.&lt;/p&gt;
&lt;p&gt;A very simple workaround is to copy the node_modules from another system and to run the packages (e.g. &lt;a href=&quot;https://github.com/trentm/node-bunyan&quot;&gt;bunyan&lt;/a&gt;, which is supposed to be installed globally) with node. Since installing (globally or not) is not possible, but node is installed, I will call it directly from the node_modules that I copied from another machine.&lt;/p&gt;
&lt;p&gt;So instead of using &lt;code class=&quot;language-text&quot;&gt;npm start&lt;/code&gt; configured in package.json as &lt;code class=&quot;language-text&quot;&gt;node app.js | bunyan&lt;/code&gt; I would do &lt;code class=&quot;language-text&quot;&gt;node app.js | node node_modules/bunyan/bin/bunyan&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Or if I would like to read the log file afterwards:&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;node node_modules/bunyan/bin/bunyan -o short error.log&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This would also work for other systems where npm can&apos;t be installed or if npm can&apos;t be used to install packages. I&apos;ve used this on a system behind a corporate proxy, although I&apos;ve found &lt;a href=&quot;../npm-without-internet&quot;&gt;a better way&lt;/a&gt; by now.&lt;/p&gt;
&lt;h1 id=&quot;node-on-rpi&quot;&gt;&lt;a href=&quot;#node-on-rpi&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Node on RPi&lt;/h1&gt;
&lt;p&gt;Keep in mind that this still requires Node.js to be installed. For a Raspberry Pi running Raspbmc it&apos;s possible to use &lt;em&gt;apt-get&lt;/em&gt; to install Node, but it won&apos;t be a recent version. Instead, I use the ARM build &lt;em&gt;node_latest_armhf.deb&lt;/em&gt; from &lt;a href=&quot;http://node-arm.herokuapp.com&quot;&gt;node-arm&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;compiling-node-on-rpi&quot;&gt;&lt;a href=&quot;#compiling-node-on-rpi&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Compiling Node on RPi&lt;/h1&gt;
&lt;p&gt;I&apos;ve also tried compiling Node from source on the Raspberry Pi (model B). It should not be very difficult, but it failed in my case, probably because of the issue with npm, mentioned before. To be complete, I will list my steps.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I had already installed gcc earlier with &lt;code class=&quot;language-text&quot;&gt;sudo apt-get install build-essential&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I looked up the latest version in &lt;a href=&quot;http://nodejs.org/dist/&quot;&gt;http://nodejs.org/dist/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;At 11-7-2015 this was &lt;a href=&quot;http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz&quot;&gt;http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# adapted from http://elinux.org/Node.js_on_RPi
wget http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz
tar -xzf node-v0.12.7.tar.gz # duration ca. 1 min
cd node-v0.12.7
./configure # duration ca. 1 min&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Here I would really recommend to start a screen session, because compiling takes ca. 2 hours.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sudo apt-get install screen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;screen&lt;/code&gt; start a session&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ctrl + a, d&lt;/code&gt; detach session&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;screen -dRR&lt;/code&gt; reattach to any session running&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My first attempt to run make ended with this error:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/usr/include/linux/sysinfo.h:8:2: error: unknown type name &amp;#39;__kernel_long_t&amp;#39;`&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;From &lt;a href=&quot;http://raspberrypi.stackexchange.com/questions/8566/peerguardian-moblock-installation-on-raspbmc&quot;&gt;this thread&lt;/a&gt; I found the solution to add these lines:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;#ifndef __kernel_long_t
typedef long     __kernel_long_t;
typedef unsigned long   __kernel_ulong_t;
#endif&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;to the file /usr/include/linux/sysinfo.h, before the lines:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;    #define SI_LOAD_SHIFT   16struct sysinfo {...&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The second attempt to run make failed with this error:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/bin/sh: 1: cannot create /home/pi/node-v0.12.7/out/Release/.deps//home/pi/node-v0.12.7/out/Release/obj.target/libuv/deps/uv/src/unix/linux-core.o.d: Permission denied&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;So in the end I ran clean and make as root:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sudo make clean&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sudo make&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;after some hours it fails with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/out/Release/obj.target/v8_snapshot/geni/snapshot.cc&amp;quot;
Illegal instruction
make[1]: *** [/home/pi/node-v0.12.7/out/Release/obj.target/v8_snapshot/geni/snapshot.cc] Error 132
make[1]: Leaving directory `/home/pi/node-v0.12.7/out&amp;#39;
make: *** [node] Error 2&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;This is either the compile issue as described in the beginning of this article, or yet again another issue. Since I found out about the compile issue at this point I&apos;ve stopped experimenting and resorted to the quick workaround.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Site updated]]></title><description><![CDATA[It's always a hard decision to move to a new platform for my personal site, and this time it was sped up by the growing
need for https (for…]]></description><link>https://mdworld.nl/mdworld-jackson//site-updated</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//site-updated</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Thu, 04 Oct 2018 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s always a hard decision to move to a new platform for my personal site, and this time it was sped up by the growing
need for https (for SEO) and the release of GatsbyJS v1. &lt;/p&gt;
&lt;p&gt;Up until now I was using a monolitical Apache + PHP webserver, but since the 2013 version of the site, a dynamic webserver
was no longer needed for the blog, because it was generated statically with Jekyll. Only the &quot;send mail&quot; component was
in PHP and I was running some other PHP apps, and hosting some binaries, that have nothing to do with the blog. I&apos;ve
done away with the PHP apps: communication by mail was already almost zero and the other apps were outdated. &lt;/p&gt;
&lt;p&gt;Now the blog has been properly containerized, this means future upgrades will be easier too: the blog is its own app
with its own scope. When I will need anything dynamic in the future, I will use &lt;a href=&quot;https://serverless.com/&quot;&gt;Serverless&lt;/a&gt; functions.&lt;/p&gt;
&lt;p&gt;Another good reason to migrate from &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; to &lt;a href=&quot;https://www.gatsbyjs.org/&quot;&gt;Gatsby&lt;/a&gt; is letting go
of Ruby dependencies and migrating to a NodeJS
based platform. With Jekyll I started to run into problems with recreating the Jekyll stack with the
correct dependencies to build the blog, in case of restoring after an emergency. This might be caused by my lack of knowledge
of Ruby, but it meant it was really time to upgrade to a newer version of Jekyll or start with a new theme. And in the mean
time, Gatsby 1.0 was released and I really subscribe to the &lt;a href=&quot;https://jamstack.org/&quot;&gt;JAMstack&lt;/a&gt; architecture.  &lt;/p&gt;
&lt;p&gt;With the new setup, I can work with a modern and familiar stack e.g. Babel, React, TravisCI. I still believe in static site
generation for blogs, and just like in Jekyll, adding a post in Gatsby is just a matter of adding a Markdown file with
some frontmatter. But an improvement is that you can also drop React components in the pages dir that will be automatically
picked up as pages. And it is even possible to add a React component inside a Markdown post. Try clicking the screenshots
below for a simple lightbox feature and
see the source for &lt;a href=&quot;https://raw.githubusercontent.com/mdvanes/mdworld-jackson/master/content/posts/2018-05-10-site-updated.md&quot;&gt;this post&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;For more information about the current stack, see the &lt;a href=&quot;../about&quot;&gt;about page&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;cover-images&quot;&gt;&lt;a href=&quot;#cover-images&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Cover images&lt;/h1&gt;
&lt;p&gt;The cover images for each post, e.g. the image you see on top of this post, are procedurally generated
with my project &lt;a href=&quot;https://github.com/mdvanes/procgen-cover&quot;&gt;procgen-cover&lt;/a&gt;. This was inspired by the talk
by &lt;a href=&quot;http://www.galaxykate.com/&quot;&gt;Kate Compton&lt;/a&gt; on &lt;a href=&quot;https://2018.jsconf.is/&quot;&gt;JSConf.is&lt;/a&gt; 2018. &lt;/p&gt;
&lt;h1 id=&quot;old-themes&quot;&gt;&lt;a href=&quot;#old-themes&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Old themes&lt;/h1&gt;
&lt;p&gt;Static versions of the 2 last themes still run &lt;a href=&quot;https://mdvanes.github.io/mdworld-ingram&quot;&gt;here (2013-2018)&lt;/a&gt;
and &lt;a href=&quot;https://mdvanes.github.io/mdworld-simon&quot;&gt;here (2010-2013)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Theme 2013-2018&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;simple-light-box img-path=&quot;/lightbox/theme-ingram.jpg&quot; img-title=&quot;Theme 2013-2018&quot;&gt;&lt;/simple-light-box&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Theme 2010-2013&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;simple-light-box img-path=&quot;/lightbox/theme-simon.jpg&quot; img-title=&quot;Theme 2010-2013&quot;&gt;&lt;/simple-light-box&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Theme until 2010&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mdvanes.github.io/mdworld-simon/sites/default/files/images/vorig_design.jpg&quot; alt=&quot;Theme until 2010&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Polymer 2 and TypeScript]]></title><description><![CDATA[For  reasons beyond my control  I'm working with
Polymer 2 at the moment. Although the idea of web components is great, the choice for HTML…]]></description><link>https://mdworld.nl/mdworld-jackson//polymer-2-and-type-script</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//polymer-2-and-type-script</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Mon, 11 Sep 2017 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For &lt;a href=&quot;../polymer-2-and-redux/&quot;&gt;reasons beyond my control&lt;/a&gt; I&apos;m working with
Polymer 2 at the moment. Although the idea of web components is great, the choice for HTML imports that comes with
Polymer 2 makes integration into a modern development stack cumbersome, as will become clear soon. Also, HTML
imports are not widely supported by browsers and although polyfills exist, only &lt;a href=&quot;https://caniuse.com/#search=html%20imports&quot;&gt;Chrome (surprise!)&lt;/a&gt;
will have native support for the foreseeable future.&lt;/p&gt;
&lt;p&gt;Using TypeScript seems like a good choice, because static typing helps prevent runtime errors. Additionally it would be a
good opportunity to try out the &lt;a href=&quot;https://github.com/code-star/scala-ts-interfaces&quot;&gt;Scala-TS-interfaces project&lt;/a&gt; by my
colleagues, that can generate TypeScript from a Scala domain model. Unfortunately, adding TypeScript to a Polymer 2
development stack proves to be difficult, whereas using it with Polymer 3 seems trivial. Polymer 3 is currently in
preview so it is not a viable option for me for the moment, but it will exchange HTML imports for ES6 Modules. This will
make integrating it into a modern development stack much easier. An &lt;a href=&quot;https://github.com/mdvanes/polymer3-typescript&quot;&gt;example&lt;/a&gt;
already exists, by &lt;a href=&quot;https://github.com/pferretti&quot;&gt;Paolo Ferretti&lt;/a&gt; and follows normal conventions for a TypeScript project.&lt;/p&gt;
&lt;p&gt;If you&apos;re adventurous, don&apos;t need any &lt;a href=&quot;https://www.webcomponents.org/&quot;&gt;existing Polymer 2 elements&lt;/a&gt; and don&apos;t need to
run production; stop reading here and use Polymer 3.
If you need Polymer 2 read on, but be warned that it won&apos;t be pretty.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR to use TypeScript with Polymer 2 use &lt;a href=&quot;https://github.com/mdvanes/typescript-batch-compiler&quot;&gt;typescript-batch-compiler&lt;/a&gt; or even better &lt;a href=&quot;https://github.com/Draccoz/twc&quot;&gt;twc&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;webpack&quot;&gt;&lt;a href=&quot;#webpack&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Webpack&lt;/h2&gt;
&lt;p&gt;For this experiment I will use my existing Polygram project and the result will be available in the &lt;a href=&quot;https://github.com/mdvanes/polygram/tree/TypeScript&quot;&gt;TypeScript branch&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;The first challenge is to use Webpack with Polymer 2. Although not strictly necessary for TypeScript compilation, it would
make sense for importing HTML as modules. Fortunately, &lt;a href=&quot;https://www.youtube.com/playlist?list=PLOU2XLYxmsII5c3Mgw6fNYCzaWrsM3sMN&quot;&gt;Rob Dodson himself&lt;/a&gt; wrote an
article &lt;a href=&quot;http://robdodson.me/how-to-use-polymer-with-webpack/&quot;&gt;How to use Polymer with Webpack&lt;/a&gt;. It even mentions TypeScript!
The article introduces the Webpack loader &lt;a href=&quot;https://github.com/webpack-contrib/polymer-webpack-loader&quot;&gt;https://github.com/webpack-contrib/polymer-webpack-loader&lt;/a&gt; and
explains how it extracts the JavaScript from the HTML of Polymer elements and eventually packages everything into one
JavaScript file. I was basically able to copy the webpack.config.js and index.ejs from his demo project, place it into Polygram and that would compile. I moved my
&lt;a href=&quot;https://github.com/mdvanes/polygram/tree/TypeScript&quot;&gt;custom elements&lt;/a&gt; from the root of the project to the src dir and I had
to modify the paths to the bower_components and it would basically work. &lt;/p&gt;
&lt;p&gt;The most important exception is Redux, the redux-mixin.html can&apos;t resolve the PolymerRedux.html dependency (in bower_components/polymer-redux/polymer-redux.html).
The polymer-webpack-loader should resolve this, but runtime it logs &lt;code class=&quot;language-text&quot;&gt;Uncaught ReferenceError: PolymerRedux is not defined&lt;/code&gt;.
E.g. for src/polygram-app.html, the loader seems to import the HTML elements that are used in the &lt;code class=&quot;language-text&quot;&gt;template&lt;/code&gt; element,
but not the JavaScript variables that are used in the &lt;code class=&quot;language-text&quot;&gt;script&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;The PolymerRedux code is distributed as JavaScript wrapped in a &lt;code class=&quot;language-text&quot;&gt;script&lt;/code&gt; tag in mainly one file, so it would be easy to
extract it to a JavaScript file. Or even to import &lt;code class=&quot;language-text&quot;&gt;polymer-redux/src/index.js&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;polymer-redux/polymer-redux.html&lt;/code&gt;
(although index.js is uncompiled and misses external dependencies that are not installed in bower_components because they are development dependencies of polymer-redux).
For now, I just comment out the Redux dependencies.&lt;/p&gt;
&lt;p&gt;It is already clear now that the result from Webpack will be one huge bundle.js that inlines all JavaScript and HTML
dependencies. This means using the &lt;a href=&quot;https://www.polymer-project.org/2.0/toolbox/prpl&quot;&gt;PRPL pattern&lt;/a&gt; will not be possible
in this workflow, nor will it be possible to have standalone Polymer components and the accompanying Polymer demo pages.&lt;/p&gt;
&lt;h2 id=&quot;adding-ts-loader&quot;&gt;&lt;a href=&quot;#adding-ts-loader&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Adding ts-loader&lt;/h2&gt;
&lt;p&gt;Normally, to migrate a Webpack project from JavaScript to TypeScript, it would be enough to add the &lt;a href=&quot;https://github.com/TypeStrong/ts-loader&quot;&gt;ts-loader&lt;/a&gt;
to the Webpack config and to rename the JavaScript files to TypeScript files. &lt;/p&gt;
&lt;p&gt;So I started with changing the extension for the bootstrapping index.js and adding .ts as a resolved extension:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// webpack.config.js&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
entry&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;src/index.ts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
resolve&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        extensions&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;.ts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;And adding this rule:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// webpack.config.js&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    test&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;/\.ts?$/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    use&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; loader&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ts-loader&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;And creating a tsconfig.json:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;sourceMap&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Everything still compiles, but the JavaScript for the Polymer components is embedded in the HTML and therefore ignored
by the new rule with the ts-loader.&lt;/p&gt;
&lt;p&gt;Adding the ts-loader to the rule for the HTML files breaks compilation:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// webpack.config.js&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    test&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;/\.html$/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    use&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; loader&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;babel-loader&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; loader&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ts-loader&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;--&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; loader&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;polymer-webpack-loader&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Even without changing any of the code itself, compilation fails with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ERROR in ./src/polygram-app.html
Module build failed: Error: Could not find file: &amp;#39;/home/me/polygram/src/polygram-app.html&amp;#39;.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Well, that just doesn&apos;t look healthy. I filed &lt;a href=&quot;https://github.com/webpack-contrib/polymer-webpack-loader/issues/64&quot;&gt;a bug&lt;/a&gt;
and almost 2 months after my report the maintainers closed the issue commenting that the root cause is with Webpack, so I
don&apos;t see this will be resolved any time soon.&lt;/p&gt;
&lt;p&gt;For now, I will try to work around it by extracting the TypeScript code to a separate file. &lt;/p&gt;
&lt;h3 id=&quot;workaround-for-typescript-compilation-in-a-polymer-element&quot;&gt;&lt;a href=&quot;#workaround-for-typescript-compilation-in-a-polymer-element&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Workaround for TypeScript compilation in a Polymer element&lt;/h3&gt;
&lt;p&gt;After removing the &lt;code class=&quot;language-text&quot;&gt;ts-loader&lt;/code&gt; line from the HTML rule in the webpack.config.js I set out to extract the TypeScript to a
separate file so it can be compiled with the rule that matches ts files. &lt;/p&gt;
&lt;p&gt;Roughly, the main entry point for the Polymer elements &lt;code class=&quot;language-text&quot;&gt;polygram-app.html&lt;/code&gt; contains:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;// imports
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;import&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;../bower_components/polymer/polymer-element.html&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
...
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;import&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;polygram-details.html&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;import&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;polygram-searchbox.html&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dom-module&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;polygram-app&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Style --&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;iron-flex iron-flex-alignment&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style language-css&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Markup --&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;layout vertical&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            ...
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        ...
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Script&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; format &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns/format&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PolygramApp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Element&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;polygram-app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    today&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;MM/DD/YYYY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;customElements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PolygramApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PolygramApp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dom-module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Since I know the &lt;code class=&quot;language-text&quot;&gt;import&lt;/code&gt; statement in the script tag works, I can use this to my advantage. Lets create a companion
TypeScript file for polygram-app.html named PolygramApp.ts.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// PolygramApp.ts&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; format &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns/format&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PolygramApp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Element&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;polygram-app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            today&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;MM/DD/YYYY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;It would be possible to import PolygramApp.ts with &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script src=&amp;quot;PolygramApp.ts&amp;quot;&amp;gt;&amp;lt;/script&lt;/code&gt;, but I like the standard ES6 module structure
of PolygramApp.ts without the added responsibility of registering itself to customElements, so I import it like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- polygram-app.html --&gt;&lt;/span&gt;
...

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dom-module&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;polygram-app&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    ...
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Script&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; PolygramApp &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./polygramApp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;customElements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PolygramApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PolygramApp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dom-module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The result is a failed compilation with 3 types of errors. Let&apos;s deal with them one by one.&lt;/p&gt;
&lt;h3 id=&quot;1-failing-accessors&quot;&gt;&lt;a href=&quot;#1-failing-accessors&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. Failing accessors&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;is&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;properties&lt;/code&gt; getters require a specifically set target ECMAScript version, the compilation error is:
&lt;code class=&quot;language-text&quot;&gt;error TS1056: Accessors are only available when targeting ECMAScript 5 and higher&lt;/code&gt;. It surprises me that the default
ES target is ES3, but it&apos;s not a problem to use ES5 or even ESNext here, because the babel-loader will transpile it back to ES5.&lt;/p&gt;
&lt;p&gt;Adding &lt;code class=&quot;language-text&quot;&gt;&amp;quot;target&amp;quot;: &amp;quot;ESNext&amp;quot;&lt;/code&gt; to compilerOptions in the tsconfig.json fixes this error.&lt;/p&gt;
&lt;h3 id=&quot;2-failing-polymer-import&quot;&gt;&lt;a href=&quot;#2-failing-polymer-import&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. Failing Polymer import&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Polymer&lt;/code&gt; can&apos;t be found for the &lt;code class=&quot;language-text&quot;&gt;extends&lt;/code&gt;. This is the most difficult of these errors to solve, because it is caused by the preferred module
architecture of Polymer 2: because HTML imports are used, it is not possible to use &lt;code class=&quot;language-text&quot;&gt;import Polymer from &amp;#39;../bower_components/polymer/polymer-element.html&amp;#39;&lt;/code&gt;
because this polymer-element does not export &lt;code class=&quot;language-text&quot;&gt;Polymer&lt;/code&gt; as an ES6 module. The webpack-polymer-loader can resolve HTML
imports, but using &lt;code class=&quot;language-text&quot;&gt;import &amp;#39;../bower_components/polymer/polymer-element.html&amp;#39;&lt;/code&gt; results in an &lt;code class=&quot;language-text&quot;&gt;error TS2304: Cannot find name &amp;#39;Polymer&amp;#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For the moment, I&apos;m just removing the &lt;code class=&quot;language-text&quot;&gt;extends Polymer.Element&lt;/code&gt; from PolygramApps.ts and &lt;code class=&quot;language-text&quot;&gt;window.customElements.define(PolygramApp.is, PolygramApp);&lt;/code&gt; from polygram-app.html.&lt;/p&gt;
&lt;h3 id=&quot;3-failing-date-fns-import&quot;&gt;&lt;a href=&quot;#3-failing-date-fns-import&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Failing date-fns import&lt;/h3&gt;
&lt;p&gt;To be able to continue resolving the compilation errors, I add a log statement to polygram-app.html:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- polygram-app.html --&gt;&lt;/span&gt;
...

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dom-module&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;polygram-app&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    ...
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Script&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; PolygramApp &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./polygramApp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PolygramApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;properties&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;today&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dom-module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The import of date-fns originally failed in the TypeScript compilation with
&lt;code class=&quot;language-text&quot;&gt;error TS1192: Module &amp;#39;&amp;#39;date-fns/format&amp;#39;&amp;#39; has no default export.&lt;/code&gt; but at this point that has two different behaviors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The IDE warns &lt;code class=&quot;language-text&quot;&gt;TS2307 Cannot find module date-fns&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Compilation succeeds, but this error is logged in the browser: &lt;code class=&quot;language-text&quot;&gt;Uncaught TypeError: format_1.default is not a function(…)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I first thought that this was caused by missing typings for the date-fns library, so I tried
&lt;code class=&quot;language-text&quot;&gt;npm install @types/date-fns&lt;/code&gt; but this logs that date-fns actually provides typings.&lt;/p&gt;
&lt;p&gt;Eventually I was able to fix the Uncaught TypeError by changing the import in PolygramApp.ts from&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; format &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns/format&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; format &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;And the IDE warning by adding &lt;code class=&quot;language-text&quot;&gt;&amp;quot;moduleResolution&amp;quot;: &amp;quot;node&amp;quot;&lt;/code&gt; to the compilerOptions in tsconfig.json.&lt;/p&gt;
&lt;p&gt;At this point, although nothing is rendered, because of the added log statement the current date is logged to the browser console. &lt;/p&gt;
&lt;h3 id=&quot;failing-polymer-import-continued&quot;&gt;&lt;a href=&quot;#failing-polymer-import-continued&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Failing Polymer import, continued&lt;/h3&gt;
&lt;p&gt;Now the import succeeds and it is clear that the TypeScript compiler correctly processes PolygramApp.ts, it is time to
try to fix the import of the &lt;code class=&quot;language-text&quot;&gt;Polymer&lt;/code&gt; module in PolygramApp.ts.&lt;/p&gt;
&lt;p&gt;A possible workaround will be to not try to import HTML imports in the TypeScript file, but instead to supply those dependencies
through the HTML that is importing the TypeScript file. To do this, I change the respective files to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- polygram-app.html --&gt;&lt;/span&gt;
...

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dom-module&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;polygram-app&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    ...
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Script&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; PolygramAppFactory &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./PolygramApp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; PolygramApp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; PolygramAppFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;customElements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PolygramApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PolygramApp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dom-module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// PolygramApp.ts&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; format &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; label&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Current Date: &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PolygramApp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Element&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;polygram-app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                today&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; label &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;YYYY-MM-DD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; create &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Now everything compiles without errors and the custom elements are rendered again!&lt;/p&gt;
&lt;p&gt;Note here that I also added a &lt;code class=&quot;language-text&quot;&gt;string&lt;/code&gt; type to &lt;code class=&quot;language-text&quot;&gt;const label&lt;/code&gt; to see if typings work.&lt;/p&gt;
&lt;h3 id=&quot;re-enabling-redux&quot;&gt;&lt;a href=&quot;#re-enabling-redux&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Re-enabling Redux&lt;/h3&gt;
&lt;p&gt;Earlier, Redux was disabled to test Webpack. It was failing with the runtime error &lt;code class=&quot;language-text&quot;&gt;Uncaught ReferenceError: PolymerRedux 
is not defined&lt;/code&gt; To re-enable it, I convert the &lt;code class=&quot;language-text&quot;&gt;polymer-redux/polymer-redux.html&lt;/code&gt; from
bower_components to a local PolymerRedux.js, by just removing the &lt;code class=&quot;language-text&quot;&gt;script&lt;/code&gt; tags.&lt;/p&gt;
&lt;p&gt;Because redux-mixin.html, action.html, and reducer.html actually are already JavaScript wrapped in &lt;code class=&quot;language-text&quot;&gt;script&lt;/code&gt; tags, I just convert
them to TypeScript files, for example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// ReduxMixin.ts&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;combineReducers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; compose&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; createStore&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;redux&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; PolymerRedux &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exports-loader?PolymerRedux!./PolymerRedux&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ReduxMixin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;PolymerRedux&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reduxStore&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;To use it in PolygramApp.ts, it can now be imported like a normal ES6 module:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// PolygramApp.ts&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; format &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; label&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Current Date: &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ReduxMixin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reduxStore&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./ReduxMixin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PolygramApp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReduxMixin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Element&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;polygram-app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Added Redux code here&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token function&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Added Redux code here&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; create &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;After making similar modifications for polygram-searchbox, the Redux events work again as before introducing TypeScript. &lt;/p&gt;
&lt;h2 id=&quot;importing-a-global-variable-from-html&quot;&gt;&lt;a href=&quot;#importing-a-global-variable-from-html&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Importing a global variable from HTML&lt;/h2&gt;
&lt;p&gt;At this point PolymerRedux is loaded from a custom PolymerRedux.js that I made in the previous step by removing the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&amp;gt;&lt;/code&gt;
tags from the file in bower_components. Although this works, it would be better to use the file in bower_components
directly because it will be easier to handle updates to this external package.&lt;/p&gt;
&lt;p&gt;Currently I import the custom PolymerRedux.js in state/ReduxMixin.ts with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; PolymerRedux &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exports-loader?PolymerRedux!./PolymerRedux&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;To load the HTML from the bower_components, I expect to have to use the polymer-webpack-loader to extract the JavaScript
from the &lt;code class=&quot;language-text&quot;&gt;script&lt;/code&gt; tags:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; PolymerRedux &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exports-loader?PolymerRedux!polymer-webpack-loader!../../bower_components/polymer-redux/dist/polymer-redux.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;This fails to compile with the message that PolymerRedux is undefined, so I add the &lt;a href=&quot;https://github.com/ianwalter/debug-loader&quot;&gt;debug-loader&lt;/a&gt; to
investigate what the result of each step looks like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; PolymerRedux &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exports-loader?PolymerRedux!polymer-webpack-loader!debug-loader?id=raw!../../bower_components/polymer-redux/dist/polymer-redux.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Thanks to debug-loader it is immediately clear that already before going into the polymer-webpack-loader the &lt;code class=&quot;language-text&quot;&gt;script&lt;/code&gt; tags have
been stripped. Just using require without any loaders turns something likes this &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&amp;gt;foo()&amp;lt;/script&amp;gt;&lt;/code&gt; into &lt;code class=&quot;language-text&quot;&gt;foo()&lt;/code&gt;
and webpack-polymer-loader is not needed in this case. I do think this only works when the file is completely self
contained and does not have dependencies with other Polymer HTML files.&lt;/p&gt;
&lt;p&gt;This is the final working import:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; PolymerRedux &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exports-loader?PolymerRedux!../../bower_components/polymer-redux/dist/polymer-redux.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;h2 id=&quot;linting&quot;&gt;&lt;a href=&quot;#linting&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Linting&lt;/h2&gt;
&lt;p&gt;Although there is a &lt;a href=&quot;https://github.com/Polymer/polymer-linter&quot;&gt;polymer-linter&lt;/a&gt;, it is &lt;a href=&quot;https://github.com/Polymer/polymer-linter#use-with-other-tools&quot;&gt;advised&lt;/a&gt; to
use Polymer Linter combined with other linters, and an obvious choice is TSLint.&lt;/p&gt;
&lt;p&gt;The way that TSLint is configured with Webpack means that it will only lint TypeScript that is not embedded in HTML:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// webpack.config.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TSLintPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    files&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./src/**/*.ts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// So, this requires none of the TS to be inline in HTML?&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Before I started with this experiment I thought this might be a problem. But now almost all script has been extracted to
separate TypeScript files anyway, so this works quite well. &lt;/p&gt;
&lt;p&gt;Of course it is also still possible to run TSLint manually for a file, e.g. &lt;code class=&quot;language-text&quot;&gt;./node_modules/.bin/tslint --config tslint.json polygram-marvel-details.ts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It is still required to run &lt;code class=&quot;language-text&quot;&gt;polymer lint&lt;/code&gt; manually. As far as I know there is no integration for Webpack yet.&lt;/p&gt;
&lt;h2 id=&quot;decorators&quot;&gt;&lt;a href=&quot;#decorators&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Decorators&lt;/h2&gt;
&lt;p&gt;I want to see if I can use &lt;a href=&quot;https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841&quot;&gt;ES decorators&lt;/a&gt;,
because decorators conceptually fit with the Mixin pattern used in Polymer
for e.g. &lt;code class=&quot;language-text&quot;&gt;class MyElement extends ReduxMixin(Polymer.Element)&lt;/code&gt;. It would be tidy if we could write this as a decorator,
especially if more mixins would need to be combined:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;@ReduxMixin
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyElement&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Element&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;As a test, I just add an &lt;a href=&quot;https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841&quot;&gt;example decorator&lt;/a&gt;
to the class in polygram-details.ts:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;    @readonly
    &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// This works, but prepends a polyfill to the output&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;just testing a decorator&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;And in the same file, but outside the class, the definition of the decorator:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;readonly&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; descriptor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    descriptor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; descriptor&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The compiler fails with: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the &amp;#39;experimentalDecorators&amp;#39; option to remove this warning.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;This flag can be added to the compilerOptions section of the tsconfig.json: &lt;code class=&quot;language-text&quot;&gt;&amp;#39;experimentalDecorators&amp;#39;: true&lt;/code&gt;. The
compilation now succeeds, but prepends a small polyfill for &lt;code class=&quot;language-text&quot;&gt;decorator&lt;/code&gt; to the output. Take this into account when using
decorator in many files, because it will cause an overhead that might be avoided by using a third party library that is
imported globally.&lt;/p&gt;
&lt;h2 id=&quot;app-vs-element&quot;&gt;&lt;a href=&quot;#app-vs-element&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;App vs Element&lt;/h2&gt;
&lt;p&gt;It is one thing to compile Typescript for a Polymer app, but another thing to use TypeScript for reusable Polymer components.&lt;/p&gt;
&lt;p&gt;The next step will be to compile the Polymer components in this test project separately. As a result, each converted
component should both be loaded into its own &lt;a href=&quot;https://github.com/PolymerElements/iron-component-page&quot;&gt;demo page&lt;/a&gt; and to be composed into a Polymer app.&lt;/p&gt;
&lt;p&gt;The demo pages should be accessible by running &lt;code class=&quot;language-text&quot;&gt;polymer serve&lt;/code&gt;, conform the normal Polymer workflow.&lt;/p&gt;
&lt;p&gt;When just running a Webpack build for the current project with &lt;code class=&quot;language-text&quot;&gt;./node_modules/.bin/webpack --config webpack.config.js&lt;/code&gt;, it will build a
&lt;code class=&quot;language-text&quot;&gt;dist&lt;/code&gt; dir containing amongst others an index.html and a bundle.js. This is a standalone app, but this would not be a good workflow to
distribute a Polymer component because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the index.html is a complete HTML document, not just a &lt;code class=&quot;language-text&quot;&gt;dom-module&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the bundle.js is one huge JavaScript blob that contains not only the compiled JavaScript for the component, but also all templates, TypeScript, Webpack and Polymer polyfills and libraries (like lodash in this case)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The polyfills and libraries need to be kept separate, so that they can be loaded once per project instead of once for every component.
The bundle.js is already 2.8MB in size (unminified) / 347kB (minified).&lt;/p&gt;
&lt;p&gt;Would it be possible to make a Polymer component that uses the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script src=&amp;quot;foo.js&amp;quot;&amp;gt;&lt;/code&gt; style import and then do a &quot;naive&quot;
compilation from foo.ts to foo.js? Let&apos;s first make a minimal example where the JavaScript is extracted from an Polymer
component:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using &lt;code class=&quot;language-text&quot;&gt;/polygram-details.html&lt;/code&gt; (this is the original, that the TypeScript+Webpack version in /src/ was based on) and &lt;code class=&quot;language-text&quot;&gt;/demo/polygram-details&lt;/code&gt; (already importing /polygram-details)&lt;/li&gt;
&lt;li&gt;Do not run webpack, but just &lt;code class=&quot;language-text&quot;&gt;polymer serve&lt;/code&gt; and test the demo page&lt;/li&gt;
&lt;li&gt;Replace &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&amp;gt;... code ...&amp;lt;/script&amp;gt;&lt;/code&gt; by &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script src=&amp;quot;polygram-details.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;, extract the JavaScript to
polygram-details.js and test the demo page again: this works.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now to TypeScript:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rename &lt;code class=&quot;language-text&quot;&gt;polygram-detail.js&lt;/code&gt; but leave the reference in &lt;code class=&quot;language-text&quot;&gt;polygram-details.html&lt;/code&gt; to point to the JavaScript version: &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script src=&amp;quot;polygram-details.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;The package &lt;code class=&quot;language-text&quot;&gt;typescript&lt;/code&gt; was already installed as a dependency, so use &lt;code class=&quot;language-text&quot;&gt;tsc&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;./node_modules/.bin/tsc polygram-details.ts&lt;/code&gt;.
This gives errors, but does generate code. The resulting code does not run.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first errors are:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;polygram-details.ts(8,31): error TS2304: Cannot find name &amp;#39;Polymer&amp;#39;.
polygram-details.ts(33,14): error TS2339: Property &amp;#39;_searchResult&amp;#39; does not exist on type &amp;#39;PolygramDetails&amp;#39;.
polygram-details.ts(35,18): error TS2339: Property &amp;#39;_searchIAUrl&amp;#39; does not exist on type &amp;#39;PolygramDetails&amp;#39;.
polygram-details.ts(42,18): error TS2339: Property &amp;#39;_searchResult&amp;#39; does not exist on type &amp;#39;PolygramDetails&amp;#39;.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Adding &lt;code class=&quot;language-text&quot;&gt;declare const Polymer: any;&lt;/code&gt; fixes these 4 errors. It tells TypeScript a global variable &lt;code class=&quot;language-text&quot;&gt;Polymer&lt;/code&gt; can be expected.  &lt;/p&gt;
&lt;p&gt;This leaves the following errors:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;polygram-details.ts(9,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
polygram-details.ts(13,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The current compilation seems to ignore the tsconfig.json, because a similar error was solved earlier by
adding &lt;code class=&quot;language-text&quot;&gt;&amp;quot;target&amp;quot;: &amp;quot;ESNext&amp;quot;&lt;/code&gt; in the config. The target can be specified with a flag: &lt;code class=&quot;language-text&quot;&gt;./node_modules/.bin/tsc --target ES6 polygram-details.ts&lt;/code&gt;.
This runs without errors and works in the browser!&lt;/p&gt;
&lt;h3 id=&quot;simple-compilation-and-webpack&quot;&gt;&lt;a href=&quot;#simple-compilation-and-webpack&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Simple compilation and Webpack&lt;/h3&gt;
&lt;p&gt;This much simpler approach without Webpack seems to provide a more realistic workflow. Can we afford to leave Webpack
out entirely? Let&apos;s reiterate its purpose:&lt;/p&gt;
&lt;h4 id=&quot;webpack-transpiles-to-es5-with-babel&quot;&gt;&lt;a href=&quot;#webpack-transpiles-to-es5-with-babel&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Webpack transpiles to ES5 with Babel&lt;/h4&gt;
&lt;p&gt;As mentioned before we don&apos;t need Babel for transpilation, the TypeScript compiler can be set to ES6 or ES5. &lt;/p&gt;
&lt;h4 id=&quot;webpack-provides-a-development-server-with-hot-module-reloading&quot;&gt;&lt;a href=&quot;#webpack-provides-a-development-server-with-hot-module-reloading&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Webpack provides a development server with hot module reloading&lt;/h4&gt;
&lt;p&gt;Hot Module Replacement is mainly to ease development, but we can use livereload combined with polyserve instead which would be acceptable for this use case.  &lt;/p&gt;
&lt;h4 id=&quot;webpack-handles-module-bundling&quot;&gt;&lt;a href=&quot;#webpack-handles-module-bundling&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Webpack handles module bundling&lt;/h4&gt;
&lt;p&gt;We can do without ES6 modules or packaging other resources like images as JavaScript modules, because we already have to
deal with Polymer Elements as a component platform. We have to distribute the end result as Polymer Elements to be able to add it to the catalog.&lt;/p&gt;
&lt;p&gt;Although Polymer 3 will use ES6 modules, a tool is supposed to become available that can migrate from elements from Polymer 2 to Polymer 3 syntax.&lt;/p&gt;
&lt;p&gt;Without Webpack we lose the module polyfill that is injected per file, which potentially saves a significant size overhead, whilst staying closer to the concept of Polymer Element development.&lt;/p&gt;
&lt;p&gt;Global JavaScript variables from external modules can be made accessible with the &lt;code class=&quot;language-text&quot;&gt;declare&lt;/code&gt; placeholder, and it is still
possible to use &lt;code class=&quot;language-text&quot;&gt;import&lt;/code&gt; to import from &lt;code class=&quot;language-text&quot;&gt;node_modules&lt;/code&gt;.
However, when module is set to &lt;code class=&quot;language-text&quot;&gt;none&lt;/code&gt; in the tsconfig.json, the variable will just be put onto the &quot;global&quot; scope. This is
not the &lt;em&gt;true&lt;/em&gt; global scope, because it is still contained within the Polymer element, so the variable will be on the Polymer
Element scope, and should not leak to the actual global scope. &lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Import&lt;/code&gt; should still be used with caution: it will lead to code duplication if 2 Polymer+TypeScript elements import the
same dependency. In that case it would be better to import that dependency via HTML import because the Polymer compiler can deduplicate it.&lt;/p&gt;
&lt;p&gt;Webpack can also be used to package CSS as modules, but for encapsulating CSS in Polymer the
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM&quot;&gt;Shadow DOM&lt;/a&gt; can be used. This is actually an
aspect of web components that is very well executed.&lt;/p&gt;
&lt;h3 id=&quot;automatic-compilation&quot;&gt;&lt;a href=&quot;#automatic-compilation&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Automatic compilation&lt;/h3&gt;
&lt;p&gt;Without Webpack, it is unpractical that for every change to a TypeScript file a manual transformation is needed. Following
the example in the previous section, each time &lt;code class=&quot;language-text&quot;&gt;polygram-details.ts&lt;/code&gt; changes, &lt;code class=&quot;language-text&quot;&gt;./node_modules/.bin/tsc --target ES6 polygram-details.ts&lt;/code&gt;
must be run. Let&apos;s try to automate this without using Webpack.&lt;/p&gt;
&lt;h4 id=&quot;with-tsc&quot;&gt;&lt;a href=&quot;#with-tsc&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;With tsc&lt;/h4&gt;
&lt;p&gt;First I make a new tsconfig named &lt;code class=&quot;language-text&quot;&gt;tsconfig.inline.json&lt;/code&gt; for this use case:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sourceMap&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ES6&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;include&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;*.ts&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;To compile run &lt;code class=&quot;language-text&quot;&gt;./node_modules/.bin/tsc -w -p tsconfig.inline.json&lt;/code&gt;. The &lt;code class=&quot;language-text&quot;&gt;-w&lt;/code&gt; flag keeps the process running and watches for
changes in the included TypeScript files. &lt;/p&gt;
&lt;p&gt;An interesting side-effect occurs. Naturally, each TypeScript file is going to need the &lt;code class=&quot;language-text&quot;&gt;declare const Polymer: any;&lt;/code&gt;
declaration as a workaround for the fact that the Polymer dependency can&apos;t be imported (see previous sections). But
because we now use &lt;code class=&quot;language-text&quot;&gt;-p&lt;/code&gt;, the project flag, the compiler expects all files share global scope. And the second file
using &lt;code class=&quot;language-text&quot;&gt;declare const Polymer: any;&lt;/code&gt; will get an error: &lt;code class=&quot;language-text&quot;&gt;Cannot redeclare block-scoped variable &amp;#39;Polymer&amp;#39;&lt;/code&gt;. How can we use
the project flag, without letting the compiler share the global scope between all TypeScript files?&lt;/p&gt;
&lt;p&gt;A workaround would be to create a TypeScript file that just imports/declares all the expected global variables once.
This would make the code less transparent at best and it might even create other scoping issues.&lt;/p&gt;
&lt;h3 id=&quot;custom-compilation&quot;&gt;&lt;a href=&quot;#custom-compilation&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Custom compilation&lt;/h3&gt;
&lt;p&gt;As an alternative let&apos;s try to run compilation with an isolated scope for each TypeScript file. &lt;a href=&quot;https://github.com/Microsoft/TypeScript/issues/1516&quot;&gt;This issue&lt;/a&gt;
explains that this would be possible by supplying a tsconfig.json for each scope. That would be doable for a limited set
of scopes that is static over time (e.g. a back-end codebase and a front-end codebase in the same project).
However, it makes no sense from a maintenance standpoint for the current project as it would need a tsconfig.json
for each Polymer element.&lt;/p&gt;
&lt;p&gt;To be complete, I did try this out. First, set up a base tsconfig that can be inherited:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;// base.json
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sourceMap&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ESNext&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;moduleResolution&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;experimentalDecorators&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Now for each Polymer TypeScript file a tsconfig, e.g.:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;// polygram-details.tsconfig.json
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;extends&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./base.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;files&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;./polygram-details.ts&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;It is now possible to compile/watch polygram-details.ts with &lt;code class=&quot;language-text&quot;&gt;tsc -w -p polygram-details.tsconfig.json&lt;/code&gt;, but it is
still not possible to compile/watch multiple tsconfigs at &lt;em&gt;the same time&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In this case it would be better to forget about the watch flag &lt;code class=&quot;language-text&quot;&gt;-w&lt;/code&gt; altogether and just use &lt;code class=&quot;language-text&quot;&gt;npm watch&lt;/code&gt; combined with
&lt;code class=&quot;language-text&quot;&gt;tsc [changedfile]&lt;/code&gt;. You can&apos;t use a tsconfig.json combined with an input file path for tsc, so all options must be
supplied as flags: &lt;code class=&quot;language-text&quot;&gt;tsc --target ES6 --sourceMap [changedFile]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I tried combining this compilation one-liner with a watch script, but I could not get this to work with &lt;a href=&quot;https://www.npmjs.com/package/nodemon&quot;&gt;nodemon&lt;/a&gt;,
&lt;a href=&quot;https://www.npmjs.com/package/npm-watch&quot;&gt;npm-watch&lt;/a&gt; or &lt;a href=&quot;https://www.npmjs.com/package/watch&quot;&gt;watch&lt;/a&gt;, so I wrote a small script:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// ts-poly-watch.js, run with: node ts-poly-watch.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; watch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;watch&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;path&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; chalk &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;chalk&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tsc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;node-typescript-compiler&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

watch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMonitor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; interval&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;monitor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chalk&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gray&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bgGreen&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;TS-POLY-WATCH started&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    monitor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;changed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; curr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; prev&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ext &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;extname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ext &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.ts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; changed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            tsc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token string&quot;&gt;&apos;target&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ES6&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token string&quot;&gt;&apos;sourceMap&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                f
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Now it is possible to watch each TypeScript file and compile it with its scope isolated from the other TypeScript files.&lt;/p&gt;
&lt;h2 id=&quot;twc&quot;&gt;&lt;a href=&quot;#twc&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;twc&lt;/h2&gt;
&lt;p&gt;With &lt;code class=&quot;language-text&quot;&gt;ts-poly-watch.js&lt;/code&gt; it looks like we finally have an acceptable working environment. I have extracted the script to
its own project &lt;a href=&quot;https://github.com/mdvanes/typescript-batch-compiler&quot;&gt;typescript-batch-compiler&lt;/a&gt; and &lt;a href=&quot;https://www.npmjs.com/package/typescript-batch-compiler&quot;&gt;npm package&lt;/a&gt; because
there is much room for improvement and it will be easier to use in other projects if it is an npm package.&lt;/p&gt;
&lt;p&gt;So are we now done? In fact there is one more thing I want to explore. During the research I ran into &lt;a href=&quot;https://github.com/Draccoz/twc&quot;&gt;twc&lt;/a&gt;.
This is a compiler for &lt;em&gt;TypeScript Web Components&lt;/em&gt; and can be used to compile TypeScript classes to Polymer 2 elements.
Although this sounds like it is similar to my &lt;code class=&quot;language-text&quot;&gt;typescript-batch-compiler&lt;/code&gt;, here are some preliminary findings:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It assumes a TypeScript file as the entrypoint: in my setup I still stay close to the Polymer setup with a
Polymer element (so HTML) that includes a script file. With &lt;code class=&quot;language-text&quot;&gt;twc&lt;/code&gt; the entrypoint is a TypeScript file that imports an HTML template.
A great advantage is that this is more like Polymer 3 and also similar to other component driven frameworks
like React, Vue and Angular. The disadvantage is of course that the style will be foreign to other Polymer developers.&lt;/li&gt;
&lt;li&gt;It&apos;s still very experimental. There is no example in the repo or an explanation of how to set up a basic element in the
README, but a general approach is outlined &lt;a href=&quot;https://github.com/Draccoz/twc/wiki/Creating-a-simple-component&quot;&gt;on the project wiki&lt;/a&gt;
and examples of twc in a project can be found in &lt;a href=&quot;https://github.com/mlisook/generator-polymer-init-twc-starter-kit&quot;&gt;this generator project&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With the aforementioned wiki, I take these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;twc&lt;/code&gt; in a new subdir of the project appropriately named &quot;twc&quot;&lt;/li&gt;
&lt;li&gt;Set up a very basic polygram-twc.ts conforming to the style as outlined in the wiki:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// polygram-twc.ts&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; CustomElement &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;twc/polymer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;bower:polymer/polymer-element.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * `online-state`
 * Lets you select an online state (online or offline) and reflect the change on a host attribute.
 *
 * @customElement
 * @polymer
 * @demo demo/index.html
 */&lt;/span&gt;
@&lt;span class=&quot;token function&quot;&gt;CustomElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OnlineState&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Polymer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Element&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    prop1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;online-state&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
          &amp;lt;style&gt;
            :host {
              display: block;
            }
          &amp;lt;/style&gt;
          &amp;lt;h2&gt;Hello [[prop1]]!&amp;lt;/h2&gt;
        `&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;tsc --init&lt;/code&gt; to create a new tsconfig.json in the twc dir. This turns out to be important. When I re-use my existing
tsconfig.json the build fails with &lt;code class=&quot;language-text&quot;&gt;Error: Debug Failure.&lt;/code&gt;. This seems to be caused by the line &lt;code class=&quot;language-text&quot;&gt;&amp;quot;moduleResolution&amp;quot;: &amp;quot;node&amp;quot;&lt;/code&gt;,
which is not needed for this compilation.&lt;/li&gt;
&lt;li&gt;Add &lt;code class=&quot;language-text&quot;&gt;node_modules/twc/types/polymer.decorators.d.ts&lt;/code&gt; to the include section of the tsconfig.json, to resolve certain types.&lt;/li&gt;
&lt;li&gt;Build in the twc dir by running &lt;code class=&quot;language-text&quot;&gt;../node_modules/.bin/twc polygram-twc.ts&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A polygram-twc.html is created.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also converted the original polygram-details.html (the one with embedded JavaScript) to this format. See the result
in &lt;a href=&quot;https://github.com/mdvanes/polygram/tree/TypeScript/twc&quot;&gt;the repo for this experiment&lt;/a&gt;. When working on this
conversion, some differences with normal web components become apparent:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;twc auto-injects the registration of the component: &lt;code class=&quot;language-text&quot;&gt;customElements.define(PolygramDetails.is, PolygramDetails);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;import &amp;#39;./polygram-ui-details&amp;#39;;&lt;/code&gt; is converted to &lt;code class=&quot;language-text&quot;&gt;&amp;lt;link rel=&amp;quot;import&amp;quot; href=&amp;quot;./polygram-ui-details.html&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the &lt;code class=&quot;language-text&quot;&gt;is&lt;/code&gt; getter, i.e. this: &lt;code class=&quot;language-text&quot;&gt;static get is() { return &amp;#39;polygram-details&amp;#39;; }&lt;/code&gt;
is auto generated from the class name.&lt;/li&gt;
&lt;li&gt;The JSDoc is converted to an HTML comment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This syntax uses plain ES modules and is therefore also closer to Polymer 3. Still there are some differences.
Compare the code for polygram-twc.ts but in &lt;a href=&quot;https://www.polymer-project.org/blog/2017-08-23-hands-on-30-preview&quot;&gt;Polymer 3 syntax&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// PolymerElement is its own module now, instead of a property of the Polymer namespace. Also, bower is no longer used.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Element &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; PolymerElement &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@polymer/polymer/polymer-element&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Aside from inline templates, this syntax can be used too:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//import * as view from &apos;./app.template.html&apos;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OnlineState&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PolymerElement&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Property must be defined in the constructor, but this might be a difference with TypeScript and not Polymer 3.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prop1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;online-state&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// I don&apos;t know where the &amp;lt;style&gt; element should go.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`&amp;lt;h2&gt;Hello [[prop1]]!&amp;lt;/h2&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Or when using an import:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//return view;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Although I can&apos;t find any sources, I heard that Polymer 3 would supply an auto converter from (normal) Polymer 2 syntax.
You could use that converter on the output of twc, so this should not be a reason to avoid twc.&lt;/p&gt;
&lt;h2 id=&quot;final-remarks&quot;&gt;&lt;a href=&quot;#final-remarks&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;Unit testing and coverage support when using TypeScript has not been mentioned, but I hope it is clear that it is
unchanged from a normal Polymer 2 application when using typescript-batch-compiler. You can just use
&lt;a href=&quot;https://github.com/Polymer/web-component-tester&quot;&gt;WCT&lt;/a&gt;), because all components
are compiled to a state that conforms to a non-TypeScript Polymer 2 situation.&lt;/p&gt;
&lt;p&gt;For the Webpack approach it would be an improvement to see why &lt;code class=&quot;language-text&quot;&gt;polymer-webpack-loader&lt;/code&gt; is not importing Polymer when
using &lt;code class=&quot;language-text&quot;&gt;import Polymer from &amp;#39;../bower_components/polymer/polymer-element.html&amp;#39;&lt;/code&gt;
or &lt;code class=&quot;language-text&quot;&gt;import &amp;#39;../bower_components/polymer/polymer-element.html&amp;#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It could also be an improvement to add the &lt;a href=&quot;https://www.npmjs.com/package/tslint-plugin-prettier&quot;&gt;prettier&lt;/a&gt; plugin to promote a
consistent coding style. This could be added to TSLint via Webpack, but could also be integrated in the
typescript-batch-compiler package.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[npm without internet]]></title><description><![CDATA[It's easy to run npm to install packages even on a system without internet access, or behind a corporate firewall. First note that  npm has…]]></description><link>https://mdworld.nl/mdworld-jackson//npm-without-internet</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//npm-without-internet</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Mon, 06 Jul 2015 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s easy to run npm to install packages even on a system without internet access, or behind a corporate firewall. First note that &lt;a href=&quot;http://jjasonclark.com/how-to-setup-node-behind-web-proxy/&quot;&gt;npm has proxy settings&lt;/a&gt;, so if you have access to the correct credentials, try that first.&lt;/p&gt;
&lt;p&gt;Let&apos;s assume you&apos;re developing a web application and you use &lt;a href=&quot;http://gruntjs.com/&quot;&gt;Grunt&lt;/a&gt; for managing jshint and uglify tasks. This requires the npm package grunt-cli to be installed globally. All the other packages (i.e. jshint and uglify) can be run locally, so it&apos;s sufficient to copy node_modules with these packages from another installation.&lt;/p&gt;
&lt;p&gt;Assuming you have another system with internet access/no proxy, and you have a working project with all the packages there:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Zip the node_modules in the project dir to e.g. node_modules.zip.&lt;/li&gt;
&lt;li&gt;Go to %userprofile%\AppData\Roaming\npm\node_modules\grunt-cli\&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;npm pack&lt;/code&gt; this should result in a grunt-cli-x.y.z.tgz&lt;/li&gt;
&lt;li&gt;Collect the node_modules.zip, grunt-cli-x.y.z.tgz and &lt;a href=&quot;http://nodejs.org&quot;&gt;Node.js&lt;/a&gt; installer and place them on the target system (e.g. by local network or usb drive).&lt;/li&gt;
&lt;li&gt;Prepare the project dir on the target system, e.g. from a Git repo on the network or from scratch. The Gruntfile.js and package.json should already be in the root of the project.&lt;/li&gt;
&lt;li&gt;Install &lt;a href=&quot;http://nodejs.org&quot;&gt;Node.js&lt;/a&gt; on the target system. This should also install npm. Check this with &lt;code class=&quot;language-text&quot;&gt;node -v&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;npm -v&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Unpack the node_modules.zip into the project dir, such that &amp;#x3C;project&gt;/node_modules contains e.g. grunt-contrib-jshint.&lt;/li&gt;
&lt;li&gt;Place grunt-cli-x.y.z.tgz in some temporary dir, e.g. \tmp and run &lt;code class=&quot;language-text&quot;&gt;npm i -g grunt-cli-x.y.z.tgz&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Grunt should now be installed globally, try &lt;code class=&quot;language-text&quot;&gt;grunt --version&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now it should be possible to run &lt;code class=&quot;language-text&quot;&gt;grunt&lt;/code&gt; in the project dir.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you want to do a lot of offline installations, you might want to +1 &lt;a href=&quot;https://github.com/npm/npm/issues/4210&quot;&gt;this issue&lt;/a&gt;. It explains the process of doing several pack and install steps and how this could be simplified by extending the pack feature to also zip all the depencies of a package.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[KnockoutJS and ES6]]></title><description><![CDATA[In the past year I've made some ES6 projects, for instance  HomeRemote , an ES6 flavored React project. My company mainly uses a KnockoutJS…]]></description><link>https://mdworld.nl/mdworld-jackson//knockout-js-and-es-6</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//knockout-js-and-es-6</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Mon, 04 Jul 2016 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the past year I&apos;ve made some ES6 projects, for instance &lt;a href=&quot;https://bitbucket.org/mdvanes/homeremote&quot;&gt;HomeRemote&lt;/a&gt;, an ES6 flavored React project. My company mainly uses a KnockoutJS based theme and it would be an improvement to introduce ES6 to this theme. The combination of Knockout and ES6 is not very common, so I&apos;ve summarized my endeavors.&lt;/p&gt;
&lt;h1 id=&quot;precompiling-with-webpack&quot;&gt;&lt;a href=&quot;#precompiling-with-webpack&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Precompiling with Webpack&lt;/h1&gt;
&lt;p&gt;Because I want to use ES6 classes and native modules, which are respectively &lt;em&gt;not well&lt;/em&gt; and &lt;em&gt;not at all&lt;/em&gt; supported cross browser, I will use a transpiler. Because I will want to look into component based development, I choose &lt;a href=&quot;https://webpack.github.io/&quot;&gt;Webpack&lt;/a&gt;, also because it is pluggable and has e.g. Typescript support.&lt;/p&gt;
&lt;p&gt;Although I am aware of the advantages of TypeScript and it&apos;s adoption should increase with the advent of Angular 2, I will stick with plain ES6 for the moment, to stay as close as possible to the native syntax.&lt;/p&gt;
&lt;p&gt;It is not very clear how to install all the needed dependencies for ES6 compilation with Webpack. It does give feedback on missing modules when running, so with some trial and error, this should be the installer command:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i --save-dev webpack webpack-dev-server webpack-merge grunt-webpack babel-core babel-loader babel-preset-2015&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Because &lt;a href=&quot;https://github.com/gruntjs/grunt-contrib-jshint&quot;&gt;JShint&lt;/a&gt; and &lt;a href=&quot;https://github.com/jscs-dev/grunt-jscs&quot;&gt;JSCS&lt;/a&gt; do not support ES6 syntax, I replace them with &lt;a href=&quot;https://github.com/jscs-dev/grunt-jscs&quot;&gt;ESlint&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i --save-dev grunt-eslint&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I integrate Webpack and ESlint into Grunt, this is very straight-forward:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;eslint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        configFile&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.eslintrc&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    dev&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;_js/**/*.js&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

webpack&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; webpackConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    build&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        progress&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        plugins&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Both Webpack and ESlint changed the syntax for their configuration since the last time I used it, my configs look like this now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Webpack 1.13.0&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;path&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; merge &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;webpack-merge&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; webpack &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;webpack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; common &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    entry&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./_js/app.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    resolve&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        extensions&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    output&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        filename&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;bundle.js&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    devtool&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;source-map&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    module&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        loaders&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                test&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;/\.js$/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                loader&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;babel-loader&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                query&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    presets&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;es2015&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; common&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;ESlint (grunt-eslint 18.1.0)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;parserOptions&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ecmaVersion&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sourceType&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ecmaFeatures&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;env&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;browser&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;es6&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;rules&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;no-bitwise&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;curly&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;eqeqeq&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;no-use-before-define&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;new-cap&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;no-caller&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;no-undef&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;no-unused-vars&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;&quot;args&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;no-trailing-spaces&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;strict&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;quotes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;single&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;complexity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;h1 id=&quot;the-entrypoint&quot;&gt;&lt;a href=&quot;#the-entrypoint&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Entrypoint&lt;/h1&gt;
&lt;p&gt;The file app.js is the main entrypoint. It imports all the factories and classes as dependencies and registers them to our application API (bqApp). E.g.:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; otherCustomModelFactory &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./es6/viewmodels/otherCustomModelFactory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; otherCustomTemplateFactory &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./es6/otherCustomTemplateFactory&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bqApp &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; blueriq&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    bqApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;modelFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;otherCustomModelFactory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    bqApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;templateFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerModelHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;otherCustomTemplateFactory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The registering used to be done in e.g. the customModelFactory file itself, but when using ES6 modules, I started to notice how this requires a dependency to bqApp in the customModelFactory file, while it&apos;s only needed for registering the factory. For the sake of
high cohesion, I decided to export the finished factory and register it in the app.js instead.&lt;/p&gt;
&lt;p&gt;In advance, one of my main concerns was handling existing variables that the application API puts on the global scope, because the API is not yet in ES6 style. Fortunately, in contrast to Typescript it is not needed to have typing definitions, making it trivial to mix ES5 and ES6 libraries in one app. Because ES6 modules are used in the app.js, it is no longer needed to use an IIFE for scoping (the ES6 modules are scoped at the file level anyway) or strict mode declaration (implicit, because strict mode indicates ES5 syntax). This does mean I need an alternative way to reference global variables. E.g. the bqApp variable is put on the global scope by the application API, which I can&apos;t change at the moment, instead of being exposed as an importable module. Supposedly, it would be possible to wrap it in a file that converts the global to a module. For the short term I see two options, though:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/* global bqApp:false */&lt;/code&gt; - this works because the var is on the global scope, it&apos;s just ESlint who warns for undefined variables.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;const bqApp = window.bqApp;&lt;/code&gt; - explicitly reassinging to a local variable, which is basically what I used to do when supplying window.bqApp as a parameter to an IIFE, and then declaring bqApp as an argument in that IIFE.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the moment I will stick with option 1, although I have included an example of both just to be complete.&lt;/p&gt;
&lt;h1 id=&quot;viewmodels-and-the-viewmodel-factory&quot;&gt;&lt;a href=&quot;#viewmodels-and-the-viewmodel-factory&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Viewmodels and the viewmodel factory&lt;/h1&gt;
&lt;p&gt;Most viewmodels that we use extend from some existing viewmodel that is build into the application API, such as blueriq.models.BaseModel. A very simple example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ko&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; blueriq&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;FooModel&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; self &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        blueriq&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;models&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BaseModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ko&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blueriq&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;As said, I was concerned about using existing variables from the application API. I had no idea how the ES6 &quot;extend&quot; would convert to ES5, but fortunately it seems to be backwards compatible with the approach above, because this simply works:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* globals blueriq:false */&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// I want to extend blueriq.models.dashboard.PageModel (which is an old-fashioned ES5 class). This works!&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PageModel&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;blueriq&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;models&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dashboard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PageModel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;new es6 PageModel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; PageModel&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Now PageModel can be imported into the modelFactory, which decides what viewModel to use based on properties of the provided model.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; PageModel &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./PageModel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;otherCustomModelFactory&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;otherCustomModelFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;page&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PageModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; otherCustomModelFactory&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;It has already been shown how otherCustomModelFactory is imported and registered in app.js.&lt;/p&gt;
&lt;h1 id=&quot;templates&quot;&gt;&lt;a href=&quot;#templates&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Templates&lt;/h1&gt;
&lt;p&gt;Creating a templateFactory, which decides what template to use based on properties of the provided model, is nearly identical to the modelFactory:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* globals blueriq */&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;otherCustomTemplateFactory&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;otherCustomTemplateFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;viewModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;viewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;field&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;themes/myTheme/template/field&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; otherCustomTemplateFactory&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;At this moment, the factory just returns the id of the template. The template itself is requested from the filesystem by the &lt;a href=&quot;https://github.com/ifandelse/Knockout.js-External-Template-Engine&quot;&gt;koExternalTemplateEngine&lt;/a&gt; (this project has been retired for several years now) or with a custom solution that reads the template from a file that contains all templates. A very important improvement that could be made here is using Webpack to resolve the paths to the templates. It should be possible to write a custom loader that retrieves the contents of a template that is being imported, e.g. like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* globals blueriq */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; fieldTemplate &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./template/field.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;otherCustomTemplateFactory&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;otherCustomTemplateFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;viewModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;viewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;field&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; fieldTemplate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; otherCustomTemplateFactory&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;h1 id=&quot;custom-binding-handlers&quot;&gt;&lt;a href=&quot;#custom-binding-handlers&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Custom Binding Handlers&lt;/h1&gt;
&lt;p&gt;Knockout &lt;a href=&quot;http://knockoutjs.com/documentation/custom-bindings.html&quot;&gt;handlers&lt;/a&gt; need to be registered to ko.bindingHandlers, e.g. like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;ko&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bindingHandlers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickTester &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;init&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;you clicked it!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;If I would put this in a module, nothing would be exported. I still need to look into how the system would handle this. Probably it will just execute adding the bindinghandler and return nothing, but for the moment I just export the body of the handler and import and register it in our app.js.&lt;/p&gt;
&lt;p&gt;In handlers/clickTester.js:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* globals $:false */&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; clickTester &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    init&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;You clicked the ES6 KO Handler!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;In app.js:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;clickTester&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./es6/handlers/clickTester&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ko&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bindingHandlers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickTester &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; clickTester&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;h1 id=&quot;follow-up&quot;&gt;&lt;a href=&quot;#follow-up&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Follow up&lt;/h1&gt;
&lt;p&gt;I still need to improve the registration of handlers, I don&apos;t know if I want them all in my app.js or maybe in a separate file. In that case I will need to figure out how to export &quot;nothing&quot; to my app.js, otherwise the import statement might fail.&lt;/p&gt;
&lt;p&gt;So far, our product does not use Knockout components. The style of component based development is very similar to React or Angular 2.0 components, although in practice, it might be closer to Angular 1.x directives. It would be interesting to see how it would translate to the ES6 syntax.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Gaining Root Access to Smart Home Gateway]]></title><description><![CDATA[Recently I bought a Risco Smart Home Gateway, and as I expected it is a rebranded off-the-shelf micro computer. 
When delivered, the HDMI…]]></description><link>https://mdworld.nl/mdworld-jackson//gaining-root-access-to-smart-home-gateway</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//gaining-root-access-to-smart-home-gateway</guid><category><![CDATA[mypc]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Wed, 08 May 2019 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I bought a Risco Smart Home Gateway, and as I expected it is a rebranded off-the-shelf micro computer.
When delivered, the HDMI and optical S/PDIF outputs and IR input hinted that it was not just a dedicated smart home
gateway. The OS seems to be loaded from a micro SD card, comparable to e.g. a Raspberry Pi. Also, the z-wave
controller is just a USB dongle and not built-in.&lt;/p&gt;
&lt;p&gt;After configuring, its network interface shows up on my router as SolidRun. A quick search finds the SolidRun CuBox-i, most
probably the &lt;a href=&quot;https://developer.solid-run.com/products/cubox-i/&quot;&gt;CuBox i2eX or CuBox i4p&lt;/a&gt;, because it also has an eSata port.&lt;/p&gt;
&lt;p&gt;These range from $100 - $150. Not too bad, considering the Risco Smart Home Gateway is around €300. Of course, this
includes a z-wave adapter (around €50) and their special software. Their software is actually much less flexible
than e.g. &lt;a href=&quot;https://www.domoticz.com/&quot;&gt;Domoticz&lt;/a&gt;, but I am sure it makes up for that in security and robustness.&lt;/p&gt;
&lt;p&gt;Solid Run has a &lt;a href=&quot;https://developer.solid-run.com&quot;&gt;community site&lt;/a&gt; for developers with plenty of information.&lt;/p&gt;
&lt;p&gt;The CuBox is an ARM micro computer with an FreeScale i.MX6 SoC and that means it can run several flavors of Linux,
&lt;a href=&quot;https://kodi.wiki/view/SolidRun_CuBox-i&quot;&gt;Kodi&lt;/a&gt; and in theory and old version of &lt;a href=&quot;http://forum.solid-run.com/android-os-on-cubox-i-and-hummingboard-f6/&quot;&gt;Android&lt;/a&gt;.
An in-depth review can be found &lt;a href=&quot;https://www.androidauthority.com/cubox-review-587011/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I won&apos;t judge the performance or review it further, but it might be worth mentioning that by know it is at least
superseded by the Raspberry Pi 4, because it can play h265 video.&lt;/p&gt;
&lt;p&gt;Now if you are bored with your Risco Smart Home you could just install a different image on the micro SD card and
use it as a media player or something, but let&apos;s see if we can gain more control over it as is. &lt;/p&gt;
&lt;p&gt;You could use Wireshark to intercept messages between the Risco Smart Home device and the alarm system, but first
I want to try to SSH in and/or inspect the software it is running.&lt;/p&gt;
&lt;p&gt;In this post, I will display the IP as 192.168.0.xxx. Accessing that IP in the browser shows nothing running on port
80, but the IP is pingable.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;nmap -v -sT 192.168.0.xxx&lt;/code&gt; on the IP shows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PORT     STATE SERVICE
22/tcp   open  ssh
8080/tcp open  http-proxy
8443/tcp open  https-alt&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Opening &lt;a href=&quot;http://192.168.0.xxx:8080&quot;&gt;http://192.168.0.xxx:8080&lt;/a&gt; in the browser it redirects to &lt;a href=&quot;http://192.168.0.xxx:8443/static/index.html&quot;&gt;http://192.168.0.xxx:8443/static/index.html&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;HTTP ERROR 404

Problem accessing /static/index.html. Reason:

    Not Found

Powered by Jetty://&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Opening &lt;a href=&quot;https://192.168.0.xxx:8443&quot;&gt;https://192.168.0.xxx:8443&lt;/a&gt; in the browser gives the same as 8080, but with SSL. It uses a self-signed
certificate by &lt;a href=&quot;https://www.openhab.org/&quot;&gt;openHAB&lt;/a&gt;. This is open-source home automation software and this may be useful
if we gain access to the device!&lt;/p&gt;
&lt;p&gt;It is possible to create an SSH connection, but it requests a password. Trying some default root passwords failed. Now
we know the certificate is from openHAB, maybe the CuBox is running openHAB? The default
credentials &lt;code class=&quot;language-text&quot;&gt;openhabian/openhabian&lt;/code&gt; do not work.&lt;/p&gt;
&lt;p&gt;It may be possible to inspect the micro SD to get more information. When disconnecting the gateway from power/utp
the alarm does not go off (good!), and the micro SD can be inspected on a different machine:&lt;/p&gt;
&lt;p&gt;The micro sd has several partitions: boot, postgre, rootfs, and scratch.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;rootfs:&lt;/em&gt; there is a &lt;code class=&quot;language-text&quot;&gt;/home&lt;/code&gt; dir, but it is empty.
there is a &lt;code class=&quot;language-text&quot;&gt;/linuxrc&lt;/code&gt; dir that seems to point at &lt;code class=&quot;language-text&quot;&gt;bin/busybox&lt;/code&gt;. This seems to be a &lt;a href=&quot;https://www.busybox.net/&quot;&gt;BusyBox&lt;/a&gt; installation.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;scratch:&lt;/em&gt; contains some ssh certificates. Copied to local disk.&lt;/p&gt;
&lt;p&gt;After reconnecting the gateway to power and UTP the message &quot;Communication with the Gateway failed.&quot; is shown in Risco cloud.
After a couple of minutes it works fine. However, the button controller that was paired (that did not work) is not
showing up anymore. The Fibaro plug does show up and still works as expected.&lt;/p&gt;
&lt;p&gt;It is not possible to login with default BusyBox credentials, so after disconnecting again, taking a closer look at the
volume &lt;em&gt;scratch&lt;/em&gt;: it contains a file &lt;code class=&quot;language-text&quot;&gt;@ssh/sshd_config&lt;/code&gt; with a line &lt;code class=&quot;language-text&quot;&gt;PermitRootLogin yes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So assuming this is the SSH config that is used runtime, we need to somehow find the root password, and then we can SSH with &lt;code class=&quot;language-text&quot;&gt;ssh root@192.168.0.xxx&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Following this &lt;a href=&quot;https://superuser.com/questions/1135128/what-is-default-username-and-passoword-for-busyboxs-ftpd&quot;&gt;suggestion&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;see the /etc/shadow or /etc/passwd (if the /etc/shadow not exist) with texteditor&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I found that, indeed, &lt;code class=&quot;language-text&quot;&gt;/etc/shadow&lt;/code&gt; contains (values are fake):&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;root:$1$foo$bar:10933:0:99999:7:::&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;So there is in fact a root entry with a hashed password visible.
One option would be to update the hash string with a hash string of a password that we already know, a method I used
years ago when adding users for a deprecated application by directly inserting lines into a database table. However,
I have no idea what effect this would have on an OS, so I would prefer to refrain from modifying the filesystem at this
point. Additionally, assuming that the provided SD card image always uses the same root password, it would be valuable
to know the password to be able to log into other devices.&lt;/p&gt;
&lt;p&gt;Another option would be to try to retrieve the password from the root entry in &lt;code class=&quot;language-text&quot;&gt;/etc/shadow&lt;/code&gt;. More information about
why passwords are stored in &lt;code class=&quot;language-text&quot;&gt;/etc/shadow&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;/etc/passwd&lt;/code&gt; &lt;a href=&quot;https://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From this article I also learned how to read the shadow file: the password entry ($1$foo$bar) is in fact three
properties separated by $. The $1 indicates MD5 hashing was used, which is notoriously easy to crack. The second
part (&quot;foo&quot;) is the salt and the third part (&quot;bar&quot;) is the hash from the password + salt.&lt;/p&gt;
&lt;p&gt;This article also shows that using the hash calculated from the salt and the password with openssl.
This is great, because know we can write a small script to try out many passwords without trying to login to SSH and
being kicked out for too many failed responses. The command looks like this, with &lt;code class=&quot;language-text&quot;&gt;-1&lt;/code&gt; indicating md5, &lt;code class=&quot;language-text&quot;&gt;foo&lt;/code&gt; as the
salt and &lt;code class=&quot;language-text&quot;&gt;secret&lt;/code&gt; the actual password.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;openssl passwd -1 -salt foo secret # output: $1$foo$ygQElgzdVoe51UiGBN5TV/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It is easy to do this in a bash script, but of course there already exists some open source tool: &lt;a href=&quot;https://www.openwall.com/john/&quot;&gt;John the Ripper&lt;/a&gt;
(&lt;a href=&quot;https://linuxconfig.org/password-cracking-with-john-the-ripper-on-linux&quot;&gt;info on usage&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First run &lt;code class=&quot;language-text&quot;&gt;sudo unshadow rootfs/etc/passwd rootfs/etc/shadow &amp;gt; mypasswd.txt&lt;/code&gt;
where &lt;code class=&quot;language-text&quot;&gt;unshadow&lt;/code&gt; is a util from &lt;code class=&quot;language-text&quot;&gt;john&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now remove all the entries from mypasswd.txt except the root user.&lt;/li&gt;
&lt;li&gt;Now run &lt;code class=&quot;language-text&quot;&gt;john mypasswd.txt --fork=4&lt;/code&gt;. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;fork&lt;/code&gt; flag enables multi threading, in this case on 4 threads. While the command is running, I see that 4 out of 8 cores
have a 100% load. After approximately 7 hours a password is found. Please note, that the other threads keep running, but a nice overview
is giving of how long the processes have been running and at what passwords they are trying.&lt;/p&gt;
&lt;p&gt;Logging in to SSH as root works! (So it was indeed the correct &lt;code class=&quot;language-text&quot;&gt;sshd_config&lt;/code&gt;).
A prompt is shown with only &quot;#&quot;. Running &lt;code class=&quot;language-text&quot;&gt;df -h&lt;/code&gt; gives:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Filesystem                Size      Used Available Use% Mounted on
/dev/root                 2.8M      2.3M    444.0K  84% /mnt/initrd
devtmpfs                239.2M         0    239.2M   0% /dev
/dev/disk/by-label/rootfs
                          1.0G    284.2M    544.7M  34% /
tmpfs                   249.4M      4.0K    249.4M   0% /dev/shm
tmpfs                   249.4M      9.1M    240.2M   4% /tmp
tmpfs                   249.4M    120.0K    249.2M   0% /run
/dev/mmcblk0p1           63.0M      5.9M     57.1M   9% /boot
/dev/mmcblk0p3            1.0G     93.7M    828.9M  10% /var/lib/pgsql
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /var/spool
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /var/log
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /etc/ssl/private
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /etc/ssh
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /etc/nextgen
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /home&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;cat /var/log/messages&lt;/code&gt; works and gives a lot of information, e.g. a daemon is running on user &quot;nextgen&quot; called Risco Service Manager.&lt;/p&gt;
&lt;p&gt;It was a fun exercise to try to get into a device you own, but don&apos;t have remote access too. Next steps could be to try
to install extra services on the device that could interact with the Risco Service Manager, or to intercept messages to
or from the Risco Service Manager.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Published with permission from Risco&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Functional Javascript Update]]></title><description><![CDATA[With a background in functional programming (Haskell), I'm interested in bringing functional programming to the web.  Frontend Masters…]]></description><link>https://mdworld.nl/mdworld-jackson//functional-javascript-update</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//functional-javascript-update</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Mon, 09 Mar 2015 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With a background in functional programming (Haskell), I&apos;m interested in bringing functional programming to the web. &lt;a href=&quot;http://frontendmasters.com&quot;&gt;Frontend Masters&lt;/a&gt; offers a course called &lt;a href=&quot;https://frontendmasters.com/courses/functional-javascript/&quot;&gt;&quot;Hardcore Functional Programming in JavaScript&quot;&lt;/a&gt; by Joe Nelson and Brian Lonsdorf.&lt;/p&gt;
&lt;p&gt;For the uninitiated in Functional Programming, you might already be using it without knowing it. If you use jQuery callbacks, e.g. $.get, this uses the functional concept of &lt;a href=&quot;http://eloquentjavascript.net/05_higher_order.html&quot;&gt;Higher Order Functions&lt;/a&gt;, because it&apos;s a function that takes or returns a function. Also the JavaScript native utility Array functions &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map&quot;&gt;map, filter, reduce etc.&lt;/a&gt; are higher order functions and are well known features of functional programming. The course &lt;a href=&quot;https://frontendmasters.com/courses/js-fundamentals-to-functional/&quot;&gt;&quot;JavaScript: From Fundamentals to Functional JS&quot;&lt;/a&gt; by Bianca Gandolfo can be recommended as an introduction to these concepts and in general to get a deeper insight into JavaScript for intermediate developers. Also see &lt;a href=&quot;https://github.com/bgando/functionalJS/&quot;&gt;the repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A simple example of a Higher Order Function (add), binding it to a new function (add5) and applying the new function:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; num1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; num2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; add5 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;add5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// result is 8&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;&quot;Hardcore Functional Programming in JavaScript&quot; outlines the &lt;a href=&quot;https://wiki.haskell.org/Pointfree&quot;&gt;&quot;point free&quot; style&lt;/a&gt; of programming, bringing Functional JavaScript closer to a purely functional language like Haskell. This is also what makes the functional &quot;hardcore&quot; in the case of this course, because the style looks quite foreign to imperative/object-oriented programmers.&lt;/p&gt;
&lt;p&gt;Advantages of point free, functional JavaScript include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It makes functions easier to test. You should need no mocks, because the point free functions are very loosely coupled and highly cohesive (if I understand well).&lt;/li&gt;
&lt;li&gt;It&apos;s very convenient for working with streams of data/events. This is &lt;a href=&quot;https://baconjs.github.io/&quot;&gt;literally&lt;/a&gt; in the description of the Functional Reactive JavaScript lib Bacon.js.&lt;/li&gt;
&lt;li&gt;It offers a very different approach to async tasks. In a sense the functional concept of &quot;Futures&quot; provides the same feature as a Promise does. For example, two asynchronous calls that depend on each others result would be written like this (&lt;a href=&quot;https://vimeo.com/97575933&quot;&gt;source&lt;/a&gt;):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Future&lt;/span&gt;
Future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loadPage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/products&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/reviews&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Compare to Promise&lt;/span&gt;
request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    url&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/reviews&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        url&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/products&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;loadPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;A disadvantage is that this style of programming in JavaScript is still in it&apos;s infancy. The &lt;a href=&quot;https://github.com/begriffs/immutube&quot;&gt;final demo&lt;/a&gt; from the course uses 7 libraries, most with some degree of overlapping functionality. We should feel encouraged to help improve the state of these libraries!&lt;/p&gt;
&lt;p&gt;The libraries used in the demo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jQuery&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lodash.com/&quot;&gt;lodash      &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ramdajs.com&quot;&gt;ramda       &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/DrBoolean/pointfree-fantasy&quot;&gt;pointfree   &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;future, part of &lt;a href=&quot;https://github.com/folktale/data.task&quot;&gt;this&lt;/a&gt;, for as far as I can tell&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://baconjs.github.io/&quot;&gt;bacon       &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://socket.io/&quot;&gt;socketio    &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The lack of (static) typing in JavaScript really becomes a large disadvantage when attempting functional programming. I can tell from personal experience that trying to do without typing in Haskell is not worth the headache. The use of a typed transpiler like &lt;a href=&quot;http://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt; might be of added value, if it&apos;s compatible with the Functional JavaScript libraries.&lt;/p&gt;
&lt;p&gt;In conclusion, it is possible to do &quot;hardcore&quot; functional programming (i.e. in a Haskell, point free style) in JavaScript, but it&apos;s definitely not as easy to pick up as jQuery or even as Angular. You really need to know why you would want to try (I&apos;m not entirely convinced myself), but it would be possible to mix it in with the existing frameworks in your everyday work. On the other hand, it would be advisable to start using the much more accessible functional Array utils, like map, filter, and reduce right away.&lt;/p&gt;
&lt;p&gt;It might be worth to mention that the presenters of the course are different from other presenters in my experience. They clearly care strongly about the abstract, academic aspect of programming. During the presentation, they develop in a terminal in Vim instead of in an IDE like Webstorm and don&apos;t lint their code, resulting in missing semicolons and otherwise sloppy code. It can be argued that it&apos;s not relevant to the subject, but I try to be consistent in my workflow, especially since people will use it as a start point. Also, I enjoy learning about new techniques/tools as a side effect of following these kind of courses.&lt;/p&gt;
&lt;p&gt;As a follow-up to this course I will probably look into Lenses (&lt;a href=&quot;https://vimeo.com/104807358&quot;&gt;video&lt;/a&gt;, &lt;a href=&quot;https://github.com/5outh/nanoscope&quot;&gt;nanoscope library&lt;/a&gt;), the book &lt;a href=&quot;https://drboolean.gitbooks.io/mostly-adequate-guide/&quot;&gt;&quot;Mostly Adequate Guide to Functional Programming&quot;&lt;/a&gt; by Brian Lonsdorf (one of the presenters), the &lt;a href=&quot;https://baconjs.github.io/&quot;&gt;Bacon.js&lt;/a&gt; library and the &lt;a href=&quot;https://github.com/fantasyland/fantasy-land&quot;&gt;Fantasy Land&lt;/a&gt; spec.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Full update for Broek]]></title><description><![CDATA[2-12-2015  After updating some packages, I rebooted for the first time after a long time. I thought it would help with cleaning up unused…]]></description><link>https://mdworld.nl/mdworld-jackson//full-update-for-broek</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//full-update-for-broek</guid><category><![CDATA[mypc]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Wed, 11 Feb 2015 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;2-12-2015&lt;/strong&gt; After updating some packages, I rebooted for the first time after a long time. I thought it would help with cleaning up unused kernels on the boot partition. The box apparently hangs on boot, but no keyboard/monitor are connected so this can still be anything. After connecting some peripherals, nothing happened. Upon trying to reboot the power LED stays on and doesn&apos;t respond to pressing (and holding) the power button. Removing and reinserting the power cable is the final straw: now nothing happens, even the power LED stays off.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3-12-2015&lt;/strong&gt; In a last attempt to find the culprit, I disassembled the box and plugged in old PSU. Upon connecting power and switching the PSU on, it&apos;s fan twitches, but does not start spinning normally. Pressing the power button on the motherboard has no visible effect. The motherboard has probably died.&lt;/p&gt;
&lt;p&gt;Building a replacement was already planned, but now has to be rushed unfortunately, so these parts were ordered:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(mobo) ASRock B85M Pro4&lt;/li&gt;
&lt;li&gt;(ram) 2x  Crucial DDR3 DIMM 1x4GB 1600 C11&lt;/li&gt;
&lt;li&gt;(cpu) Intel Celeron G1840&lt;/li&gt;
&lt;li&gt;(case) Cooler Master Silencio 352&lt;/li&gt;
&lt;li&gt;(fan) Noctua NH-L9i&lt;/li&gt;
&lt;li&gt;(psu) Seasonic G-Serie 360Watt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, I will re-use the drives (80GB + 3TB) and a Samsung 840 SSD (128GB) that I have lying around.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;12-12-2015&lt;/strong&gt; After assembeling the parts and just popping in the hard drives the system boots normally, although getting the secondary drive to work this requires fixing its entry in /etc/fstab.&lt;/p&gt;
&lt;p&gt;The ethernet adapter is not working, which makes sense, because it is a different on-board adapter.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I can&apos;t ping outside the system&lt;/li&gt;
&lt;li&gt;The ethernet lights next to the port are on&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ifconfig&lt;/code&gt; lists a br0 and an lo device, but no eth0&lt;/li&gt;
&lt;li&gt;lspci lists the Ethernet Controller as Intel I217-V&lt;/li&gt;
&lt;li&gt;running &lt;code class=&quot;language-text&quot;&gt;sudo lshw -C network&lt;/code&gt; gives &lt;code class=&quot;language-text&quot;&gt;*-network DISABLED&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;running &lt;code class=&quot;language-text&quot;&gt;dmesg | grep eth&lt;/code&gt; gives &lt;code class=&quot;language-text&quot;&gt;eth0: link is not ready&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;renamed network interface eth0 to eth1, then ran:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sudo modprobe e100
sudo ifconfig eth1 up&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;did not work, but no errors.&lt;/li&gt;
&lt;li&gt;According to &lt;a href=&quot;http://www.serenux.com/2009/11/howto-fix-a-missing-eth0-adapter-after-moving-ubuntu-server-from-one-box-to-another/&quot;&gt;this article&lt;/a&gt; I need to edit &lt;code class=&quot;language-text&quot;&gt;/etc/udev/rules.d/70-persistent-net.rules&lt;/code&gt; (as root) and comment out the old ethernet device&lt;/li&gt;
&lt;li&gt;After rebooting, it detects the ethernet adapter automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;13-12-2015&lt;/strong&gt; Of course, since the on-board sound card also changed, its drivers also needs to be reconfigured. I plugged the speakers into the lime port, I just want to use 2 channel sound.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;aplay /usr/share/sounds/alsa/Front_Center.wav&lt;/code&gt; gives an error.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sudo aplay -l&lt;/code&gt; does lists several cards, one being PCH ALC892 analog&lt;/li&gt;
&lt;li&gt;when using alsamixer, I see that HDMI is set as the default out. The old motherboard did not have HDMI out, so it did detect this new HDMI correctly. This should be changed to analog.&lt;/li&gt;
&lt;li&gt;I tried several things that had no effect, such as reinstalling alsa and rebooting, and changing the default device with &lt;code class=&quot;language-text&quot;&gt;pacmd list-cards&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Eventually, running &lt;code class=&quot;language-text&quot;&gt;lspci -knn|grep -iA2 audio&lt;/code&gt; shows I&apos;m using snd&lt;em&gt;hda&lt;/em&gt;intel kernel driver&lt;/li&gt;
&lt;li&gt;I edit &lt;code class=&quot;language-text&quot;&gt;/etc/modprobe.d/alsa-base.conf&lt;/code&gt; as root&lt;/li&gt;
&lt;li&gt;I add the line &lt;code class=&quot;language-text&quot;&gt;options snd_hda_intel index=1&lt;/code&gt; under the last &quot;install&quot;  statement&lt;/li&gt;
&lt;li&gt;Now I run &lt;code class=&quot;language-text&quot;&gt;sudo alsa force-reload&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;run alsamixer: now analog is active!&lt;/li&gt;
&lt;li&gt;run &lt;code class=&quot;language-text&quot;&gt;aplay /usr/share/sounds/alsa/Front_Center.wav&lt;/code&gt;. I hear the sound!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The case and fans were picked for being very silent. Unfortunately, they are still quite loud at the moment. I did have the sense to pick a case with PWM fans, so I need to configure those.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://askubuntu.com/questions/22108/how-to-control-fan-speed&quot;&gt;This article&lt;/a&gt; describes how to set it up.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install: &lt;code class=&quot;language-text&quot;&gt;sudo apt-get install lm-sensors fancontrol&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Configure lm-sensors: &lt;code class=&quot;language-text&quot;&gt;sudo sensors-detect&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the result:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;#----cut here----
# Chip drivers
coretemp
nct6775
#----cut here----&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;After starting the service, &lt;code class=&quot;language-text&quot;&gt;sensors&lt;/code&gt; gives output. I see coretemp around 30 C and RPMs for fan1, fan2, fan5.&lt;/li&gt;
&lt;li&gt;Configure fancontrol: &lt;code class=&quot;language-text&quot;&gt;sudo pwmconfig&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Found the following devices:
   hwmon0/device is coretemp
   hwmon1 is nct6776

Found the following PWM controls:
  hwmon1/pwm2           current value: 165
  hwmon1/pwm3           current value: 165
respond to changes, pwm1 doesn&amp;#39;t. Probably the two chassis fans.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I have a &lt;a href=&quot;http://www.silentpcreview.com/Noctua_NH-L9i&quot;&gt;Noctua NH-L9i CPU fan&lt;/a&gt; so I could use the Low-Noise adapter, but lets first try PWM.&lt;/p&gt;
&lt;p&gt;Fan2 seems to be the CPU fan, because the fan speed corresponds with the max speed of the Noctua NH-L9i. During pwmconfig I found out that setting the speed below 2000 RPM will greatly reduce the sound production. This means the low-noise adapter would definitely help. The CPU fan is hwmon1/fan2_input and is controlled by pwm hwmon1/pwm2.&lt;/p&gt;
&lt;p&gt;After configuring both fans with pwmconfig, I start fancontrol service: &lt;code class=&quot;language-text&quot;&gt;sudo service fancontrol start&lt;/code&gt; and the noise dropped significantly!&lt;/p&gt;
&lt;p&gt;The front fan (I think, I can&apos;t really hear it that well) is still quite noisy. It doesn&apos;t respond to configuring by pwmconfig, for some reason. I might just turn it off. The state after configuring:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fan1 (front?): was 1100 before configuration → after configuration 1100 (unchanged)&lt;/li&gt;
&lt;li&gt;fan2 (cpu): 2500 → 1150&lt;/li&gt;
&lt;li&gt;fan3 (rear?): 1100 → 380&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;15-12-2015&lt;/strong&gt; Added the low noise adapter to the front fan. Running &lt;code class=&quot;language-text&quot;&gt;sensors&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fan1 (front): 1100 → 881. &lt;/li&gt;
&lt;li&gt;fan2 (cpu): 980&lt;/li&gt;
&lt;li&gt;fan5 (rear): 327. &lt;/li&gt;
&lt;li&gt;Cpu temp around 32 C&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The noise production is now is very low.&lt;/p&gt;
&lt;p&gt;I&apos;ve also added two extra drives (an SSD and an old 1,5TB HDD) that need to be configured. Running &lt;code class=&quot;language-text&quot;&gt;sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL&lt;/code&gt; gives:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;NAME                    FSTYPE        SIZE MOUNTPOINT  LABEL
sda                                   2.7T            
`-sda1                  ext4          2.7T /mnt/disk3t
sdb                                  74.5G            
|-sdb1                  ext2          243M /boot      
|-sdb2                                  1K            
`-sdb5                  LVM2_member  74.3G            
  |-broek-root (dm-0)   ext4         71.8G /          
  `-broek-swap_1 (dm-1) swap          2.5G [SWAP]     
sdc                                   1.4T            
`-sdc1                  ext3          1.4T             OldDrive
sdd                                 119.2G            
|-sdd1                  ext4          119G            
`-sdd3                  vfat          249M             EFI&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;The filesystem sizes give away which drives are which and even the label of one of the drives is still intact.
For the moment I mount them manually:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt; /dev/sdc1 /mnt/disk1500g
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt; /dev/sdd1 /mnt/diskSsdTemp&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Both seem to work, so I just added them to the fstab and configured the 1,5TB drive as an export via Webmin.&lt;/p&gt;
&lt;p&gt;At this moment only the USB device &lt;a href=&quot;https://bitbucket.org/mdvanes/mderekelbox&quot;&gt;Rekelbox&lt;/a&gt; doesn&apos;t work anymore. I thought it might need an update of the USB drivers, not unlike the audio and network drivers before. The initPort.sh script fails with
&lt;code class=&quot;language-text&quot;&gt;stty: /dev/ttyUSB0: Inappropriate ioctl for device&lt;/code&gt;. Trying to find a solution gives many hits, non of which seem appropriate for my case. Trying a USB flash drive works fine, so I don&apos;t think it&apos;s the USB drivers.&lt;/p&gt;
&lt;p&gt;After searching messageboards for a long time, I just tried rebooting with the USB device plugged in: it started working immediately!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Reducing cyclomatic complexity with functional operators]]></title><description><![CDATA[Reducing the cyclomatic complexity in a JavaScript application is a good,  quantifiable  
way to make code more readable and maintainable…]]></description><link>https://mdworld.nl/mdworld-jackson//reducing-cyclomatic-complexity-with-functional-operators</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//reducing-cyclomatic-complexity-with-functional-operators</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Thu, 09 Feb 2017 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Reducing the cyclomatic complexity in a JavaScript application is a good, &lt;a href=&quot;https://eslint.org/docs/rules/complexity&quot;&gt;quantifiable&lt;/a&gt;
way to make code more readable and maintainable.&lt;/p&gt;
&lt;p&gt;Cyclomatic complexity increases as more control statements are used. For a summary of the factors that influence complexity,
see &lt;a href=&quot;https://craftsmanshipforsoftware.com/2015/05/25/complexity-for-javascript/&quot;&gt;&quot;Complexity for JavaScript&quot;&lt;/a&gt;. Because
it is quantifiable, it can be automatically validated in build setups with &lt;a href=&quot;https://eslint.org/docs/rules/complexity&quot;&gt;eslint&lt;/a&gt;.
Bear in mind that a single &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt; statement with a large amount of options will have a high cyclomatic complexity but
probably is still perfectly readable. As always, rely on common sense when refactoring. &lt;/p&gt;
&lt;p&gt;Control statements that concern one parameter often use &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt;, for example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; foo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;banana&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;apple&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;First&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;banana&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Second&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;coconut&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Third&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Last&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Second&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;A very common way to reduce the cyclomatic complexity with &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt; is to use a JavaScript object as a map. Instead of
traversing the switch statement, do a lookup in the map where the key is the condition and the value is the action. For the
example above this could look like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; actions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    apple&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;First&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    banana&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Second&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    coconut&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Third&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; foo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;banana&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;actions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasOwnProperty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    actions&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Last&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Second&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;This does not work directly with more complex conditions. e.g. a composite condition that checks against multiple parameters
within one statement or between statements.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stdout&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mapping&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stderr &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;A problem occurred&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Not found&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stderr &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`Execution error &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stdout&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;|&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapping&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`Invalid configuration &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stdout&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mapping&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;|&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;stdout &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; stdout&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;No output&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Result from some process with mapping and stdout&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;A problem occurred&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Not found&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Execution error Error||&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Invalid configuration |||&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;No output&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Foo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Result from some process with mapping and stdout&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;In this case a JavaScript Array of objects can be used here, with one property holding the condition and another holding the desired action.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// First part&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; actions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;stdout &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; stdout&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;No result&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapping&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Config invalid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; error &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stderr &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error executing&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; stderr &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;A problem occurred&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Not found&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;It would be possible to loop over each entry with a &lt;code class=&quot;language-text&quot;&gt;for&lt;/code&gt; loop or an &lt;a href=&quot;http://webuniverse.io/cyclomatic-complexity-refactoring-tips/&quot;&gt;iterator (see an example)&lt;/a&gt;, but this is where the expressiveness of
the functional operators &lt;code class=&quot;language-text&quot;&gt;Array.prototype.filter&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Array.prototype.reduce&lt;/code&gt; shines.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Second part&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stdout&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stderr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mapping&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; actions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// See above&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; selectedAction &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; actions
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;accumulated&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; currentAction&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// By design, reduce will only keep the last match when the accumulator &lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// is ignored, so the order inside the actions array has significance.&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; currentAction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Else clause&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Result from some process with mapping and stdout&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;selectedAction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;A problem occurred&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Not found&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Error executing&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Config invalid&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;No result&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Foo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Logs &quot;Result from some process with mapping and stdout&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;A working example can be found in &lt;a href=&quot;https://jsfiddle.net/mdvanes/367q8p35/&quot;&gt;this fiddle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This shows how to use functional operators to reduce cyclomatic complexity for an &lt;code class=&quot;language-text&quot;&gt;if else&lt;/code&gt; condition. Do keep in mind
it may not be beneficial for performance. For instance, do not declare the action array inside of the function as in
the example, as it would redeclare the array each time the function is executed. Another improvement would be to stop
iteration in filter/reduce
as soon as a matching action was found. &lt;/p&gt;
&lt;p&gt;Also note that the example with the &lt;code class=&quot;language-text&quot;&gt;if else&lt;/code&gt; condition itself is quite readable, so it will not be worth the trade off of
refactoring to resolution through an array of objects in this case. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Apollo Client in Practice]]></title><description><![CDATA[Some time ago I joined a team that is working on a search application. The application takes search terms and displays 
the results in a…]]></description><link>https://mdworld.nl/mdworld-jackson//apollo-client-in-practice</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//apollo-client-in-practice</guid><category><![CDATA[webdevelopment]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Mon, 04 Feb 2019 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Some time ago I joined a team that is working on a search application. The application takes search terms and displays
the results in a table with potentially dozens of columns and hundreds
of rows, even before pagination. It is implemented in React and uses &lt;a href=&quot;https://www.apollographql.com/&quot;&gt;Apollo&lt;/a&gt; for
GraphQL calls. I was surprised to find it noticeably slow when a lot of search results were retrieved. React is
well-known for leveraging virtual DOM to optimize performance and GraphQL should even be able to add caching to further
optimize performance on the side of network requests. &lt;/p&gt;
&lt;p&gt;Looking into the performance tab of Chrome dev tools lead me to believe the performance problems were caused by
computations in the bottom components (e.g. formatting in cells). Because there are so many and they are
re-rendered quite often, this approach is quite intensive on resources.&lt;/p&gt;
&lt;p&gt;Besides that, the application had obvious state synchronization problems. When moving between views it was not
maintaining the same state of selected rows. Even though Redux was used to store application state and communicate it
between components, it was not used consistently. There were still plenty of React class components that stored some parts of the state locally. &lt;/p&gt;
&lt;p&gt;To summarize, there were two issues that needed to be solved:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Poor performance due to excessive re-rendering&lt;/li&gt;
&lt;li&gt;Loss of application state when navigating views due to decentralized state stores&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since both issues were caused by (a lack of) architecture, we redesigned the structure of the application. The original implementation used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.apollographql.com&quot;&gt;Apollo Client&lt;/a&gt; as a GraphQL client&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/axios/axios&quot;&gt;Axios&lt;/a&gt; as an HTTP client for REST endpoints&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redux.js.org&quot;&gt;Redux&lt;/a&gt; and &lt;a href=&quot;https://reactjs.org/docs/hooks-reference.html#usestate&quot;&gt;React local state&lt;/a&gt; to manage the state between components&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It used Apollo, but by &lt;a href=&quot;https://www.apollographql.com/docs/react/essentials/queries#manual-query&quot;&gt;manually firing&lt;/a&gt; &lt;code class=&quot;language-text&quot;&gt;client.query()&lt;/code&gt; and
after processing the response, it stored the result in the Redux store.&lt;/p&gt;
&lt;h1 id=&quot;fixing-application-state-with-apollo-local-state&quot;&gt;&lt;a href=&quot;#fixing-application-state-with-apollo-local-state&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Fixing application state with Apollo Local State&lt;/h1&gt;
&lt;p&gt;When restructuring the application, Apollo Client was updated to 2.5. This version has a built-in &lt;a href=&quot;https://www.apollographql.com/docs/react/essentials/local-state&quot;&gt;local state manager&lt;/a&gt;
(formerly &lt;em&gt;apollo-link-state&lt;/em&gt;) and it supports REST calls with the &lt;a href=&quot;https://www.apollographql.com/docs/link/links/rest&quot;&gt;apollo-link-rest&lt;/a&gt; plugin.
The &lt;a href=&quot;https://github.com/apollographql/apollo-client/tree/master/packages/apollo-boost&quot;&gt;apollo-boost&lt;/a&gt; package contains the
client and several useful plugins. Adopting these means that both Redux and Axios can be removed and Apollo will be
used as a single source of truth. If there is a single store for the data, there is no need for synchronization and
with that one of the issues is solved. &lt;/p&gt;
&lt;p&gt;The way we used Apollo Client was also updated, to create a better separation of UI and data. Instead of using &lt;code class=&quot;language-text&quot;&gt;client.query()&lt;/code&gt;
directly in the component lifecycle methods, components are split into a presentational component and enhanced with the
&lt;a href=&quot;https://www.apollographql.com/docs/react/api/react-apollo#graphql&quot;&gt;graphql()&lt;/a&gt; HOC to add data from remote (i.e. GraphQL
back-end) or local fields. Both utilize the Apollo cache, which fulfills multiple functions, one of them an application local state store.&lt;/p&gt;
&lt;p&gt;Example of wrapping a component in a Query HOC:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Books&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; books &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;books&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;book &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;book&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;li&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ul&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;graphql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
  query($author: String!) {
    books(author: $author) {
     title
    }
  }`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
  variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; author&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mickiewicz&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Books&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Apollo reactively updates when using &lt;code class=&quot;language-text&quot;&gt;Query&lt;/code&gt; as a container, basically like the &lt;code class=&quot;language-text&quot;&gt;connect&lt;/code&gt; HOC in Redux. When
the &lt;code class=&quot;language-text&quot;&gt;variables&lt;/code&gt; prop on the &lt;code class=&quot;language-text&quot;&gt;Query&lt;/code&gt; component is updated, it will automatically re-query. It uses the cache if possible and
falls back to a network call if needed, although this behavior can be configured.&lt;/p&gt;
&lt;h1 id=&quot;improving-performance-with-local-field-resolvers&quot;&gt;&lt;a href=&quot;#improving-performance-with-local-field-resolvers&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Improving performance with Local Field Resolvers&lt;/h1&gt;
&lt;p&gt;Having a single source of truth fixes the state synchronization problem. It also paves the way for improving the
performance. In general, when a lot of data enters the application, it is a good idea to format it once and cascade the
formatted data down to the components and it&apos;s descendants with as little transformations to the data itself. This
reduces the amount of computations in the lower components, which solves our other issue.&lt;/p&gt;
&lt;p&gt;When using Redux, a common way to transform data in the store is using
&lt;a href=&quot;https://github.com/reduxjs/reselect&quot;&gt;Reselect&lt;/a&gt;, which computes derived data from the Redux store with selectors. For
Apollo this is done by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wrapping the table in a &lt;code class=&quot;language-text&quot;&gt;Query&lt;/code&gt; that queries a local prop &lt;code class=&quot;language-text&quot;&gt;rows @client&lt;/code&gt;, using the &lt;a href=&quot;https://www.apollographql.com/docs/react/essentials/local-state&quot;&gt;@client&lt;/a&gt; directive&lt;/li&gt;
&lt;li&gt;making client side resolvers for rows that queries GraphQL endpoint&lt;/li&gt;
&lt;li&gt;mapping the data in a resolver from a raw format to a format ready for the table components, e.g.:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;from a data object&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
  author&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mickiewicz&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
  publications&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; 
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
      title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Pan Tadeusz&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      date&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4291747200&lt;/span&gt; 
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;to an array rows of cells&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mickiewicz&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Pan Tadeusz&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;January 1834&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;h1 id=&quot;next-steps&quot;&gt;&lt;a href=&quot;#next-steps&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Next steps&lt;/h1&gt;
&lt;p&gt;Apollo is excellent for merging data from multiple sources (in this case GraphQL, REST, local state and cache) and
functions as a &quot;single source of truth&quot; which should solve the state synchronization problems. The local fields that
Apollo uses in its local state manager can derive data, moving expensive operations from component render functions
to resolvers in its application level cache. Although the issues mentioned in the introduction are now dealt with, we did
encounter plenty of other issues I may dive into later. However, these are some things that you might want to
take into account when working with Apollo Client:&lt;/p&gt;
&lt;p&gt;Outside of restructuring the application, we improved performance with &lt;a href=&quot;https://github.com/bvaughn/react-virtualized&quot;&gt;react-virtualized&lt;/a&gt; which speeds up rendering
large tables. Apollo also offers GraphQL pagination. We did not use that, as we
have to do our pagination on the client side to keep the sorting feature of react-virtualized in tact.&lt;/p&gt;
&lt;p&gt;Apollo Client offers support for TypeScript, it is even possible to generate queries and typed React components from
GraphQL schemas with &lt;a href=&quot;https://graphql-code-generator.com/&quot;&gt;@graphql-codegen/cli&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also definitely use the &lt;a href=&quot;https://jimkyndemeyer.github.io/js-graphql-intellij-plugin/&quot;&gt;JS GraphQL IntelliJ Plugin&lt;/a&gt; because
it will not only auto complete queries, but it will help you think about (client side) schema&apos;s.&lt;/p&gt;
&lt;p&gt;When the &lt;code class=&quot;language-text&quot;&gt;Query&lt;/code&gt; component mounts, it creates an observable that subscribes to the query in the query prop. This
encourages reactive behavior like RxJS (which can also be used as a &lt;a href=&quot;https://github.com/mdvanes/realtime-planner&quot;&gt;state store&lt;/a&gt;).
However, it seems that Apollo offers much less fine-grained control over the observables than what RxJS provides. And considering observables, Apollo Client
effortlessly &lt;a href=&quot;https://www.apollographql.com/docs/link/links/ws&quot;&gt;scales to web sockets&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Are you looking for inspiration on how Apollo client can be applied? I can recommend
&lt;a href=&quot;https://www.youtube.com/watch?v=g6Mhm9W76jY&quot;&gt;this talk by Uri Goldshtein&lt;/a&gt; and this &lt;a href=&quot;https://www.youtube.com/watch?v=2RvRcnD8wHY&quot;&gt;introduction to Apollo state
management by Sara Vieira&lt;/a&gt;. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dop won't boot and USB issues]]></title><description><![CDATA[When I plugged in an USB stick in the USB3 front panel of my workstation dop, there was no response. The USB stick's light didn't turn on…]]></description><link>https://mdworld.nl/mdworld-jackson//dop-wont-boot-and-usb-issues</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//dop-wont-boot-and-usb-issues</guid><category><![CDATA[mypc]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Mon, 02 Feb 2015 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I plugged in an USB stick in the USB3 front panel of my workstation dop, there was no response. The USB stick&apos;s light didn&apos;t turn on.&lt;/p&gt;
&lt;p&gt;After I opened up the sidepanel the USB plug to the motherboard wasn&apos;t plugged in, so I fixed that.&lt;/p&gt;
&lt;p&gt;After rebooting, I was greeted with this ugly message:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error: no such partition found 
grub rescue&amp;gt;&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;I tried using grub rescue. But using &lt;code class=&quot;language-text&quot;&gt;ls&lt;/code&gt; I can&apos;t find the boot partion. Then I notice, the bootdisk isn&apos;t showing up in the EFI.&lt;/p&gt;
&lt;p&gt;After opening up the sidepanel again I notice the power is not plugged in to my SSD, the bootdisk of the machine... Strangely, after plugging it in, the same error occurs.&lt;/p&gt;
&lt;p&gt;Booting from an Ubuntu live CD, all drives are visible, but the main SSD (/dev/sda2) shows an error in gparted. It does have the bios_grub flag. It gives the error:&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;unable to detect file system&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After deleting the /dev/sda4 bios_grub partition of 17MB this leaves an EFI fat32 partition with boot flag (dev/sda3) and main partition /dev/sda1 with /boot.&lt;/p&gt;
&lt;p&gt;Reboot: doesn&apos;t change anything.&lt;/p&gt;
&lt;p&gt;Now I&apos;m really need to use the system, so I try rebooting with super grub disk. The system boots immediately with first found settings. I think I&apos;ll leave it like this because I want to upgrade the SSD in the near future anyway.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Utopic Dop]]></title><description><![CDATA[Upgrade started Replaced /etc/gnome/defaults.list During installation the "report problem" pop-up appears, but the upgrade continues. I…]]></description><link>https://mdworld.nl/mdworld-jackson//utopic-dop</link><guid isPermaLink="false">https://mdworld.nl/mdworld-jackson//utopic-dop</guid><category><![CDATA[mypc]]></category><dc:creator><![CDATA[M.D. van Es]]></dc:creator><pubDate>Thu, 01 Jan 2015 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Upgrade started&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replaced /etc/gnome/defaults.list&lt;/li&gt;
&lt;li&gt;During installation the &quot;report problem&quot; pop-up appears, but the upgrade continues. I press report problem and it&apos;s about i915-3.15-3.13-dkms. Seems to be &lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/xorg/+bug/1386721&quot;&gt;Intel graphics related&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Changes to php.ini, kept my version&lt;/li&gt;
&lt;li&gt;PhpMyAdmin is updated. Had to give root db password which was difficult to find... Noted it now.&lt;/li&gt;
&lt;li&gt;After reboot the system seems to run fine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Third party repos that were disabled on upgrade to utopic:&lt;/p&gt;
&lt;p&gt;Installed new repo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_14.04/&quot;&gt;http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_14.04/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Re-added:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ubuntu-wine/ppa/ubuntu&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ppa.launchpad.net/rabbitvcs/ppa/ubuntu&quot;&gt;http://ppa.launchpad.net/rabbitvcs/ppa/ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://get.docker.com/ubuntu&quot;&gt;https://get.docker.com/ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://linux.dropbox.com/ubuntu&quot;&gt;http://linux.dropbox.com/ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ppa.launchpad.net/graysky/utils/ubuntu&quot;&gt;http://ppa.launchpad.net/graysky/utils/ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dl.google.com/linux/chrome/deb/&quot;&gt;http://dl.google.com/linux/chrome/deb/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not re-added:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://ppa.launchpad.net/webupd8team/atom/ubuntu&quot;&gt;http://ppa.launchpad.net/webupd8team/atom/ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ppa.launchpad.net/webupd8team/nemo/ubuntu&quot;&gt;http://ppa.launchpad.net/webupd8team/nemo/ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://download.01.org/gfx/ubuntu/14.04/main&quot;&gt;https://download.01.org/gfx/ubuntu/14.04/main&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;update-7-2-2015&quot;&gt;&lt;a href=&quot;#update-7-2-2015&quot; aria-hidden=&quot;true&quot; class=&quot;anchor&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Update 7-2-2015&lt;/h3&gt;
&lt;p&gt;When trying to update owncloud, this message appears:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;The following packages have unmet dependencies:
 owncloud-client : Depends: libowncloudsync0 (= 1.7.1) but it is not going to be installed
                   Depends: owncloud-client-l10n but it is not going to be installed
E: Unable to correct problems, you have held broken packages.&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;Install from .deb should work, but it complains about a conflict with the installed package &apos;libqtkeychain0&apos;.&lt;/p&gt;
&lt;p&gt;Running:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sudo apt-get update
apt-get autoremove&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;removed owncloud repos from Other Software&lt;/li&gt;
&lt;li&gt;removed libqtkeychain0 0.20140128 with Ubuntu Software Center&lt;/li&gt;
&lt;li&gt;now libqtkeychain0 0.3.0-2 is available -&gt; installed it&lt;/li&gt;
&lt;li&gt;re-added owncloud repo and run installation -&gt; works!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now there still is a problem with lxc-docker, it can&apos;t be updated.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot;&gt;
      &lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;apt-get remove lxc-docker
apt-get install lxc-docker&lt;/code&gt;&lt;/pre&gt;
      &lt;/div&gt;
&lt;p&gt;This works!&lt;/p&gt;</content:encoded></item></channel></rss>