Wednesday, March 21, 2018

Getting started with POI and React

This will be a quick one and, quite frankly, a very obvious one. But since I forgot how it is done I better write it down for posterity (and me).

Setting things up

As always you'll need a folder. Let's call it my-example

$ mkdir my-example
$ cd my-example

Then we need to initialize our project:

$ npm init

and accept all the defaults.

Next we need a few packages installed:

$ npm install poi react react-dom --save-dev

Creating poi.config.js

Since by default POI compiles JSX down to Vue's interpretation of what JSX is we need to tell it to use React's JSX compilation. We do that by adding the poi.config.js file with the following content:

module.exports = {
  jsx: 'react'

Creating start script

Finally, to make our project setup complete we should add a start script to package.json to make use of the locally installed POI:

"scripts": {
  "start": "poi"

Time for a simple app

With all that setup all there is to it is to test it with some React components. For that we will create index.js with the following content to display a Hello, world!-type app:

import React from 'react'
import ReactDOM from 'react-dom'

ReactDOM.render(<h1>Hello, world!</h1>, document.getElementbyId('app'))

And just like that, in under 3 minutes, by the magic of POI, we have a fully-working application that can be developed, tested and built for production deployment. I like it!

Happy coding!

Big Fat Ass - Windows + Visual Studio

Warning: this post contains bad language, obscene descriptions and a lot of frustration. Don't read it if you're sensitive.

The fucking nightmare

In the past I used to work with Windows. I liked it - especially Windows 2000 and then XP. It was kind of fresh, you know? Still looking the same as the old win but kinda... better. And after a few small upgrades to the hardware, like a tiny bit more RAM, it worked really fast. I was reluctant to look for other OSes for more reasons than just I got used to it: Delphi, the IDE I was working most of the time in, was not available on other platforms. And I loved Delphi. It was the best thing ever! Especially the Personal edition which was bloody fast and easy to use.

At one point I gave Linux a try. Slackaware to be precise. I felt this was not just for me but also not for any sane human being. I mean come on: compile kernel just to be able to install the distro? Are you fucking kidding me? Then I gave RedHat a try. Well.. better but still: 24 floppies just to install the basic OS? Are you fucking kidding me?!!! And then Ubuntu came along a few years later. I ordered the CD (good old days :D), installed it and liked it instantly. It looked different, foreign... but nice. I got along with the keyboard quite fast, cmd was finally bash and way more humane to work with... Basically, for the first time I didn't immediately went with "You have to be shitting me, man! What a shit hole!". But I was still a Delphi developer so it was more for entertainment than anything else...

Fast forward a few years and that stopped being a problem since I moved to Java.


It's 2018. I work exclusively in Linux, I love every bit of it. I like that I can choose not to butcher my computer with CPU/GPU-intensive operations just to show the content of a fucking folder. I'm loving XFCE and everything about it. I use Linux Mint and my main occupation is frontend development so Windows is pretty much useless anyways. I play on Linux, I watch movies on Linux, I work on Linux. And everyone in my family does too and they like it! My distro of choice is Linux Mint because it is the closest approximation of Windows XP I can get out of the box. And it is good!

And then I decided to give .NET a spin... Man,.. there are decisions that one regrets moments after they are made. At first it wasn't so bad. I still used Linux with Mono, tried Core but it wasn't the right target I was looking for so Mono was the option. Everything seemed to work just fine, MonoDevelop rocks! Fast, easy, nice... I like. I even completed the entire project, was able to test it using XSP...

All was good just up to the point where I needed to test it in real conditions. NOTHING FUCKING WORKED! NOT A SINGLE FUCKING THING! JAVA KILLER MY ASS!!!

So basically creating a solution in MonoDevelop does not mean you will be able to load it into the latest Visual Studio. Windows, when I turned it on, immediately started taking over my CPU fan, spinning it so fucking fast the whole machine became more than just a bit warm. It was FUCKING HOT!!! And still... nothing fucking worked!!!

After a trial and error, looking at Stack Overflow and other enlightened sites I finally was able to throw away all the project files, recreated them in VS 2017 and then it still didn't fucking work! All because some idiot decided to switch from one XML configuration section to another. I mean for the love of God, really?! WHAT THE FUCK!?!?

It took me a better part of this evening to just get it started, then about 3 minutes to add a portion to my node module that converts from fucking backslashes to forward slashes (as though the rest of the fucking world were morons and used the wrong character for path separator) and I was finally on my marry to start hating Windows on my blog.

Post mortem

Unfortunately, as a front developer I need to have access to Edge which, surprise surprise!, is only available on fucking Windows. And this is the only reason I have a separate, dual boot notebook that runs a legal (my God, what a fucking waste of fucking hard earned money) copy of Windows 10.

I need a fucking drink after all this. No wonder .NET developers are so strange... there is a damn good reason for it!

God save us from Windows and .NET. Please!!!

Monday, January 29, 2018

Side project: getting eyes far away

Last year I became obsessed with FPV. I don't mean games - that's kinda for kids. I'm talking here about getting an object, a plane in this case, equipped with a camera and other equipment that can be controlled from a distance. I was trying to get into the multi-rotor business but that seems not to be my thing. Planes, on the other hand, are. So I tried my luck there...

My first time was... well... exciting wouldn't even begin to cover it! It was a mysterious experience! I was actually in a plane that flies around, hundreds of meters away from me, seeing the real life flashing before my eyes. It was simply a blast! But as soon as I flew the first time and saw the land that I already covered something woke up in me: the nagging question what is out there? I guess I am kind of an explorer down deep inside :) And so I begun to cover more and more ground. It soon was pretty clear for me that the equipment I had at the time with a 200mW VTX was not going to quite cut it. All that was made crystal clear for me once I lost the plane after just several hundred meters flight in the neighborhood. It sucked big time and about 600 PLN was forever lost. Sometimes when I drive around I hope to see this plane hanging out in some tree but that didn't happen.

Someone could say: this is way too expensive and too dangerous - but not me. I came back home, late at night that day, and immediately ordered a stronger VTX (used to ride a 200mW one, now I ordered a 600mW ImmersionRC that people said was good for several kilometers!). It took a while before I was able to get back up in the sky but it eventually happened. With the new VTX, a changed site and a new plane I was rocking the sky again!

Over the course of last summer I didn't loose a plane (well, technically I did but more on that later or). I was flying first 1.3km to a landmark I knew and I was passionate to get to. That didn't work because of the antennas that I had. That day I learned that power is not everything - you need to have something to convey it with. And in the case of video transmission (and also the control transmission from your radio to the plane) antennas are the holy grail! So I went ahead and bought 3 of the most recommended (and most sexy) ones - the Aomway clover leave antennas. Alongside the 600mW VTX I also bought a 14dBi directional patch antenna. Using this setup I was finally able to easily break the 2km range!

But my appetite (and the addiction) grew...

So I started experimenting. First about going further than 2km. It turned out that the 100mW OpenLRS system wasn't all that good at ground leve. - so I built a 2m mast that gave me more range. A few weeks later I tested it up to 4.8km and let me tell you the wiggles that I have had that day were nothing compared to the first time with a woman! I was so fucking stressed out I almost fainted!

All things considered it was a pretty good flight. I used a 3s 3000mAh Li-on pack at that flight and it almost lasted to get the plane home. Just a few tents of meters over a field and the plane was safe and sound in my hands. That meant I needed more power. Lot's of it.

In a situation like that power comes from a combination of input voltage, amps, ESC, motor and propeller. So I started looking for the best combination. Just out of share luck I have had a few od 2212 810kv motors around (from my failed attempt to build a 450-sized quadcopter). I thought, since it had the required max thrust (around 1kg) so why I don't I give it a shot. And so I did!

The first attempt was very promising. At 4S and a 10x4.5 prop it flew great and I was able to finally reach the 5km mark. I turned back to see how the battery will behave on the way but it was plenty left. That encouraged me to give it another shot the next day and... that is how I achieved my up-to-date record of 8.2km out and safely back!

Oh boy was I excited! All my efforts were finally paying off! My dream was to take the plane from the place where I was usually flying back to the place I live - which was about 6.5km away. With the record flight of 8.2km I thought it was a no brainer. Man, was I wrong! It's not just the tx/rx/antennas combination but first and foremost the lay of the land that allows (or not) to get to longer distances. Luckily the day before that I have put my phone number and since the plane automatically landed on a busy street and a good man picked it up and called me the plane was recovered - and my ambition was greatly humbled.

This year I'm trying my luck in the same direction that my record flight of 8.2km was. I am hoping to break through the 20km barrier with some new equipment that I have bought:

  • 500mW Wolfbox TX (with potential to be modded to 1W)
  • 1W VTx and a biquad 11dBi antenna that I tested up to 12km with crystal clear picture on the ground
  • an all new Mini Talon with 4S2P Li-on battery pack

The plan is as follows:

  • First do a maiden of the plane with the minimum electronics to get it to fly
  • Add a flight controller for stabilization and get it to work as expected (F4 AIO FC with OSD)
  • Do a test flight over a 1km distance with the lest powerful antennas I have to check the viability of the video down and control up link
  • Do a endurance test with all equipment to see how long will the battery will last at what speeds - hope to get at least 40km range before the batteries are all dead)
  • Get back to the 5km mark and back
  • Get past the 10km mark and back
  • Get past the 15km mark and get back
  • Get past the 20km mark and get back

I have no idea if this is going to work or not. I truly don't! But I hope one day I'll have a video to show you how the flight went and what emotions it gave me!

Happy flying!

Sunday, January 21, 2018

Creating your own ESLint shareable configuration

This is going to be a quick one: How to share ESLint configuration between projects.

Step 1: create a separate project

By separate I mean really separate with its own package.json and own repository.

$ mkdir eslint-config-config-name
cd eslint-config-config-name
npm init
About to write to .../package.json:

  "name": "eslint-config-config-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "author": "",
  "license": "ISC"

Is this ok? (yes)

Step 2: create your configuration

Since the main in package.json points to index.js this will be the spot where we put our shareable configuration. Let's start small - you can always extend it further later on as you work your way through the available rues:

module.exports = {
  rules: {
    'no-var': 'error',

To make sure you don't forget about installing ESLint in your target project add the following lines to the package.json of your configuration project:

  "peerDependencies": {
    "eslint": ">= 4"

This will ensure that when the target project doesn't have ESLint as a dependency then an error will be thrown telling that it needs to be present.

Step 3: publish your repository

In order for the configuration to be available for everyone you need to have it somewhere everyone can access it. In that case it is recommended to add the following keywords to your package.json.

  "keywords": [

If you choose to publish it to NPM then that's fine, but honestly those config files can get pretty specific for your company therefore I would suggest just tagging and pushing to your Git repository, like so:

$ git init
git add .
git commit -a -m "Initial import"
git tag 1.0.0
git remote add origin url-to-your-repo
git push --set-upstream origin master

Make sure your repository is accessible via HTTP or HTTPS - that's going to be needed for the next step, which is...

Step 4: use the config

In order to use that preset you need to add it as a dependency or devDependency to your project:

  "devDependencies": {
    "eslint-config-config-name": "git+https://url-to-your-repo#1.0.0"

That way you are not specifying just the latest version but a specific version. This is done so that projects can adopt the changes to your common configuration as they get the time for it.

Next we need to make use of the configuration in our local project. We do that by creating either a local .eslintrc.js or by adding that configuration to package.json. Since we have already created an example .eslintrc.json in the previous step let's see it being used in package.json:

  "eslintConfig": {
    "extends": [

That's it! Now when you npm install your dependencies then the configuration and all its dependencies will be installed along with it.

If you would like to see a working example take a look at Vue.js + Electron example on Github that uses the common configuration I prepared for my company.

Happy linting!

Sunday, January 14, 2018

Electron - where Vue.js meets desktop

Today I was pushed by some unseen force to check out Electron - the desktop platform that embeds Chrome for everything. Let me tell you - it is amazing! Not only you have just one browser to care about but it automatically runs on all sorts of platforms! Well, I am sold on the idea - how about you? If you're like me then keep reading.

Getting started

First we need a sort of web application. For obvious reasons I am choosing Vue.js (don't even get me started on Angular X or React - I could bitch about them forever). So Vue.js it is. Obviously we need a build system for it. And what better can we get than POI! So let's do a Vue.js app.

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install ` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (vue-electron) 
version: (1.0.0) 
entry point: (index.js) main.js
test command: poi test
git repository: 
license: (ISC) 
About to write to .../vue-electron/package.json:

  "name": "vue-electron",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "poi test"
  "author": "",
  "license": "ISC"

Is this ok? (yes) 

$ npm install --save-dev poi poi-class-component

Since this will be an Electron app we need the electron package too:

$ npm install --save-dev electron

Now we're all set to create our app. In the src folder let's create 2 files: index.js and App.vue


import App from './App.vue'

new App({ el: '#app' })


  <h1>{{ message }}</h1>

import Vue from 'vue'
import Component from 'vue-class-component'

export default class App extends Vue {
  message = "Hello, world!"

h1 {
  background-color: green;

Easy, right? Now here comes the hard part: embedding the application in Electron. I mean, it's not really hard if you know how :). There is a good documentation for both Electron and POI on how do to it but nowhere is there one place that shows the whole solution. So there you have it.


module.exports = {
  entry: './src/index',
  webpack(config) { = 'electron-renderer'
    return config
  homepage: './',


const electron = require('electron')
const isDev = require('electron-is-dev')
const app =
const BrowserWindow = electron.BrowserWindow
const path = require('path')
const url = require('url')

let mainWindow

function createWindow () {
  mainWindow = new BrowserWindow({width: 800, height: 600})

  const entryDev = 'http://localhost:4000'
  const entryProd = url.format({
    pathname: path.join(__dirname, 'dist/index.html'),
    protocol: 'file:',
    slashes: true
  mainWindow.loadURL(isDev ? entryDev : entryProd)

  if (isDev) mainWindow.webContents.openDevTools()

  mainWindow.on('closed', function () {
    mainWindow = null

app.on('ready', createWindow)

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {

app.on('activate', function () {
  if (mainWindow === null) {

Now we need a few things to be able to run it. First there needs to be a way of starting the web application and then the Electron container hosting our app. We'll do that by using the concurrently module and by adding a start script to our package.json. While we're at it let's also install electron-is-dev package used in the main.js script:

$ npm install --save-dev concurrently
$ npm install --save electron-is-dev

Since the electron-is-dev package will be part of our Electron app and will not be bundled with the rest of the app then it needs to be added as a regular, transitive, dependency.

Now the promised start script. Remember, that goes into the "scripts" section in your package.json

"start": "concurrently \"poi\" \"sleep 10 && electron .\""

Please note the sleep 10 before starting electron. That is to give the initial bundler run enough time to start serving our app.

And that is it! Your Vue.js app runs in Electron! And yes, it does hot reloading! Isn't that cool? Well... How about giving your app to other people? You wouldn't do that this way as you do in development, would you? We need some bundling techniques. Luckily for us there is a package called electron-packager that has our backs covered.


Let's start by installing the electron-packager module:

$ npm install --save-dev electron-packager

With that covered let's add a few more scripts:

"build": "npm run clean && npm run compile && npm run package",
"clean": "rm -rf dist $npm_package_name-*",
"compile": "poi build --no-clear",
"package": "electron-packager . --ignore=\"src|poi.config.js|.gitignore\""

I think they are pretty self explanatory. Now from the console when you start the npm run build command it will first remove all leftovers, then build the client application using POI and then package the application for your platform. If you would like to additionally package your app for a different operating system then you can always start the package target with additional parameters, like so:

$ npm run package -- --platform=win32 --arch=all

And that is it! Electron is super cool - go check it out! And as a reward for getting to those last words here's a link to a GitHub repository that has a ready-made working example: Besides the mentioned settings it also contains ESLint integration that I described in my previous post.

Happy coding!

Saturday, January 13, 2018

POI, Vue and ESLint

Writing code is hard. It is however much harder to write code that conforms to standards that are already in the project. Fortunately for us there is ESLint with all the bells and whistles that help in that tedious task. And believe it or not there are ready-made presets and plugins that make the configuration really simple.


First, as usual, we need some packages added to our project:

$ npm install --save-dev eslint poi-preset-eslint eslint-plugin-vue babel-eslint
Then create or update your existing poi.config.js with as follows:
module.exports = {
  presets: [
    require('poi-preset-eslint')({ mode: '*' }),


All that is left is to configure ESLint. I prefer to have a set of rules that don't get in the way while developing but hold the forth when building final version. That is why some of my settings are environment-dependant:

// This defines the mode of operation for checks depending on the environment
const mode = process.env.NODE_ENV === 'production' ? 'error' : 'warn'

module.exports = {
  parserOptions: {
    'parser': 'babel-eslint',
    'sourceType': 'module'

  extends: [ 'eslint:recommended', 'plugin:vue/recommended' ],

  rules: {
    'camelcase': [ 'error', { 'properties': 'always' } ],
    'func-name-matching': 'error',
    'func-names': [ 'error', 'never' ],
    'object-shorthand': [ 'error', 'always' ],
    'prefer-const': 'error',
    'prefer-template': 'error',
    'template-curly-spacing': [ 'error', 'never' ],
    'no-useless-rename': 'error',
    'no-useless-constructor': 'error',
    'arrow-spacing': [ 'error', {
      'before': true,
      'after': true,
    } ],
    'arrow-parens': [ 'error', 'as-needed' ],
    'arrow-body-style': [ 'error', 'as-needed' ],
    'no-const-assign': 'error',
    'prefer-numeric-literals': 'error',
    'indent': [ 'error', 2, {
      'SwitchCase': 1,
    } ],
    'semi': [ 'error', 'never' ],
    'quotes': [ 'error', 'single' ],
    'comma-dangle': [ 'error', 'always-multiline' ],
    'no-console': mode,
    'no-debugger': mode,
    'no-alert': mode,
    'no-var': 'error',
    'one-var': [ 'error', 'never' ],
    'space-before-function-paren': [ 'error', {
      'anonymous': 'never',
      'named': 'always',
      'asyncArrow': 'always',
    'object-curly-spacing': [ 'error', 'always' ],
    'array-bracket-spacing': [ 'error', 'always' ],
    'computed-property-spacing': [ 'error', 'never' ],
    'key-spacing': [ 'error', {
      'beforeColon': false,
      'afterColon': true,
    } ],
    'keyword-spacing': 'error',
    'space-infix-ops': 'error',
    'space-unary-ops': 'error',
    'space-in-parens': [ 'error', 'never' ],
    'comma-spacing': [ 'error', { 'before': false, 'after': true } ],
    'no-whitespace-before-property': 'error',
    'no-multi-spaces': 'error',
    'no-multiple-empty-lines': [ 'error', { 'max': 1 } ],
    'dot-location': [ 'error', 'property' ],
    'getter-return': 'error',
    'consistent-return': [ 'error', { 'treatUndefinedAsUnspecified': true } ],
    'valid-jsdoc': 'error',
    'eqeqeq': 'error',
    'no-return-assign': [ 'error', 'always' ],
    'vue/max-attributes-per-line': [ 'error', {
      singleline: 5,
      multiline: { max: 5, 'allowFirstLine': true },
    } ],
    'vue/html-indent': [ 'none' ],
    'vue/attribute-hyphenation': [ 'error', 'never' ],

As for the rules (and remember this is a personal preference), I don't like the fact of being forced to write every single attribute for a component in a separate line. I think this looks awful. Sure, if there are more than X attributes then it should be in a separate line. That's why the number is so high (5). Also, I found that the hyphenation of attributes that are bound, like :selection-mode causes compilation errors so this one is (at least currently) broken.


A hint for transitioning projects from non-eslint to eslint: when you'll start with the project there will be a massive number of violations. I mean like hundrets of them. Before you commit to fixing them all consider selectively disabling ESLint in all files by means of the following directive:

/* eslint-disable */

Then, when you will get the time remove that directive from 1 file and fix warnings. Then move to the next until ESLint is enabled in all the files. That will make the job much more approachable!

And that is it! Of course you can add or change more rules as you see fit. Whatever works for you.

Happy coding!

Sunday, December 31, 2017

Creating libraries with Vue components

Vue.js is great. There is no question about it. It's small, versatile, conscious, easy to learn - you name it. With the addition of POI it is probably also one of the most friendly frameworks to work with. Let's see how we can share single-file components between projects!

Method 1: npm link

npm link is probably one of the least known features if your primary occupation is creation of web application and you have never created an NPM package yourself. It has been there in NPM for ages and is the primary tool for library creators.

To use it when you have created your library and want to test it then what you do is you run

npm link

in the library folder and you run

npm link <library-name>

in the project that you want to use the library in. That gives you practically a hard binding between the library and the project using a symlink which means that if you introduce a change in the library then the project sees those changes immediately. It's a fantastic tool when you're in the process of working on the library. It can be further streamlined when we specify a dependency using the file: protocol like so:

"dependencies": {
  "my-library": "file:path-to-library"

This is also a great option if the library itself is part of your project and is being used to simply tear the application code from the reusable components. This is a great idea because if the application code changed often and the components change seldom then the size of your client.js gets smaller as all code from node_modules (this includes libraries referenced with the file: protocol) get pushed into the vendor.js block.

"dependencies": {
  "project-components": "file:../project-components"

This will automatically setup a link named project-components inside node_modules. What's even more interesting, when you do the npm install to install dependencies then the project-component's dependencies will be installed in ../project-components/node_modules automatically thus each project that uses that library won't need a copy of the shared dependencies.

Method 2: npm publish

When you want to go for a reusable library that you'd like to share between multiple projects then the right way to go is to use a repository. There is a multitude of options but the one I find really useful in an organization are for all things opensource and verdaccio for all the packages that you would like to keep available only for in-house components. The nice thing about verdaccio is that it automatically acts as a proxy to so all you do in your project is you tell npm that the repository is located where verdaccio is

npm set registry http://localhost:4873/

and you're all set.


To show you how it is done I have created a sample project on GitHub. It consists of 3 parts: the library containing 2 components, a host application using those components and a little bit of automation to start the repository server.


When creating a component library there are 2 options that one can use:

  • include the modules that build the library
  • include the built version of the library

Which one to use depends on the library itself. If you create a library that is to be used in all sorts of projects but you wrote it in some non-standard way (let's say you used CoffeeScript) then to make it useful for the rest of us you need to point the main to the compiled version. However, if you created a library specifically for use within a specific environment it makes sense to create an index.js and point your main entry in package.json to it and to put all your code in the lib folder:

export { default as componentA } from './lib/componentA.vue'
export { default as componentB } from './lib/componentB.vue'
That way, if someone wants to include all of your library they just include it and all is great:

import myLib from 'myLib'

Or using requirejs:

const myLib = require('myLib')

If for whatever reason they want to include only a portion of it, let's say just one or two components and not the whole shebang, then they are free to do so as follows:

import componentA from 'myLib/lib/componentA.vue'

Or using requirejs:

const componentA = require('myLib/lib/componentA.vue')

The latter form allows for the treeshaking algorithm to exclude everything that is not used by the application in the resulting file thus making the final bundle smaller (sometimes a lot smaller - see the use of lodash).

To create a compiled version of your library with POI all you need is to run the following command:

poi build --library index.js

and in the dist folder you'll get a library.js that you point the main in package.json to and you're done!

That's it! It is really simple to create libraries shared between parts of your project and not all that much more complex to create universal applications shared with everyone else in the NPM ecosystem.

Happy coding in 2018!