Creating a React based Chrome extension

Creating Chrome extensions is quite easy. In fact it is so easy I found it hard to believe how quick I had a sample up and running. And given how useful Chrome extensions can be I wondered how hard it would be to create one using React. It turns out that it is easy Smile

 

Creating a basic React app

To get started I decided to create a React app using create-react-app.  This gave me a working React application to get started with. To turn an HTML page with JavaScript into a Chrome extension you need to add a package.json file. The Chrome developer Getting Started tutorial has a nice template to get started with. As this file needs to be in the root of the folder you deploy as an extension I added it to the public folder. As it needs an PNG to display I downloaded the logo_small.png from the React GitHub repository and also added that to the public folder. After updating the page to open to index.html I ended up with the following package.json:

{
"manifest_version": 2,

"name": "Demo React-Chrome extension",
"description": "This extension shows how to run a React app as a Chrome extension",
"version": "1.0",

"browser_action": {
"default_icon": "logo_small.png",
"default_popup": "index.html"
}
}

This is already enough but it is helpful to give the window a specific size. If you don’t the window will be as small as is possible which isn’t nice in this case. Again easy to do by adding a height and width to the body tag in the index.css.

body {
margin: 0;
padding: 0;
font-family: sans-serif;

/* Added body dimensions */
height: 300px;
width: 250px;
}
A chrome extension needs to be static files that get packed up. Again easy to do, just run npm run build and the resulting build folder contains exactly what you need.
 
 

Testing the extension locally

Doing a local test with the extension is easy. Open up Chrome and select Setting/Extensions or just navigate to chrome://extensions/. At the right top there Developer mode checkbox. Make sure that it’s checked.

image

Next you can drag the build folder into the extensions window. Now you should see the extension appear in the top bar of Chrome. There you should see the React icon appear.

image

When you click the React icon the extension should start. You will see the default create-react-app Welcome to React home screen. Complete with its animation and just like you would see it in the main browser window.

image

How cool is that Smile

 

 

Deploying to the Chrome web store

Publishing the extension to the Chrome web store is easy as well. You will need to create an account for a small one time fee. Once your account is setup just follow these steps and you will be done in no time. You can install and try this demo extension here.

 

The complete source code for the plugin can be found here.

Bring your own React

React is a a great UI library from Facebook that works well for creating fast browser based user interfaces. Working with it is quite easy. Once you learn the basics you can be quite productive. But to create great applications it is helpful to understand some of the internals of React. But that is where things become a bit more complex. The React source code is not easy to understand. There are a lot of performance optimizations that make code harder to read. Also there are  a lot of browser related issues. Small differences that add a lot more complexity. Another reason is that React is not just for browser based applications and their DOM. It’s also for other platforms like React Native.

When going through the original source code is really hard. Like it is with React. But understanding the choices is beneficial, there is a good alternative. That alternative is to create a simplified own implementation. The goal is not to create a new UI library. No there are other simpler alternatives out there like Preact. The goal is just a teaching tool to better understand React.

 

To JSX or not to JSX?

Using JSX to write React code is not necessary or required. But it is the de-facto standard way of writing React. It makes code a  lot easier to read compared to the plain JavaScript style. Fortunately  JSX is just a format that can be used with different UI libraries.  Transpiling JSX into JavaScript isn’t even done by the React team these days. Instead that is left up to Babel which is pretty much the de-facto standard for transpiling ECMAScript 2015 and JSX.

The way to do this is in fact quite simple. There is a Babel plugin called transform-react-jsx. This is the normal way to transpile JSX code. By default it turns JSX markup elements into React.createElement() functions. Yet by specifying a pragma option you can make it output anything you want. In this case I am going to replace React.createElement() with my own ByoReact.createElement() using the following .babelrc file.

{
"presets": ["es2015", "stage-0", "react"],
"plugins": [
["transform-react-jsx", {
"pragma": "ByoReact.createElement"
}]
]
}

This will allow me to use any new ECMAScript feature and transpile JSX code to my own library.

 

The Hello World of Bring Your Own React

Most development starts with Hello World and there is no reason why not to start there. The fist version of the code is just going to render the following:

image

Not impressive but we have to start  somewhere Smile

The code to render this Hello World is as follows:

import ByoReactDOM from '../../src/bring-your-own-react-dom';
import ByoReact from '../../src/bring-your-own-react'; // eslint-disable-line no-unused-vars

class HelloWorld extends ByoReact.Component {
render() {
return <div>Hello world</div>;
}
}

