25 March 2019

Book Review: The JavaScript Handbook by Flavio Copes

If you're a competent programmer but have been away from JavaScript for some time and want an extremely brief overview of the updates to JavaScript, in bite size form, then this book (The JavaScript Handbook) is for you.

Flavio goes over all the new features in JavaScript from ES6 to ES2018. Listing out each feature or change and giving an extremely brief description of it.

This book reads like a collection of very short blog posts though. And would benefit from more editing, both on a sentence level and on an overall topic cohesiveness level. That's a small nitpick in what is overwise a good set of writing.

There's definitely two major parts to the book. First part is extremely brief in describing the changes in each version of ECMAscript.

Second part basically goes over all the changes, again, but this time in more detail. Not a lot more, but sufficient for a competent programmer to know enough.

E.g. if you don't know that much about async and promises on a conceptual level, this book isn't going to teach you enough to really use those features productively.

Or if you don't really know the problems with the "this" keyword in JavaScript, the book's description of it in relation to how it works and how it's changed with arrow functions isn't the most enlightening. Some sentences on it, superficially without a deeper understanding of how programming languages work, are downright contradictory sounding.

All in all though, I went through it cover to cover, and the book does a good job for reviewing changes to JavaScript for the competent programmer.

For next to free (i.e. email signup), it's hard to beat.

23 March 2019

Homebrew blew up from libffi, ruby, or? Here's how to fix it.

I wanted to upgrade Homebrew itself and what it installed on my Mac.  It's probably been over a year, so lots of outdated stuff.  I ran:

brew update
brew upgrade

Everything looked good, and it gave me some instructions to add to my PATH the Homebrew installed ruby and ruby gems along the lines of adding the following to my .bash_profile:

PATH="/usr/local/opt/ruby/bin:$PATH"
PATH="/usr/local/lib/ruby/gems/2.6.0/bin:$PATH"

So I did that, and tried out ruby, irb, and emacs. It starts spitting a bunch of different errors, and I probably confounded the causes and errors as I was trouble shooting, but it gave me errors about:

dyld: Library not loaded: /usr/local/opt/libffi/lib/libffi.6.dylib

Especially when I ran emacs, I got:

dyld: Library not loaded: /usr/local/opt/libffi/lib/libffi.6.dylib
Referenced from: /usr/local/opt/p11-kit/lib/libp11-kit.0.dylib
Reason: image not found

And when I ran irb, I got:

