tag:blogger.com,1999:blog-31179323034340738122024-02-07T05:57:58.866-08:00Darn Elk KilosSketches, thoughts, and observations on all the things. A personal notebook.Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comBlogger42125tag:blogger.com,1999:blog-3117932303434073812.post-53792462642706344812018-10-10T05:49:00.001-07:002018-10-10T05:52:27.138-07:00Moving onMy new blog is here: <a href="https://www.rendall.tv/blog">https://www.rendall.tv/blog</a><br />
<br />
An old post about my angst over using Blogger <a href="https://rendallkoski.blogspot.com/2017/10/update-and-partial-faq.html">is here on Blogger</a>, so this is quite overdue.<br />
<br />
Also long overdue: moving my website from an old-style web host to which I paid $35/month. For now, I'm moving to Netlify, but the migration is not yet complete, which means, as of now, I get a 'This site can’t be reached' error. So, not sure if that's a propagation issue or what, or whether I'll give up and go to github.io. But by the time that <b><i>you</i></b> read this, days, months or years from now, it's either up and running or I have transcended such mundane concerns for some reason.<br />
<br />
The new blog will likely be generated using Hugo, but I'm not sure about that, either.Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-59948263569494282352018-10-10T05:34:00.001-07:002018-10-10T05:34:42.143-07:00Chrome extension: Twitter 'likes' HiderTL;DR: I made a Chrome extension to hide Twitter posts that are likely designed to waste my time.<br />
<br />
Here it is: <a href="https://chrome.google.com/webstore/detail/twitter-likes-hider/dkcgnebncpfljfaaplmedjnfjifffagj" target="_blank">https://chrome.google.com/webstore/detail/twitter-likes-hider/dkcgnebncpfljfaaplmedjnfjifffagj </a><br />
<br />
The source code is here:<br />
<br />
<a href="https://github.com/rendall/twitter-like-hider">https://github.com/rendall/twitter-like-hider</a><br />
<br />
The long story:<br />
<br />
I wrote a Chrome extension that hides specific tweets from my Twitter newsfeed. Those tweets being headed with 'So-and-so liked this' or 'Thus-and-such follows So-and-so'.<br />
<br />
Twitter, the company, really wants us to spend as much time as possible on its site, and so it deploys various tricks to bypass our rational time-management skills (this strategy of distracting folk to keep them spending is as old as casinos and suburban shopping malls). One of those tricks is to sprinkle throughout your newsfeed posts that someone else 'liked', or a post from someone that someone else 'follows'. I would bet a lot that the Twitter 'time-suck' algorithm has somehow identified these as a particular time-suck for your specific demographic.<br />
<br />
e.g. Are you a left-leaning, 20-something urban professional living on the East Coast of the US? Take a look at this tweet, that asserts in a spectacular smug and condescending tone that only the Republic party can save the country. And, oh look! Lots of interesting commentary...<br />
<br />
And, while you can mute people, or turn off their retweets, you cannot turn off these 'like' and 'follow' tweets. At least, not through Twitter's user interface.<br />
<br />
So, I wrote a Chrome extension that does just that, and helps me separate the signal from the noise.<br />
<br />
It does not always work reliably, and I think that's a timing issue: sometimes when the extension triggers, Twitter has not yet finished loading those tweets. So, sometimes it will take a whole minute for all 'like' and 'follow' tweets to hide. However, you can push the extension button and trigger it manually. I'm not sure if I will ever spend the 80% time to grind down that 20% to make it shine. Perhaps, if I hear of literally anyone else in the world using it, I will make that effort.<br />
<br />
The name that I used on the required screenshot is 'Alexander Stubb'. It was kind of a random choice, but this name is shared by a Finnish politician from the center-right party Kokoomus (who recently started a campaign to be EU President), and I think I should change that, because it's distracting. Those who know who Alexander Stubb is are likely to wonder if I'm making some kind of political statement, and what it could possibly be. But, alas, no, I'm not making a political statement. I think I used the name because at the time it felt like an Easter egg.<br />
<br />
I mean, I do <i>vaguely</i> disapprove of Kokoomus, because I hear they want to replicate some of the demonstrably failed policies that have been so divisive in my homeland. But I have not yet heard a steel-manned argument in favor of them, and until then I cannot bring myself to hold a strong opinion about them either way. Finnish politics is a bit beyond my ken, at the moment.<br />
<br />
The only remaining question is "Why?" Why, if Twitter is bound and determined to present you with click-baity nonsense, stay on the site? Why not just quit? Why spend the time to write an actual <i>extension</i>? Well, there are some great gems in that garbage. Here are a few!<br />
<br />
<a href="https://twitter.com/PaulMMCooper/status/915959278028148736" target="_blank">Ruins: Ancient, Modern & Imaginary</a><br />
<a href="https://twitter.com/davidmacdougall/status/1044169731698241536" target="_blank">A raid in the Baltic Sea</a><br />
<a href="https://twitter.com/timolaak/status/1034321155627409408" target="_blank">Finland is made of...</a><br />
<a href="https://twitter.com/scorintha/status/1033405477542084609" target="_blank">How to find stuff in git</a><br />
<br />Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-76890943779326988452018-05-16T02:25:00.000-07:002018-05-16T02:25:04.774-07:00Bookmarks: productivity<a href="https://alistapart.com/article/owning-the-role-of-the-front-end-developer" target="_blank">Owning the Role of the Front-End Developer</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-48197815092743331792018-05-16T02:24:00.003-07:002018-05-16T02:24:48.390-07:00Ethereum thoughts1) A smart contract to force/encourage/cajole/blackmail yourself to do something. You place money in an account, and it is released to you if certain conditions are met, or else it goes into another account and is given away according to the terms of that account.<br />
<br />
2) An account that, when it receives money, disburses it to a random one of a set of charities.<br />
<br />
3) Conditions met: well, maybe for me to become better at Finnish, I can add a significant amount of money into an account that will release the money only if I show a specific, measurable improvement at Finnish at some specific time. Otherwise it goes to a charities' account as above.<br />
<br />
4) This evaluation of this 'improvement' would be determined according to some happening, perhaps on the internet. Perhaps a committee of some kind votes via some kind of secret ballot.<br />
<br />
5) Offering a bet on some event that could be independently verified (say, by AI, or by frequency of mention on the internet or whatever), two bets could create a prediction market. A prestige prediction market could be created by secretly approaching experts, and having them create accounts. We let those who sign up know who else is in the prediction market<br />
<br />
6) Or perhaps! Anyone can sign up, but their ability to predict is tracked. They achieve score and ranking (still anonymous). q.v. <a href="https://web.archive.org/web/20180509121742/https://www.wsj.com/articles/the-worlds-largest-hedge-fund-is-building-an-algorithmic-model-of-its-founders-brain-1482423694" rel="nofollow" target="_blank">Ray Dalio's algorithmic decision making</a>.<br />
<br />
7) If two anonymous accounts want to agree, they can share their real information with each other.<br />
<br />
8) Someone wanting to check the results of the prediction market can see the prediction score of any individual, and use it to increase the accuracy of their target predicition, by only including those who score highest in a particular topic.<br />
<br />Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-35984793750914928282018-05-16T02:09:00.001-07:002018-05-16T02:09:55.622-07:00Bookmark: design, especially IxD<a href="https://threadreaderapp.com/thread/970424435554574336.html" target="_blank">A thread from Twitter on rigor in IxD</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-54160351914438757932018-01-16T00:24:00.003-08:002018-01-16T01:44:02.049-08:00Bookmark: estimations<a href="https://news.ycombinator.com/item?id=16122963" target="_blank">Hacker news thread</a><br />
<a href="https://www.joelonsoftware.com/2007/10/26/evidence-based-scheduling/" target="_blank">Evidence based scheduling (blog post)</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-58810121487477865942018-01-15T13:01:00.004-08:002018-01-15T13:01:54.463-08:00Bookmark: images and image compression<a href="https://images.guide/" target="_blank">Essential image optimization</a><br />
<a href="https://www.youtube.com/watch?v=dv2TvTXQ4FQ" target="_blank">SVG can do that?! [video]</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-54644394717320759522018-01-15T13:01:00.003-08:002018-01-15T13:01:38.687-08:00Bookmark: Comments<a href="https://standards.mousepawmedia.com/csi.html" target="_blank">CSI</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-84577622990539530672018-01-05T04:40:00.000-08:002018-10-10T04:27:17.566-07:00An American's Guide to Washing Dishes in a Finnish HomeWhen you're in a Finnish home, don't shove every dirty dish into the dishwasher and switch it on. Apparently, many Finnish homes have old dishes, and many old dishes have glazes that will be removed by heat and chemical reaction with dishwasher soap. If there is one phrase you never want to hear, that phrase would be "Oh no! This was my great-grandmother's plate, and now it's ruined!" You will lose friendships over this.<br />
<br />
Full disclosure, I did not ruin anyone's great-grandmother's plate. I did, however, remove the polish from someone's decades-old ice-cream scoop. But there have been great-grandmother's plates rescued from my dishwasher.<br />
<br />
I have tried to ban in my household the use of dishes that cannot be washed in the dishwasher. They are to be used only on special occasions, like when we have completely run out of other clean dishes.<br />
<br />
What we have here, I believe, is an example of culture clash, and in broad strokes, I'm tempted to claim that Americans appreciate old things only to the extent that they are convenient. Old, inconvenient things will be banished to the attic or a museum. This is not necessarily a bad thing, or a criticism, just an observations. Finns seem to, generally speaking, not only appreciate old things, but use them in every-day life.<br />
<br />
At least, in my circles.<br />
<br />
Update: 10.10.2018<br /><br />After some consultation, I have discovered that there are many Americans who keep and use old things, and many Finns who do not. I have not really yet discerned a specific difference between who does what and why. While many American Southerners do keep and use old things, others do not. While many urban people of either Finnish or American nationality do not, many do.<br />
<br />
Anyway, be careful when washing unknown dishes! You could lose a friend!Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-44751979100030434222017-11-10T07:40:00.002-08:002017-11-10T07:40:44.784-08:00BMapp updateWell, the Burning Man Map App is coming along nicely. It's at the stage where I'm willing to show it to a UX designer to get some tips. I've also moved it to another host, <a href="https://garbage-collector-acronyms-27351.netlify.com/" rel="nofollow" target="_blank">served from here</a>.<br />
<br />
There is still a list of things that needs to be done, but I think it's really getting there!<br />
<br />
<a href="https://garbage-collector-acronyms-27351.netlify.com/">https://garbage-collector-acronyms-27351.netlify.com/</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-51493483605383046992017-10-07T01:57:00.002-07:002017-10-07T01:57:16.313-07:00Update and partial FAQThese is a FAQ for the questions that I frequently imagine that I am being asked. As you will see, my internal interlocutor can sound a bit judgey.<br />
<br />
<h4>
What's going on with BMapp?</h4>
I am continuing to work on BMapp apace. I'm keeping it on a private git repo at Bitbucket for now. I may open-source it at some point, but there's something irrationally nice about its being a private solo project*. I've committed to <a href="https://infernojs.org/" target="_blank">Inferno</a>, <a href="http://redux.js.org/" target="_blank">Redux </a>and <a href="http://reactivex.io/rxjs/" target="_blank">Rx</a>. I'm looking at <a href="https://redux-observable.js.org/" target="_blank">redux-observables</a>, since it's using two libraries I'm already using.<br />
<br />
<h4>
What's up with all the Bookmarks lately?</h4>
Well, there is not really a public social bookmarking application anymore, since the demise of del.icio.us. When I find or build one, I'll move all of those to it. There are a lot more in my chrome bookmarks. If I added them all, it would look even more like spam.<br />
<br />
<h4>
What's up with using Blogger? I think my grandad used Blogger once. All the cool kids use <span style="font-family: Courier New, Courier, monospace;">${some_other_thing}</span> or roll their own.</h4>
Rolling my own or moving it is in some distant future plan, a bit like my social bookmarking plans or the open-source social media plan. I started this blog waaay back nigh on 10 years now to keep track of a specific collaboration, almost immediately abandoned it, and rebooted it when I felt the need to have a public notebook. It is quite limited, but so far I have not bumped up hard against those limitations. It does the job. The risks are that it will be sunsetted by the notoriously fickle Google. Or that webstandards will leave it far behind. (Does it even have any full time staff?)<br />
<br />
<br />
* "Rather than its being a public solo project? A publicly ignored solo project? A project that's so stunningly fun that someone will fork it and do something more interesting?" asks my internally judgmental interlocutor. "Don't worry about any of that. Open source it! Do it! Do it! YOLO!" he shouts.Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-21369734907116124552017-09-28T09:48:00.000-07:002017-09-28T12:07:31.995-07:00Bookmark: Font and Font fallbacks<br />
<br />
Various resources dealing with fonts on websites.<br />
<br />
<a href="https://www.youtube.com/watch?&v=tO01ul1WNW8" target="_blank">Front End Center — Crafting Webfont Fallbacks</a> (YouTube)<br />
<a href="https://www.zachleat.com/web/comprehensive-webfonts/" target="_blank">A Comprehensive Guide to Font Loading Strategies</a><br />
<a href="https://github.com/bramstein/fontfaceobserver" target="_blank">fontfaceobserver: Webfont loading js library</a><br />
<a href="https://meowni.ca/font-style-matcher/" target="_blank">Font style matcher</a> + <a href="https://github.com/notwaldorf/font-style-matcher" target="_blank">github</a><br />
<a href="https://www.cssfontstack.com/" target="_blank">CSS Font Stack</a><br />
<a href="https://webdesign.tutsplus.com/tutorials/quick-tip-how-to-consistently-render-typefaces-cross-browser--cms-29514" target="_blank">Quick Tip: How to Consistently Render Typefaces Cross-browser</a> (video)<br /><a href="http://typerendering.com/" target="_blank">Type Rendering Mix</a> (library referenced in preceding video)Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-56765937337019228142017-09-20T12:30:00.002-07:002017-09-20T12:30:45.657-07:00Bookmark: Offline-only contentI may consider doing something like this for the BMapp: Offline-only content.<br /><br /><a href="https://chris.bolin.co/offline/">https://chris.bolin.co/offline/</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-34137614375939211992017-09-15T14:11:00.004-07:002017-09-15T14:11:58.178-07:00Bookmark: The Jupyter Notebook<blockquote class="tr_bq">
The Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and explanatory text. Uses include: data cleaning and transformation, numerical simulation, statistical modeling, machine learning and much more.</blockquote>
<br />
<a href="http://jupyter.org/">http://jupyter.org/</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-29214459890581638142017-09-14T20:19:00.004-07:002017-09-14T20:20:02.089-07:00Bookmark: Web Workers<blockquote class="tr_bq">
Web Workers makes it possible to run a script operation in background thread separate from the main execution thread of a web application. The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usually the UI) thread to run without being blocked/slowed down.</blockquote>
<br />
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API">https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-17381953621372988112017-09-14T01:26:00.000-07:002017-09-14T01:27:10.952-07:00Baby perspective on adults<p>Adults probably seem kind of like monsters to small children. Besides the obvious things, like that we are large and talk in loud, deep voices; we also do weird, dangerous things in the kitchen like boil water and cook food, which we then eat as hot as we can handle it. Hot coffee, hot soup, food with molten cheese toppings and such probably seem like monster food to babies; which we gobble up with huge bites.</p>
<p>But for that matter, babies seem like weird little creatures to older children. Especially newborns who can't do much except cry and just lie there like blobs. Adults are always boiling their bottles, wrapping them delicately in sterilized fabrics and such. And they smell bad quite often.</p>
<p> Like adults, really, if we're being honest.</p>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-46318288778770247772017-09-13T00:36:00.001-07:002017-09-13T00:42:44.201-07:00Configuring Typescript in Visual Studio 2017Be aware that there are 2 places to configure Typescript behavior in Visual Studio 2017 (and older, I assume). They do <i>not</i> communicate with each other. The first is the <span style="font-family: "courier new" , "courier" , monospace;">tsconfig.json</span> file at the root of your project (the one you get when you type <span style="font-family: "courier new" , "courier" , monospace;">tsc --init </span>in the command line). The second is in the properties of your project (right-click the project folder in Solution Explorer => Properties => Typescript Build).<br />
<br />
If you find your Typescript behaving in a way that is different from what you expect, make sure that both config files are synced.<br />
<br />
For instance, despite my explicitly putting<span style="font-family: "courier new" , "courier" , monospace;">'compileOnSave':false</span> in <span style="font-family: "courier new" , "courier" , monospace;">tsconfig.json</span>, javascript files kept popping in next to my <span style="font-family: "courier new" , "courier" , monospace;">.ts </span>files at every save. It was because <span style="font-family: "courier new" , "courier" , monospace;">Compile on save</span> was checked in the project properties.<br />
<br />
<br />
<img alt="The More You Know!" border="0" data-original-height="354" data-original-width="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx0lRLs24GS3xO0hcvPWIHCWVGc-x4vhAOmTBXiJEOSb9a6NLQPlIEKWn8RgUE8f-BxNggwZvf3C0Xf3s5cOiVlFEY5pZTuNsRD2AAsnBGjWdCqe-ufCZH1yt2XmhBRNOOsHk9SKS0pDAH/s1600/star.gif" title="" />Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-49104126976572490332017-09-12T14:48:00.001-07:002017-09-12T22:41:00.933-07:00Bookmark: Fake dataFake Online REST API for Testing and Prototyping<br />
<a href="http://jsonplaceholder.typicode.com/" target="_blank">http://jsonplaceholder.typicode.com/</a><br />
<div>
<br />
Quick & simple image placeholders.<br />
<a href="https://placeholder.com/">https://placeholder.com/</a></div>
Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-13945857700143915492017-09-12T13:31:00.004-07:002017-09-12T14:49:02.774-07:00Bookmark: Stack Share<blockquote class="tr_bq">
Discover & discuss the best open source and SaaS tools
<br />
<ul>
<li>Discover new tools and services </li>
<li>See side-by-side comparisons </li>
<li>Share your tech stack </li>
</ul>
</blockquote>
<a href="https://stackshare.io/">https://stackshare.io/</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-89759254502807997232017-09-11T23:07:00.000-07:002017-09-14T01:08:24.170-07:00Bookmark: Tech Conferences CalendarI'm maintaining a calendar of tech conferences and conventions around the world, mainly programming related. I add them as I become aware of them. If something is missing, here, or you'd like to help maintain it, shoot me an <a href="mailto:rendall@gmail.com?subject=Tech Conferences Calendar" target="_blank">email</a>.
<iframe frameborder="0" height="600" scrolling="no" src="https://calendar.google.com/calendar/embed?showTitle=0&showCalendars=0&showTz=0&height=600&wkst=1&bgcolor=%23DDDDBB&src=i9b9en2o4vdivnob77c7e7pd34%40group.calendar.google.com&color=%23330000" style="border: solid 1px #330000;" width="100%"></iframe>
Here are public links: <a href="https://calendar.google.com/calendar/embed?src=i9b9en2o4vdivnob77c7e7pd34%40group.calendar.google.com">HTML</a> and <a href="https://calendar.google.com/calendar/ical/i9b9en2o4vdivnob77c7e7pd34%40group.calendar.google.com/public/basic.ics">iCal</a> format.Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-34432190441159556542017-09-11T22:44:00.000-07:002018-03-05T03:53:12.141-08:00Bookmark: CSS MethodologiesHere are various methodologies for structuring CSS:<br />
<br />
<a href="https://github.com/stubbornella/oocss/wiki" target="_blank">OOCSS (Object Oriented CSS)</a><br />
<a href="https://smacss.com/" target="_blank">SMACSS (Scalable and Modular Architecture for CSS)</a><br />
<a href="http://getbem.com/" target="_blank">BEM (Block Element Modifier)</a><br />
<a href="http://suitcss.github.io/" target="_blank">SUIT CSS (Style tools for UI components)</a><br />
<a href="https://github.com/nemophrost/atomic-css" target="_blank">Atomic CSS</a><br />
<a href="https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/" target="_blank">ITCSS (Inverted Triangle CSS)</a><br />
<a href="http://ecss.io/" target="_blank">Enduring CSS</a><br />
<br />
<a href="https://stylable.io/" target="_blank">Stylable</a> is a pre-processor and component library that also has structuring constraints.<br />
<br />
More will be added as discovered.<br />
<br />
Here is a danger to be aware of.<br /><a href="https://jakearchibald.com/2018/third-party-css-is-not-safe/" target="_blank">Third Party CSS Is Not Safe</a>Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-29089623347797278142017-09-10T22:59:00.000-07:002017-09-12T22:40:33.652-07:00Bookmark: DEC64.com<br />
<br />
<blockquote class="tr_bq">
DEC64 is a number type. It can precisely represent decimal fractions with 16 decimal places, which makes it very well suited to all applications that are concerned with money. It can represent values as gargantuan as 3.6028797018963967E+143 or as measly as 1.0E-127, which makes it well suited to most scientific applications. It can provide very fast performance on integer values, eliminating the need for a separate int type and avoiding the terrible errors than can result from int truncation.</blockquote>
<br />
<a href="http://dec64.com/">http://dec64.com/</a><br />
<br />
<br />
<br />Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-16994476687304319132017-09-08T06:59:00.001-07:002017-09-08T06:59:55.369-07:00CDNs vs. bundlingRemember, this is a personal sketchbook, not a how-to guide nor really even a blog. So I might have some bad ideas on here. Might even be terrible. That's ok.<br />
<br />
I created <a href="https://www.npmjs.com/package/cdnler" target="_blank">cdnler </a>to help me with a workflow of using Typescript, but without necessarily loading modules through npm. If I were to use <a href="http://ramdajs.com/" target="_blank">Ramda </a>to build a site, I would load (only) <a href="https://www.github.com/DefinitelyTyped/DefinitelyTyped.git" target="_blank">Ramda's type declarations</a> using npm, so that its classes and methods would be available to my development environment. But on the web page itself, I'd just use a script call to a <a href="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.js" target="_blank">CDN</a>. Any project I'm working on might have 5 or 6 CDN calls on one page, and since it's best practice to use CDNs only with a <a href="https://www.hanselman.com/blog/CDNsFailButYourScriptsDontHaveToFallbackFromCDNToLocalJQuery.aspx" target="_blank">local fallback</a>, for production I'd have to download every CDN asset file by hand, and then hand-code its fallback. cdnler just does that.<br />
<br />
Which is fine as far as that goes, but the fad these days, <a href="http://www.inboundmarketingagents.com/inbound-marketing-agents-blog/bid/361535/Google-to-Start-Penalizing-Non-Mobile-Sites" target="_blank">backed by the power of Google</a>, is to bundle up all of your javascript into a single, or two, large, minimized files, and then link to those from within your page. This has the advantage of reducing server calls, since a script reference blocks any other browser activity until that call is resolved. CDNs are another way of handling this bandwidth issue, since in theory, a CDN asset would be cached on the browser, and presumably shared when the same browser visits a different site with that same asset, but, to be honest, that's a bit dubious. Considering, <a href="http://code.jquery.com/jquery-3.2.1.js" target="_blank">jQuery</a> alone, there are so <a href="http://code.jquery.com/jquery-3.2.1.slim.js" target="_blank">many</a> <a href="http://code.jquery.com/jquery-3.2.1.slim.min.js" target="_blank">different</a> <a href="http://code.jquery.com/jquery-3.2.1.min.js" target="_blank">versions</a>, and so many different <a href="https://docs.microsoft.com/en-us/aspnet/ajax/cdn/overview#jQuery_Releases_on_the_CDN_0" target="_blank">CDNs</a> <a href="https://developers.google.com/speed/libraries/#jquery" target="_blank">that</a> <a href="https://www.akamai.com/us/en/resources/jquery-cdn.jsp" target="_blank">host</a> <a href="https://cdnjs.com/libraries/jquery" target="_blank">it</a>, that even sites that use jQuery, and a CDN to reference it, would not necessarily be caching the same files. As well, Google now wants your site to be a progressive app, which makes CDN references problematic. Not impossible, but the tide is against that method.<br />
<br />
The expected way to bundle javascript code is to load of external libraries locally using a package manager like npm or <a href="https://code.facebook.com/posts/274518539716230/announcing-yarn-1-0/" target="_blank">yarn</a>. Then, in the code, to require them using <a href="https://nodejs.org/api/modules.html#modules_require" target="_blank">node.js syntax</a> e.g. <br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">import R = require('ramda');</span><br />
and then to use a build tool like <a href="http://browserify.org/" target="_blank">browserify</a> or <a href="https://rollupjs.org/" target="_blank">rollup</a> which work by following all those require calls up the <a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" target="_blank">abstract syntax tree</a> to know what libraries comprise the app, mushes them all into one file, which is what then goes into the <span style="font-family: "courier new" , "courier" , monospace;"><script></span> src reference.<br />
<br />
Here's where my bad idea comes in. Why not build a companion module to cdnler, that would follow all of the local script references in an html file (<span style="font-family: "courier new" , "courier" , monospace;"><script src="local.js"></span>), then bundle and minimize those local assets? Then it could replace those script references in the html file with a single script reference to the bundled asset. It wouldn't need to do any so-called <a href="https://en.wikipedia.org/wiki/Tree_shaking" target="_blank">treeshaking</a>, just put the contents of each file in just a long file of its own.<br />
<br />
To recap, this hypothetical work-flow would be to reference external libraries using CDNs during development, and then download them locally during pre-build, then bundle them into a single (or more) local file during build, and then replace the CDN script references in the html with a single a reference to that local file. <br />
<br />
What would be the point? I just like working with CDNs. There's something neat about having the world's javascript libraries available to just a single flat index.html. And there's something hegemonically monocultural about using npm to manage all of everyone's code. If there's ever <a href="http://www.sciencealert.com/how-a-programmer-almost-broke-the-internet-by-deleting-11-lines-of-code" target="_blank">a problem with npm</a>, we're all in trouble. So, it's a good thing, I think, to have a variety of ways to build and create apps.<br />
<br />Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-24800788167010753152017-09-07T23:38:00.000-07:002017-09-08T06:59:25.788-07:00Brunch and BMappThe "Burning Man App" (I'm settling on the working title <i>BMapp</i>) that I'm building has stalled for a minute. Before I dig in, and move from proof of concept to actual build, I want to make sure that the architecture and pipeline are solid. That is to say, I'd like a good framework and a build task that keeps the coding itself relatively simple. For the framework, I've settled on <i><a href="https://infernojs.org/" target="_blank">Inferno</a></i>, because it is light and fast. While its key developer <a href="https://medium.com/inferno-js/introducing-inferno-1-0-f3da5c4e773b" target="_blank">has left (?) the project</a> to move onto <i>React </i>at Facebook, and I'm not sure what that means for <i>Inferno</i>'s<i> </i>future, for now, the relative advantages yet go to <i>Inferno</i>.<br />
<br />
As to a build task, the <i>Inferno</i> team itself appears to recommend <a href="https://infernojs.org/docs/guides/brunch" target="_blank">Brunch</a>, an open-source, community-driven "build tool" rather than a "generic task runner". Its main selling point is that it reduces some of the monstrous complexity that some build task runners can encompass. A single <i>brunch-config.js</i> file pointing to input files, plugins and some output directories, and <i>boom</i>, you have a minified, uglified, compressed, tightened, tested web app. No fuss, no muss. Sounds great! Also, during setup I ran into a few errors (that were ultimately caused by a flawed npm release, <i>not</i> Brunch): with one issue ticket <a href="https://github.com/brunch/brunch/issues/1745" target="_blank">the Brunch team was incredibly responsive</a>. They were <i>on it!</i> Even committing to closing out the issue over the weekend! That is dedication. "Windows support is very important to us."<br />
<br />
So, when I say that Brunch isn't working for me, it is by no means a slight of Brunch itself or the hardworking team that created it. If you're looking for a build pipeline, do check it out! This post is more a documentation that I tried it, and why I'm moving on.<br />
<br />
I generally like to code javascript using <i>Typescript</i>, for a number of reasons, but mostly because it <i>is</i> javascript, only with strict typing. Coding with it prevents me from easily relying on type ambiguity (and the advantages that ambiguity can sometimes confer), and in return, I'm made aware in the editor, even before compilation, of potential problems. Other advantages: I can use the latest and greatest coding practices from ES6 and later (does what <i><a href="https://babeljs.io/" target="_blank">Babel </a></i>does), and my code will automagically be compiled into whatever version necessary.<br />
<br />
Brunch kinda has typescript support, but see, that's the thing: it suffers from the same issue that all popular task runners do: you need to rely on some intermediary plugin that may, or may not, be up-to-date. Brunch uses '<i><a href="http://brunch.io/skeletons" target="_blank">skeletons</a></i>' which are a kind of template or starter pack for different configurations. Their official '<i><a href="https://github.com/ysle/brunch-with-typescript" target="_blank">brunch with typescript</a></i>' skeleton, out of the box, gives you a `<i>brunch-typescript is unsupported, use typescript-brunch instead</i>` deprecation message. Okay, no big deal, I'll just swap out the <i>brunch-typescript</i> plugin for the <i>typescript-brunch</i> plugin. But <i>typescript-brunch</i> has this notation: "<i>From version 1.8.2 up to current version, this plugin may report TypeScript errors that you are not expecting</i>" and "<i>We are hoping to support the full language service, at least for brunch build at some point, but until then...[etc]</i>". Not exactly inspiring confidence. Okay, no big deal. I'll just use Typescript itself to compile to javascript, and once there, let Brunch takeover to do what it does best.<br />
<br />
On to uglify js, the minimizer. I followed all instructions as I understood them to get it working and it just plain did not work, meaning, to minimize and 'mangle' the compiled javascript; or really, to have any effect at all. Simply installing <a href="https://www.npmjs.com/package/uglify-js-brunch" target="_blank">the plugin</a> and referencing it in the config file appeared to have zero effect on the code itself. <i>No doubt</i>, and I mean this, it's my bad. I didn't understand the instructions, or didn't fiddle with it enough. Perhaps if I had changed the order of the plugins, or if I had only spent another 10 minutes or half-an-hour, then I'm certain I could get it working as expected.<br />
<br />
And, it's community driven! If it's not working, get on the stick! It's not like you can demand your money back. Write up a ticket describing the issue. Ask questions on the forum! Write the bug fix, if that's what's necessary. I get it! But that's the thing: I had already spent a lot of time with it already. A task runner / builder / DevOp tool / what-have-you is supposed to make things easier, <i>minimize</i> errors <i>and </i>time in the setup and manipulation of code. If you're spending as much time on the tool as you would just rolling your own, then it's maybe best to roll your own. My spare coding time, right now, is dedicated to getting this BMapp up and going.<br />
<br />
So, for now, it's back to using <a href="https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/" target="_blank">npm as my build tool</a>. It's simple, it works, and if something isn't there, it's super easy to code up a module that does what you want.Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.comtag:blogger.com,1999:blog-3117932303434073812.post-44420313176367464622017-09-07T01:12:00.000-07:002017-09-08T07:00:12.500-07:00Visual Studio 2017 and Frontend DevelopmentVisual Studio 2017 is a great IDE for frontend development that has some extremely picky, opinionated ideas about how you should set up your projects. And since I, too, have extremely picky, opinionated ideas about how I should set up my projects, too, we often fight during setup, VS2017 and I. VS2017 is a cranky old man who hired you to mow his lawn, insists that you wear gloves and smeary safety glasses, that you mow out back <i>before </i>you mow out front, and then forgets what he told you and yells at you anyway. That's only during setup, though. Once you get going, VS2017 is a dream.<br />
<br />
If you, like me, use npm; git; a task runner; have a development folder separate from your production folder; and run a web server from your production folder; even if you're not at this point interested in the backend - or want to use an entirely different IDE and technology than .NET; then you can get the good parts of VS2017 without annoying <i>Scripts</i> folders and what-not.<br />
<br />
These are the precise steps to follow to turn that Visual Studio 2017 from an angry old man into a cooing, cuddly baby. An extremely <i>useful</i> baby.<br />
<br />
(Oh, by the way, this is if you're setting up a new project. VS2017 makes you jump through a whole host of other annoying steps if you have already set up another project, so follow these steps <i>only</i> if you have not yet set up you project. I may, or may not, cover the latter case in another post.)<br />
<br />
<ol>
<li>Open VS2017, then do <i>File </i>=> <i>New Project</i></li>
<li>Choose <i>Blank Node.js Web Application</i></li>
<li>Fill in the fields in this way:</li>
<ul>
<li> Name => <i>dev </i></li>
<li> Location => the *parent* directory of where you want your project to live. <br /> e.g. <i>/workshop/websites</i> <br /> (<i>Not</i> inside a folder named for your project. e.g. NOT <i>/workshop/websites/MyProject</i>)</li>
<li> Solution => <i>create new solution</i></li>
<li> Solution name => *this* is where you put the name of your project's folder.<br /> e.g. <i>MyProject</i></li>
<li> Check both <i>create directory for solution</i> and <i>create new git repository</i>.</li>
</ul>
<li>Click <i>OK</i>.</li>
<li>From the 'Solution Explorer', you can go ahead and delete the <i>Scripts </i>folder, <i>package.json</i>, <i>README.md </i>and <i>server.ts</i>. </li>
<li>Right click the 'Solution' node in the 'Solution Explorer' and pick '<i>Add</i>' then '<i>New Website</i>'</li>
<li>Choose <i>ASP.NET Empty Website</i>.<br />Don't worry. There is no ASP.NET involved.</li>
<li>Web location: browse to the project directory (e.g. <i>MyProject</i>) and create a new folder named <i>dist</i> by adding its name to the path in the field named "Folder:"<br />e.g. <i>C:\workshop\websites\MyProject\<b>dist</b></i></li>
<li>Click '<i>open</i>'. You should get a dialog box telling you that '<i>dist</i>' does not exist and asking if you would like to create it. Click '<i>Yes</i>'.</li>
<li>Click '<i>ok</i>'.</li>
<li>Click through any warnings.</li>
<li>Go ahead and delete the <i>Bin </i>folder, <i>packages.config </i>and <i>Web.config</i>.</li>
<li>Right-click on the 'dist' node in the 'Solution Explorer' and click '<i>Add</i>' => '<i>Add New Item</i>'</li>
<li>In the "Name:" field write '<i>index.html</i>'</li>
<li>Click '<i>add</i>'.</li>
<li>In the editor, add a "<i>hello world</i>" message in the <body> tag.</li>
<li>Right click the 'dist' node in the 'Solution Explorer' and select '<i>View in Browser</i>'.</li>
<li>If you see your index.html message, success!</li>
<li>Right-click the root 'solution' node in the Solution Explorer.</li>
<li>Select '<i>Add</i>' => '<i>New Solution Folder</i>'</li>
<li>Name it '<i>root</i>'.</li>
<li>Right-click, '<i>Add</i>' => '<i>Existing Item</i>'.</li>
<li>Select <i>.gitignore </i>and any other relevent file from your project folder (the parent of 'dev' and 'dist', e.g. <i>MyProject</i>). <br />Now these are easily accessible in the Solution Explorer from the 'root' folder. Do this any time during development if there are files in there you would like to see inside the 'Solution Explorer'.</li>
<li>Related, if at any time there is a file that is definitely in the <i>dist</i> or <i>dev</i> folder but is not showing up in the Solution Explorer, check for an icon along the top just under the title 'Solution Explorer' named '<i>Show All Files</i>'. Click that. Your missing file should show up. You can right-click its icon and select '<i>Include in Project</i>' if you like.</li>
<li>Select <i>View </i>=> <i>Other Windows </i>=> <i>Terminal Window</i>. (Or use <i>Power Shell</i> or <i>CMD</i>).</li>
<li>In the 'dev' directory type:</li>
<ol>
<li> <i>npm init</i>, then fill in the information</li>
<li> <i>tsc --init</i> => creates a typescript.config file.</li>
<li> <i>git status</i> => check to see if there are any files that need to be added to .gitignore</li>
</ol>
<li>If all is well, this would be a good time to type '<i>git -m "init commit"</i>'</li>
<li>Now the world is your oyster.</li>
</ol>
Rendallhttp://www.blogger.com/profile/11103221991681823393noreply@blogger.com