ByoReactDOM.render(<HelloWorld />,
document.getElementById('app'));

Doing the minimal required means mostly just implementing the ByoReact.createElement(). React itself uses a virtual DOM but in this case I am just going to stick with the real browser DOM. This will change soon enough but this is a nice start. The function is passed three parameters: The tag to render which can be a HTML tag name or a child component. The second is the properties, something we will ignore for now. The last is the list of child components. These child components can either be a string literal or another component.

The code for this is quite simple and always returns a HTML element:

const createElement = (tag, props, ...childeren) => {
let result;
if (typeof tag === 'string') {
result = document.createElement(tag);
} else {
const component = new tag(); // eslint-disable-line new-cap
result = component.render();
}

for (const child of childeren) {
if (typeof child === 'string') {
const textNode = document.createTextNode(child);
result.appendChild(textNode);
} else {
result.appendChild(child);
}
}

return result;
};

The base class Component is there but as it doesn’t contain any functionality yet there is not much to see. Again this will change as we get further along.

This leaves rending the <HelloWorld /> component in the browser using ByoReactDOM.render(). Again there is little to this yet as the ByoReact.createElement() returns a DOM object.

const render = (reactElement, domContainerNode) => {
domContainerNode.innerHTML = reactElement.outerHTML; // eslint-disable-line no-param-reassign
};
 
When we switch to a virtual DOM and updating existing UI components this will become a lot more complex. This will basically trigger the reconciliation process. This is the complex logic to determine the difference between the previous and next DOM and apply it as efficient as possible.
 
You can browse the complete source code, including unit tests, here.
 
Enjoy Smile

Introducing the React Tutorial

React is hot and it seems that almost every front-end web developer wants a piece of it. Not surprising maybe because Facebook created and open sourced React. And React not only powers the Facebook website but also many others like Netflix and Airbnb.

Because I have been using and teaching React for the last year I decided to try doing things a bit bigger. If you want to learn React I want to help you with a series of online video tutorials. Each video covers one part and the whole series will give you a deep understanding of React. Of course this takes quite some work so I decided to start a Kickstarter campaign to fund the whole project. You can find the Kickstarter project here.

If you become one of the backers you can get early access to the videos if you want to. All you need to do is choose the appropriate backer level. Regardless of the level you back me you will get access to the videos before others who buys after the Kickstarter campaign finishes. And not just earlier access, you will also pay less :-).

http://bit.ly/the-react-tutorial

Turbocharging Docker build

Building a Docker image can take a bit of time depending on what you have to do. Specially when you have to do something like DNU Restore, DotNet Restore, NPM Install or Nuget Restore builds can become slow because packages might have to be downloaded from the internet.

Take the following Dockerfile which does a DNU Restore.

FROM microsoft/aspnet:1.0.0-rc1-update1-coreclr

MAINTAINER Maurice de Beijer <maurice.de.beijer@gmail.com>

COPY . ./app

WORKDIR ./app
RUN dnu restore

EXPOSE 5000

CMD ["--server.urls", "http://*:5000"]
ENTRYPOINT ["dnx", "web"]

Running the Docker build multiple times without any changes is quite fast. To time it I am using the command:

time docker build -t dotned .
This reports it takes between 1.3 and 1.5 seconds on my aging laptop. Not too bad really.
 
Unfortunately this changes quite a bit when I make a change to the source code of the application. Just adding some non significant whitespace slows the build from 1.5 seconds to 58 seconds which is quite a bit of time to wait before being able to run the container.
 
The reason for this slowdown is that Docker has to do a lot more work. When you build a Docker container for the second time Docker creates a layer for each command executed. And each layer is cached to be reused. But if a cached layer depends on another layer that is changed it can’t be reused anymore. This means that once the source code is changes the result of the COPY command is a different layer and the DNU Restore layer has to be recreated which takes a long time.
 
A much faster approach is to copy just the project.json file so we can do a DNU Restore before copying the rest of the source code. With this approach Docker build are down to quite a reasonable 3.3 seconds  and only take a long time when there is a change to the project.json file. Something that should not happen very often. The functionally identical but much faster Dockerfile looks like this:
 
FROM microsoft/aspnet:1.0.0-rc1-update1-coreclr

MAINTAINER Maurice de Beijer <maurice.de.beijer@gmail.com>

COPY ./project.json ./app/

WORKDIR ./app
RUN dnu restore

COPY . ./app

EXPOSE 5000

