18. December 2015

Weekly Challenges

Since I started missing a lot of Friday posts, I came up with a new section for which I can prepare during the week.

I’m introducing Weekly Challenges. Every Friday I will post an assignment related to programming. These challenges can be math problems, mathematical phenomenons or building something using a previously mentioned library.

These assignments are to challenges yourself. This is not a competition. I will do my best to design/pick challenges that will be interesting for developers of all skill levels. But do not feel limited to the challenge description, if you can create something more complex than the challenge describes, do it!

If you have great idea’s for futures challenges please submit it via this Google Form.

An overview of the challenges can be found at /challenges. This weeks challenge is the Pythagoras Tree.

17. December 2015

isomorphine

isomorphine (GitHub: d-oliveros/isomorphine, License: MIT, npm: isomorphine)

Earlier this week I came across a post by Marco Romero. It was a highlight of isomorphine, which is a Webpack loader that lets you require and use server-side entities from the browser, as if you were in the server. The browser accesses a proxy of the server’s methods that are being required. The proxy is a mirror of the server-side entity and creates an HTTP request to Isomorphine’s endpoint within the server.

Marco describes it as “A Painkiller for Isomorphic Data Fetching”. With which I totally agree. When developing Isomorphic/Universal apps data retrieval can be a real hassle and this little marble will take way a lot of that pain.

Of course there are established libraries and techniques for solving this issue such as: Relay and React-Transmit. The downside of these approaches is that you are doing a commitment to a framework which could collide with your business philosophy or you just do not like React. Don’t get me wrong I love React, but I can understand if some developer do not or need something more agnostic and now you can.

I could go into the details of how you would use it but I doubt that it will be more complete than the great post Marco did. So I won’t and instead refer you to the post on medium and for more extensive documentation check the README.

15. December 2015

Runjs

Runjs (GitHub: pawelgalazka/runjs, License: MIT, npm: runjs)

Back in the days we used to do everything with Makefile’s now we have Gulpfile’s, Gruntfile’s and probably too much to put in a list. Now there is a new friend in the build family, Runjs, which is a minimalistic framework for executing build tasks.

It’s API consists of just a few functions run, watch, generate and call. With these functions you would create a runfile.js. A simple runfile would look something like this:

import {run} from 'runjs';

export function showFiles(){
    run('ls');
}

export function mkdir(name){
    run(`mkdir ${name}`);
}

These tasks can be executed via the Runjs cli like so:

run showFiles
run mkdir someDirName

It can do everything from watching files to generating new files based on configured templates etc. What I like about this little framework is that it does not require plugins but just Node packages for extra functionality. This in contrast to Gulp where most plugins are wrapped as a gulp-plugin and using libraries that do not have this is as hassle.

To help you get started this is what full runfile would look like:

import {run, generate, watch} from 'runjs';
import fs from 'fs';
import crypto from 'crypto';
import {sleep} from 'sleep';
import express from 'express';

let task = {};

function timeHash(){
    let time = Date.now();
    return crypto.createHash('sha1').update(time.toString()).digest('hex');
}

function exist(path){
    try {
        fs.accessSync(path, fs.F_OK);
        return true;
    } catch(e){
        return false;
    }
}

task.echo = () => {
    console.log('echo');
};

task.install = () => {
    run('npm install');
    run('jspm install');
    task['build:dev:configure'](true);
};

task.uninstall = () => {
    task['clean:dist']();
    task['clean:cache']();
    run('rm -rf node_modules');
};

task.test = () => {
    run('mocha');
};

task['clean:dist'] = () => {
    run('rm -rf dist/*');
};

task.cmd = (...args) => {
    run(args.join(' '));
};

task['build:dev:configure'] = (force) => {
    if(!exist('dist/react.bundle.js') || force){
        run('jspm bundle react + react-dom dist/react.bundle.js --inject');
    }
};

task.watch = () => {
    watch('src/app.less', () => {
        run('lessc src/app.less dist/app.css --source-map');
    });

    watch('src/*.jsx', (path) => {
        let outPath = path.split('/');
        outPath.shift();
        outPath.unshift('dist');
        outPath = outPath.join('/');
        outPath = outPath.split('.');
        outPath.pop();
        outPath.push('js');
        outPath = outPath.join('.');
        run(`babel ${path} --out-file ${outPath} --source-maps inline`);
    });
};