Traceback (most recent call last):
2: from /usr/local/opt/ruby/bin/irb:23:in `<main>'
1: from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': can't find gem irb (>= 0.a) with executable irb (Gem::GemNotFoundException)

Hmm?  I tried a bunch of stuff and it probably made it more confusing, especially as I started running brew and got errors like:

/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- active_support/core_ext/object/blank (LoadError)

Or when I ran brew help and got:
 
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- mechanize/version (LoadError)

Well now I just wanted to "start over".  You could do that by deleting all of Homebrew and what it installed, to start fresh, but what a pain!  I'd have to know what packages to re-install with a new Homebrew installation and go through installing those one by one.

Instead, the easier thing to try first is this:

1. Remove from your PATH the brew installed ruby and rubygem

On Macs, it's probably "safest" when troubleshooting Homebrew to use the Mac OS X's original Apple installed ruby.  Yes, it's an old version of ruby, but when I changed my PATH to use the Homebrew installed ruby, I probably made troubleshooting much more difficult.  It's tough enough to troubleshoot Homebrew, but if brew (a ruby program) runs on the brew installed ruby, brew just might be running on a ruby that brew screwed up...

2. try brew update-reset

This fetches and resets Homebrew and all tap repositories to the latest from their git repositories.  In other words, restart them fresh.

3. brew reinstall libffi

emacs, ruby, python, and a bunch of other stuff needs it.  Even if you've got it installed.  Reinstall it to make sure it's installed right.  It fixed emacs for me for sure.  Probably ruby too.

4. update and upgrade brew again

brew update
brew upgrade

And that finally fixed it.  I added the ruby and gem paths back into PATH in my .bash_profile, and installed irb as a ruby gem (Mac OS X has old versions of both ruby and irb pre-installed, but getting the latest means installing ruby via brew and irb as a ruby gem).

20 March 2019

How to migrate ReactXP App to make an Electron Desktop App

ReactXP comes with a few sample apps. The TodoList app is the most developed and closest to the structure of a production app written in TypeScript, but doesn't target Electron.  Here's how to migrate it to run on Electron so it could work as a desktop app.

I'm on a Mac, but Electron is cross platform with Windows and Linux so it should work there too.  ReactXP 1.6.x is current right now (hilariously, it upgraded from 1.5.x just as I was working on this and it introduced some new error so this migration is totally in beta).

Strategically, the idea is ReactXP can already directly target the web via React (in addition to native iOS, Android, and Windows via React Native).  So we just target the web with ReactXP, modify the web page loader to run in Electron, and modify some code so it doesn't assume it's running at the root of a web server.

Make TodoList into a web app. Run it on a local dev web server

First, use git to clone the ReactXP repository:

git clone https://github.com/microsoft/reactxp

In the reactxp/samples directory, you'll find the TodoList app. Open it:

cd reactxp/samples/TodoList/

Install Electron into it:

npm install --save-dev electron

Now we need a web page to load the app into Electron.  We'll use the default one from Electron quick start.  Just copy the main.js from electron-quick-start into the TodoList folder, and rename it to electron-main.js just for clarity.

09 March 2019

Maximally Cross Platform with React?

Once upon a time, going cross platform meant making an application that ran on both Macs and Windows, and maybe Linux/Unix if you're into that crowd.

Now everything is fragmented and compartmentalized.  Consider what "platforms" there are now for making apps:

  1. desktop web browsers --- i.e. Chrome, Firefox, Safari, vs Edge --- further divided by Macs, Windows, and Linux (at least for browsers that are cross platform, ha!)
     
  2. mobile web browsers --- i.e. iOS vs Android --- further divided by phone vs tablet display sizes
     
  3. Electron desktop apps --- i.e. Macs, Windows, vs Linux (built with web browser technology)
     
  4. native desktop apps --- i.e. Macs, Windows, vs Linux
     
  5. native mobile apps --- i.e. iOS vs Android --- further divided by phone vs tablet display sizes
Some of the above differences are a matter of building user interfaces sized for use on that display size, while other differences are a matter of framework (e.g. Cocoa vs Android SDK).

But at worse, that's still 26 different platforms to build for!  There are technologies that help bridge the divide, and one family of such tech is called React.

Here's a survey of some React based technologies and which platforms they work well for.


06 March 2019

Create React Native App using TypeScript with Babel and Expo

Here's every step to creating a React Native app (with or without Expo), written in and type checked with TypeScript, but compiled with Babel 7.

You're assumed to have some proficiency with using the terminal.

Tools to Install on your PC

I'm on a Mac, but the steps shouldn't be much different on Ubuntu Linux or Windows.
  1. Install Homebrew.
    It's a package manager for Macs, and Linux too, but if you're on Ubuntu or Debian, I suggest just use the built-in one like APT.
  2. Install Node thru brew.
    Installing Node should include the NPM package manager with it, which is needed below.
  3. Some say to next install Yarn thru brew.
    Yarn is yet another node package manager... you can skip this if you want, it's not strictly needed, and I won't use Yarn in this tutorial.
  4. Fix NPM because of Yarn.
    I actually mentioned Yarn at all only because with Homebrew, you might now need to fix the Node NPM install as it might be broken by installing yarn.  Simply[1] run: yarn global add npm.  Remember, we don't need Yarn in this tutorial though.
  5. Install Expo thru npm:npm install -g expo-cli.

    Expo is apparently kind of a mini-platform for running React Native apps, and makes it easy to test a React Native app on devices through its Expo app, or on Macs and PCs without resorting to an Android or iOS emulator (which is great, because those emulators are dreadfully slow in my experience).  Plus installing Expo should include React Native with it.
[1] https://stackoverflow.com/questions/33870520/npm-install-cannot-find-module-semver/49422151#49422151

New Project with Expo (or not)

1. Create a React Native project with or without Expo:
$ expo init CoolProject
or alternatively without Expo:
$ react-native init CoolProject

2. cd CoolProject to go into the new project's root directory, then install Babel:
$ npm install --save-dev @babel/core @babel/cli
I assume this will install for you Babel 7 or above.  We'll need it later to migrate to TypeScript.

3. Create a lib folder in the project root.
$ mkdir lib
The lib folder will be used to contain the App's JavaScript files. Traditionally, the folder would be called "src", but looking forward, these JavaScript files eventually will be produced by the TypeScript compiler for us.

So instead, we're going to reserve "src" for later when we migrate to TypeScript, instead of calling it "src" right now when we're still dealing with just JavaScript JS, or JSX, files.

Separating the TypeScript and the compiled JavaScript files is a technique to avoid in-source builds (a usual technique used in compiled languages like C++: see e.g. in-source vs out-of-source builds).