Setting up Chrome Extensions for use with ES6

First time setup of Chrome Extensions can be painful if you’ve never done it before. Add to that setting them up for use with ES6 and you can end up spinning your wheels longer than writing code. I recently went through this while creating Reading List, which makes heavy use of ES6 as well as Ramda for the functional work. While Babel setup is fairly easy, the module loading presented some challenges. Having originally gone with SystemJS I faced a lot of difficulty in getting the tests to run. After switching to Webpack, for all the horror stories I had heard about it, the issues I was facing were resolved within the hour.

TLDR: You can see an example of the setup here https://github.com/coreyc/reading-list. It is somewhat barebones – intentionally – as so many JavaScript developers waste their time with tool configuration these days. This setup is meant to get you off the ground ASAP.

We’ll step through the setup as follows:

  • Transpiling – Babel
  • ES6 module bundling & loading – Webpack
  • Setting up the Chrome extension
  • Setting up unit tests

Transpiling – Babel

This part is pretty simple. Install the Babel tools we’ll need with the command below:

What does this install? Because Babel can compile several ECMAScript specs we need to install the preset for the version we want to use, in this case ES2015 (ES6). If we wanted ES7 we could install a preset for that too. We also need to install babel-loader so that we can integrate with Webpack. Lastly, babel-register is needed so that we can run our Mocha tests.

Next step is to tell Babel what presets we want to enable. Create a .babelrc config file if you haven’t already and add the following:

And of course if you want to use ES7 features you would add the ES7 preset to this config.

That takes care of Babel.

ES6 module bundling & loading – Webpack

We’ll be using the import / export statements from ES6, formatting our modules as ES6 rather than AMD or CommonJS. Webpack will bundle these modules up for loading in the browser. Install with:

Next we need to add a webpack.config.js file to the root of our project. Configure it like so:

The entry point for our app contains imports of the other files used in the project. It might look something like this:

bundle.js is the output of our modules after they’ve been run through Babel and Webpack. If you have any 3rd party libraries, include them in the externals property so that they won’t be included in the bundle. Otherwise all the code for that library will get bundled up and dramatically increase the file size.

From the command line, run the following in order to actually create the bundle and it’s source map:

Now we need to configure our npm run start command so that it does this bundling and serves up the files in one step. Add this to package.json:

That takes care of Webpack.

Setting up the Chrome extension

Chrome extensions have a config file of their own, manifest.json. Here’s the one from my project:

I won’t go into too much detail as this config can get really complex, but the main things to know are that you specify the icon, the HTML file you want to run when you click the extension icon, what Chrome API’s you need under permissions, then add your content scripts, which are scripts needed by the HTML file you specify. Disclaimer: you can also specify background scripts that run, but I did not make use of these. This setup is not tested for use with background scripts, although they may run just fine.

We take the bundle file output from Webpack and use it as our content script. An important thing to note is that you can specify when this file should run using "run_at". This is especially useful for when you need to use DOM events such as DOMContentLoaded, as extensions seem to block this event from firing. The "run_at" property is useful because it tells the script to execute when you specify, in this case at the start of the document load.

Next we need to add the bundle file to our HTML:

A side note here: I had to add the Ramda library to the HTML even though it was specified in the Webpack config as an external library. Not sure if this is the correct way or not, but it works. YMMV.

That takes care of Chrome.

Setting up unit tests

Now we just need to set up our unit tests. If you don’t already have mocha installed, run npm install --save-dev mocha . Add this to the “scripts” property of the package.json file:

Most info you’ll find on setup will recommend
"test": "mocha --compilers js:babel-core/register test pattern here"
but this seems to be outdated and the Mocha docs recommend just using –require babel-register. From the docs:
“If your ES6 modules have extension .js, you can npm install –save-dev babel-register and use mocha –require babel-register; –compilers is only necessary if you need to specify a file extension.”

Run npm run test and watch your tests run.
That takes care of unit tests.

 

Why is `compose` right to left?

I’ve been working my way through the excellent Mostly Adequate Guide to Functional Programming recently. Although I’ve been working with compose for a bit now, I needed to review why it operates from right-to-left (also known as “right associative”). A review of mathematical theory will help answer this question.

Function Composition

functional composition

The image above is read as “g ∘ f”, or “g composed with f”, or “g-compose-f”. For example, (g ∘ f )(c) = #. If we change ‘c’ to ‘x’, this function would read as g(f(x)). As you’ll remember from high school algebra and composite functions, this means you plug in something for ‘x’, then plug that value into ‘f’, then plug that value into ‘g’. This evaluation occurs from right to left, hence why compose is right associative.

To illustrate compose, consider the following:
f(x) = 2x + 2 and g(x) = –x + 3, find (g o f)(1)
Solution:
(g o f)(1) = g(f(1))
f(1) = 2(1) + 2 = 4
g(4) = -4 + 3 = -1 (remember, 4 was return value of f(1))
…and -1 is our answer from this function composition.