task['build:template'] = (src, dst, context) => {
    generate(src, dst, context);
};

task['build:dev'] = () => {
    run('lessc src/app.less dist/app.css --source-map-map-inline');
    run('babel src --out-dir dist --source-maps inline');
    run('rm dist/config.js');
    task['build:template']('src/index.tpl.html', 'dist/index.html', {compiled: false});
    task['build:dev:configure']();
};

task['build:dist'] = () => {
    task['clean:dist']();
    let fingerprint = timeHash();
    task['build:template']('src/index.tpl.html', 'dist/index.html', {compiled: true, fingerprint: fingerprint});
    run(`jspm bundle-sfx app dist/app.${fingerprint}.js --minify`);
    run(`cleancss src/app.css -o dist/app.${fingerprint}.css`);
};

task['serve:express'] = (prod) => {
    let port = 9090;
    let app = express();
    app.use(express.static('dist', {etag: true}));
    if(!prod){
        app.use(express.static('src', {etag: true}));
    }
    let server = app.listen(port);
    console.log('Express static server listening at http://localhost:%s', port);
};

task['serve:dev'] = () => {
    task['build:dev']();
    task['serve:express']();
    run('live-reload --port 9091 dist', {async: true});
    sleep(1);
    run('open -a "Google Chrome" http://localhost:9090');
    task.watch();
};

task['serve:dist'] = () => {
    task['build:dist']();
    task['serve:express'](true);
    sleep(1);
    run('open -a "Google Chrome" http://localhost:9090');
};


export default task;

14. December 2015

Shem

Shem (GitHub: xixixao/Shem, License: MIT)

demo

Shem is a new “compiled-to-JS”, functional programming language which is statically typed. The semantics are based on Haskell but the language evaluates strictly in a similar way to PureScript. The syntax is S-expressions-based. This for allowing for a LISP-like macro system. Shem’s prelude includes a full-featured, highly-polymorphic collections library backed by ImmutableJS.

It comes with an amazing IDE called “Golem“. This IDE was designed with the language to make the integration seamlessly. The IDE is available at shem.io to work with in the browser. There are plan’s to make it also accessible as a local IDE for developing applications native platform such as desktop.

There is a video available of what I believe is one of the first presentations check it out to see Shem and Golem in action

When this language interests you, you can go over to IDE and follow a small tutorial to give you a quick overview of how the language works. If you are familiar with languages such as LISP and Haskell you will feel right at home.

The owner of the project Michal Srb also want you to know the following:

I am providing code in this repository to you under an open source license. Because this is my personal repository, the license you receive to my code is from me and not from my employer (Facebook).

10. December 2015

Split.js

Split.js (GitHub: nathancahill/Split.js, License: MIT, npm: split.js)

Split.js is a lightweight, unopinionated utility for creating adjustable split views or panes. What I like about this library is the minimal requirements to get it to work. It has no depenencies such as jQuery and does not require you to jump through three burning hoopes before you have it working, just two elements that have a parent in common and you are set. I comes with draggable gutters to resize the panes and the API is very easy, just one function, Split.

So let’s look at some code. Let’s say we have a markup that looks something like this:

<!-- .... -->
<div class="parent">
    <div id="one">
        <!-- .... -->
    </div>
    <div id="two">
        <!-- .... -->
    </div>
</div>
<!-- .... -->

Then a basic split would work like this in Javascript:

Split(['#one', '#two'], {
    sizes: [25, 75],
    minSize: 200
});

It’s possible to add as many elements as you want, as long as they share the same parent. Let’s take three as example:

Split(['#one', '#two', '#three'], {
    minSize: [100, 100, 300]
});

Because this library is unopinionated, it does not come with much styling. You can implement your own styles like so:

.gutter {
  background-color: #eee;
  background-repeat: no-repeat;
  background-position: 50%;
}

.gutter.gutter-horizontal {
  background-image: url('grips/vertical.png');
  cursor: ew-resize;
}

.gutter.gutter-vertical {
  background-image: url('grips/horizontal.png');
  cursor: ns-resize;
}

Note that split works the best with border-boxed element’s, so if you did not apply this within your reset, you could set it like this:

.split {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

The library comes with a lot of extra options which will infusence how the panes and the gutters should act. Check the README for that.