CMD ["--server.urls", "http://*:5000"]
ENTRYPOINT ["dnx", "web"]

Enjoy Smile
 
 

JavaScript functional goodness

10522520853_efce3f51df_z

Using some functional principals and using immutable data can really make your JavaScript a lot better and easier to test. While using immutable data in JavaScript seems like something really complex it turns out is really isn’t that hard to get started with if you are already using Babel. And while libraries like Immutable.js are highly recommended we can start even simpler.

Babel does a lot of things for you as it lets you use all sorts of next generation JavaScript, or ECMAScript 2015 to be more correct. And it is quite easy to use whatever your build pipeline is or even as a standalone transpiler if you are not using a build pipeline yet.

When you want to use immutable data the functional array functions map() and filter() as well as spread properties are really useful. Here are a few examples to get you started.

Changing a property on an object

var originalPerson = {
firstName: 'Maurice',
lastName: ''
};

var newPerson = {
...originalPerson,
lastName: 'de Beijer'
};

console.log(newPerson);

The …originalPerson is using the spread properties which expands all properties. The lastName: ‘de Beijer’ comes after it so it overrules the lastName from the originalPerson object. And the result is a new object.

{
firstName: "Maurice",
lastName: "de Beijer"
}

Simple and easy. And as we are never changing objects we can replace the var keyword with the new const keyword to indicate variables are never reassigned.

const originalPerson = {
firstName: 'Maurice',
lastName: ''
};

const newPerson = {
...originalPerson,
lastName: 'de Beijer'
};

console.log(newPerson);

 

Adding something to an array

Usually when adding something to an array either an assignment or a push() function is used. But both just mutate the existing array instead of creating a new one. And with the pure functional approach we do not want to modify the existing array but create a new one instead. Again really simple using spread properties.

const originalPeople = [{
firstName: 'Maurice'
}];

const newPeople = [
...originalPeople,
{firstName: 'Jack'}
];

console.log(newPeople);

In this case we end up with a new array with two objects:

[{
firstName: "Maurice"
}, {
firstName: "Jack"
}]

 

Removing something from an array

Deleting from an array is just as simple using the array filter() function.

const originalPeople = [{
firstName: 'Maurice'
}, {
firstName: 'Jack'
}];

const newPeople = originalPeople.filter(p => p.firstName !== 'Jack');

console.log(newPeople);

And we end up with an array with just a single person.

[{
firstName: 'Maurice'
}]

 

Updating an existing item in an array

Changing an existing items is just as easy when we combine spread properties with the array map() function.

const originalPeople = [{
firstName: 'Maurice'
}, {
firstName: 'Jack'
}];

const newPeople = originalPeople.map(p => {
if (p.firstName !== 'Jack') {
return p;
}

return {
...p,
firstName: 'Bill'
};
});

console.log(newPeople);

And that is all it takes to change Jack to Bill.

[{
firstName: "Maurice"
}, {
firstName: "Bill"
}]

 

Really nice and easy and it makes for very easy to read code once you are familiar with the new spread properties.

Hosting an ASP.NET 5 site in a Linux based Docker container

Note: This post is based on ASP.NET 5 Beta8, the samples might not work for you anymore

Docker has becoming a popular way of hosting Linux based applications the last few years. With Windows Server 2016 Docker containers are also coming to Windows and are likely going to be a popular way of hosting there as well. But as Windows support is just in CPT form right now and ASP.NET is also moving to Linux with the CoreCLR I decided to try and run an ASP.NET web site on a Linux based container.

 

Getting started with an ASP.NET 5 application

To get started I installed the ASP.NET 5 beta 8 using these steps. Once these where installed I created a new ASP.NET MVC project. Just to show where the application is running I added a bit of code to the About page. When running from Visual Studio 2015 using IIS Express this looks like this:

image

The extra code in the HomeController:

   1: public class HomeController : Controller

   2: {

   3:     private readonly IRuntimeEnvironment _runtimeEnvironment;

   4:  

   5:     public HomeController(IRuntimeEnvironment runtimeEnvironment)

   6:     {

   7:         _runtimeEnvironment = runtimeEnvironment;

   8:     }

   9:  

  10:     public IActionResult About()

  11:     {

  12:         ViewData["Message"] = "Your application is running on:";

  13:         ViewData["OperatingSystem"] = _runtimeEnvironment.OperatingSystem;

  14:         ViewData["OperatingSystemVersion"] = _runtimeEnvironment.OperatingSystemVersion;

  15:         ViewData["RuntimeType"] = _runtimeEnvironment.RuntimeType;

  16:         ViewData["RuntimeArchitecture"] = _runtimeEnvironment.RuntimeArchitecture;

  17:         ViewData["RuntimeVersion"] = _runtimeEnvironment.RuntimeVersion;

  18:         

  19:         return View();

  20:     }

  21: }