Left to Right

Developers don’t always think in right-to-left fashion, so if you want the reverse pipe (or sequence depending on the library), is an alternative to compose that operates from left-to-right.

 

ES6: Mutability of ‘const’

When first hearing about const in ES6, I was excited about the possibility of having immutability in native JavaScript. For developers programming in the functional style, this would have come in handy, but it turns out const is not actually immutable. It allows mutable properties. For example, all of the below is valid:

while the below is not valid:

So the object cannot be reassigned, but the value of the property can be changed and properties can be added and removed. It seems so similar to immutability, but it’s not and it’s an important distinction to make.

It’s probably known by now that if you need to make an object’s values immutable, you can use Object.freeze(), but be aware that this freezes the object entirely. You can’t add more properties or remove properties after it’s been frozen.

It’s probably a good idea to use const as much as possible as it discourages unnecessary re-assignment and forces the developer to think about how the variable will be used. If you need true immutability, you can use the Immutable library by Facebook.

This post is part of a continuing series on practical application of ES6 features. To view the first in this series, check out this link. More are on the way.

 

Functional Programming as the Paradigm for IOT

FP-iot

As the Internet of Things reaches maturation and begins to become commonplace in our lives, the technology used to support IOT must be chosen well. With potentially millions of devices connected, developing applications to support these devices and the data they produce, while converting that data into something meaningful, will require thoughtful attention to technology choices. In building any system, attention to architecture and technology stacks is important, but if IOT delivers on its promise of scale, the technology implications will be very different than what we’ve had to solution and develop for before. It will not be enough to simply “use what we’ve always used” and to keep building things the way we’ve been building them. The challenges are far too complex to not take a step back and look at other options.

What challenges does IOT present?

Scalability and concurrency are likely the two biggest challenges that IOT will bring about. Think of the scale of data that these devices will produce and the number of applications that will be developed to handle those devices and their data; there is the potential for great complexity in designing these systems. While scaling problems can sometimes be solved by adding more infrastructure, this solution won’t apply to the potentially massive amount of Internet-connected devices. And concurrency is an even bigger problem. Millions of devices and real-time communication amongst these devices and consumer-end applications means millions of concurrent connections. Thread-locking and race conditions get hairy fast. Great strides have been made in recent years with non-blocking technology such as Node.js, but this of course won’t be nor should it be the only solution used.

As systems become more complex, so does the underlying codebase, and so we can consider code readability to be just as important as the other two factors.

Functional Programming as the paradigm

Functional programming is well-suited to help solve these challenges. The properties of functional programming – preference for immutability, function composition, avoiding side-effects, less code, etc. – will help avoid many of the pitfalls of an IOT world. Immutable data helps solve the concurrency issue as locks can be avoided. Real-time communication is also better supported by FP. As an aside here, it should be noted that not all FP languages are strictly immutable (for example Haskell has mutable data structures). Furthermore, not all FP languages are created equal when it comes to concurrency management – some perform better than others. This is important to keep in mind when selecting the right language for your application use-case.

Another benefit is side-effect free functions.  While some FP languages are more liberal than others in their allowance of side-effects, FP as a whole favors side-effect free.  This is of great use when programming IOT applications as it makes scaling easier while making the code easier to reason about.  Functions without side-effects can be run in parallel much easier than functions with side-effects as functions that only take inputs and produce outputs only care about their individual inputs and outputs, not other operations like database calls.  This same reason is why side-effect free functions also have the benefit of being able to be better optimized.

Lastly, with FP there is just less code to write, which means less bugs, which means better programs.

Precursors

What IOT-like applications are currently using FP languages?

Erlang

  • RabbitMQ
  • WhatsApp
  • Chef
  • League of Legends chat
  • Facebook chat (first version, now using C++)
  • Numerous game servers (Call of Duty, Battlestar online)

Clojure

  • Netflix
  • Walmart

Elixir

  • Senseware
  • CargoSense

Haskell

  • IMVU
  • Numerous trading/financial companies

As you can see, many of these applications above have similar challenges as those posed by IOT, namely many concurrent connections (chat, WhatsApp, games servers) and scale (all of the above). FP has proven itself in the above applications, furthering the argument that it is a prime candidate for IOT.

There’s still room for OOP

There’s still room at the table for Object-Oriented programming, although it probably shouldn’t be the dominant paradigm. It’s called Internet of Things for a reason, and OOP can still be useful in describing and reasoning about those things. However, central to IOT is data and communication, and it’s easier to reason about this with FP than OOP.

A better glue

Out of the box, Internet-connected devices will rely on the applications and systems that support them to maintain this connectedness and communication, and so these supporting systems must have a good way of doing so. As John Hughes worded it in his “Why Functional Programming Matters” paper, “… a language must provide good glue.” Functional programming is that “good glue” that will help enable technologists to solve many of the challenges brought about by IOT.