With the following Razor view:

   1: @{

   2:     ViewData["Title"] = "About";

   3: }

   4: <h2>@ViewData["Title"].</h2>

   5: <h3>@ViewData["Message"]</h3>

   6:  

   7: <h4>OperatingSystem: @ViewData["OperatingSystem"]</h4>

   8: <h4>OperatingSystemVersion: @ViewData["OperatingSystemVersion"]</h4>

   9: <h4>RuntimeType: @ViewData["RuntimeType"]</h4>

  10: <h4>RuntimeArchitecture: @ViewData["RuntimeArchitecture"]</h4>

  11: <h4>RuntimeVersion: @ViewData["RuntimeVersion"]</h4>

  12:  

  13: <p>Use this area to provide additional information.</p>

 

So far so good and we can see the application runs just fine on Windows using the full CLR. From Visual Studio we can also run the application using Kestrel with the CoreCLR as shown below.

image

 

Running the application in a Docker container

Having installed the Docker-Machine we can also run this same website in a Docker container on Linux. The first thing we need to do is create a Dockerfile with the following contents:

   1: FROM microsoft/aspnet:1.0.0-beta8-coreclr

   2:  

   3: COPY ./src/WebApplication3 ./app

   4:  

   5: WORKDIR ./app

   6: RUN dnu restore

   7:  

   8: ENTRYPOINT dnx web --server.urls http://*:80

 

With this container definition in place we need to build the Docker container itself using the docker build -t web-application-3 . command. This is executed from the Docker terminal window in the main folder of our web application where the Dockerfile is located. This will build our Docker image which we can now see see when running docker images.

image

With this new image we can run it using: docker run -d -p 8080:80 web-application-3

image

With the application running we can navigate to http://192.168.99.100:8080/Home/About where 192.168.99.100 is the IP address of the virtual machine running the Linux machine with the Docker daemon.

image

Sweet Smile

What is the right level of maturity

In my previous blog post I explained about the Data Storage Maturity Model and how you would get a much more mature and capable application if you used Event Sourcing. That blog post did bring up some interesting question.

 

Should I always use Event Sourcing?

Given that Event Sourcing was at the top of the pyramid you could conclude that you should always aim for the the top and use Event Sourcing. Aiming high is a noble cause and sounds like the right thing but it turns out that it isn’t that simple.

If your application is relative simple and you don’t have much of a domain model there is little point in Event Sourcing your data storage. For example a To-Do application probably has little reason to do so. Maybe if you want to do advanced analysis over the history of to-do items there is a need but in most cases all you need to do is persist a few items of data to some persistent store for later retrieval. And that sounds like level 1, CRUD with structured storage, will do quite well while adding Event Sourcing would just complicate things.

There is also a differentiation to be made inside of applications. Suppose you are doing  a complex banking app. In that case Event Sourcing would make perfect sense for your domain layer. However there is more then just your domain layer. Every application has utility data, for example a list of countries in the world. This is a mostly static reference table and using Event Sourcing for data like that would be over engineering. Again just using a CRUD store for this data would be more then enough even though all financial transaction data is stored using Event Sourcing.

So I guess the answer is: It depends but probably not for everything in your applications or maybe not at all 🙂

 

But what about Data Access?

Another question that came up is that of Data Access technology to be used. Again this is kind of a hard question to give a simple answer to. It also depends on whether you are looking at the Event Sourced domain model or the projected Read Model.

For the Event Sourcing side I really like Greg Young’s GetEventStore which can be used as a standalone server or embedded client. You can either use an HTTP API but as I mainly use .NET on the server it’s native C# client is the way to go.

For the projected Read Model it really depends on what you are using as the data storeage mechanism. In the case of a relational database you could use NHibernate or Entity Framework but these are probably a bit overkill and will hurt performance. On most cases you will be better of with one of the Mirco ORM’s out there like Dapper, ServiceStack.OrmLite or something similar.

I prefer using a NoSQL database though and really like RavenDB or MongoDB. Currently I am using Redis with the ServiceStack.Redis client in a sample project and that is also working really well for me.

So again it really depends on your preferences but choosing for speed and flexibility is a good thing.

 

Enjoy!