Photo Of Battersea Regeneration - Art Deco Icon In London.

Node.JS Regeneration In One Year Without Tech Nation Visa

  1. How I Regenerated Node.JS Stack In One Year Without Tech Nation Visa
  2. Babel: When Open Source Is Not Free Software
  3. Issuing Proceedings: Suing Tech Nation For Defamation
visitors' counter

NodeTools

A 20th Century Liner Shipping New Node.JS Tools (Below) Zoroaster Testing4.1.2 ÀLaMode Transpiler3.0.0 JSX Middleware1.6.0 Documentary1.33.2 Depack Compilation0.0.1 Goa Server1.1.3 Idio Bundle0.1.0 Splendid PWA1.9.5

Receive Updates

Most of this series is still work-in-process, so please leave you e-mail to receive notifications of updates:


I agree with terms

Or simply subscribe using push-notifications:
📥 Receive PUSH

^^ until I implement this, follow me on twitter


Share This Article

There is a difference between free and open source software which must be understood. Babel, praising itself on being open source, actually harms users' freedoms and delivers them right into the hands of the vendor predator — TypeScript.

Babel: When Open Source Is Not Free Software

12 August 2019 TLDR; Babel is the most relied upon software in the Node.JS ecosystem, yet it leaves out ridiculous bugs that take away essential user freedoms such as an ability to write JSDoc, while its owners get paid up to $10k a month for maintenance and attending events. TypeScript also comes for free, but also has bugs of the same nature that make developers switch to the OOP ideology that is characterised by self-righteous "Open Source" community who feel free to lash out on everyone who disagrees with them. My simple software offers solutions to restore the freedom of the development process, but I don't expect it to become popular — I have created it for myself as part of my spiritual quest in life.

Introduction

When you are studying a particular topic, and become interested in a certain area of this vast world, not only you actively find more information and opinions, but so it happens that bits of the puzzle actually find you in a completely random and unexpected ways. One of this bits was a blog post "My Personal Journey From MIT To GPL", that I came across I don't even know how. Despite the randomness of the encounter, this article had a tremendous impact on me: I finally started to understand the significance of differences in Open Source licensing models, but more crucially, I was ready to discover other knowledge related to the same topic.

A tower building under construction in London.

bandcamp activation placeholder
BandCamp uses cookies on .bandcamp.com domain. Click To Activate.

In short, the difference between MIT, which I put on all of my packages just because that's how I've been doing it from day one by following the lead of all other packages that do the same, and GPL is that anyone can take a piece of MIT work, use it in proprietary software, and start selling it for cash without any responsibilities to the author (other that retaining the copyright notice), whereas GPL requires them to publish the source code of all other products which link to GPL-licensed code (linking means using as a dependency). This point didn't really come home until I realised, that the permissive MIT license allowed corporate entities to not just use my work in their work, but make a product out of what I'd invested hours of coding into, and then compete with me! That's probably not such a big risk, until you accumulate a large code base that actually makes the difference.

That's why I'm now releasing my software under AGPL as well (A meaning that it can't be installed on a server for SaaS purposes either). However, it's not this decision that is the main point of this section, but the fact that after browsing web in search for more info on licensing, I discovered the GNU website which outlines the Free Software Foundation philosophy, that confirmed my suspicions that there is a difference between Open Source, and Free software. In one sentence, what everyone should remember is that free is used to highlight essential human freedoms and rights, such as:

  • freedom of expression;
  • right for privacy ( Article 8 of the European Convention of Human Rights);
  • right for data protection (recital 1 of GDPR about which, the official Endorsing Body of the UK in technology giving out fake Tech Nation Visas does not even know about);
  • and others.
Open Source does not really mean that software which anyone can download and which has its source code released for public is free in humanitarian terms.

As they say, the biggest feat of Devil is that he convinced the world he doesn't exist. Same with Open Source: just because software is made by a "community" of developers without being paid in traditional ways, just because anyone is allowed to fork it and upgrade it, and just because it can be very popular, everyone must believe that such software is quality, good and free. The Open Source Initiative puts it that "the promise of open source is better quality, higher reliability, more flexibility, lower cost, and an end to predatory vendor lock-in". Now I'm going to prove to you that one of the most installed, essential and well-known Node.JS packages, babel achieves exactly opposite objectives while justifying its shortcomings by referring to the "Open Source" label.

Back To Top

Babel R U OK

That's the title of an issue that I opened in Babel's repository after I found out one of the most devastating bugs in the entire Node.JS ecosystem. I already wasn't happy with having to use a dependency with 230+ transient dependencies for every package that I created just because I liked the import syntax and believed that it was essential to follow the modern day standard. Although with an SSD and fibre-optics it doesn't take that long to download and link all of those dependencies, in summer I sort of down-shifted from Sky to mobile 3G and became conscious of inbound/outbound data, as well as worked on an older iMac with a standard hard drive. Therefore, each real dependency took a few minutes to install due to all linking that had to be done against babel's dependencies (the linking N... number actually grows exponentially). But what I found out in August, my last month in England which I spent at Streatham Hill on really short rent, waiting for my Tech Nation Visa that never came, made me absolutely outraged.

So let's take an example that uses ES6 modules, i.e., the JS standard since 2017:

// Tech Nation are shameless liars.
//  console.log('https://technation.sucks')

/**
 * Instantiates the corrupt pseudo-endorsing body.
 * @param {string} location The city of establishment.
 * @param {Person[]} staff The list of corrupt employees.
 */
async function TechNation(location = 'London', staff = [
  'Lindy Pyrah',
]) {
  console.log('Serving venture capitalist in %s.', location)
}

/**
 * The method used by Tech Nation for libel.
 * @param {string} to Whom to lie.
 */
export const expert = (to = 'Home Office') => {
  console.log('Lie to %s', to)
}

/**
 * Proves that the pseudo-endorsing is useless.
 * @param {string} resistance The name of opposition.
 * @param {boolean} willWin Whether results will be achieved.
 */
export const sucks = (resistance = 'Art Deco', willWin = true) => {
  console.log('%s: fighting for freedom.', resistance)
}

export default TechNation
And see how it is compiled:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.sucks = exports.expert = void 0;
// ˅ ˅ ˅ CLICK TO EXPAND ˅ ˅ ˅
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.sucks = exports.expert = void 0;

// Tech Nation are shameless liars.
//  console.log('https://technation.sucks')

/**
 * Instantiates the corrupt pseudo-endorsing body.
 * @param {string} location The city of establishment.
 * @param {Person[]} staff The list of corrupt employees.
 */
async function TechNation(location = 'London', staff = ['Lindy Pyrah']) {
  console.log('Serving venture capitalist in %s.', location);
}
/**
 * The method used by Tech Nation for libel.
 * @param {string} to Whom to lie.
 */


const expert = (to = 'Home Office') => {
  console.log('Lie to %s', to);
};
/**
 * Proves that the pseudo-endorsing is useless.
 * @param {string} resistance The name of opposition.
 * @param {boolean} willWin Whether results will be achieved.
 */


exports.expert = expert;

const sucks = (resistance = 'Art Deco', willWin = true) => {
  console.log('%s: fighting for freedom.', resistance);
};

exports.sucks = sucks;
var _default = TechNation;
exports.default = _default;

The code looks ugly but since every JS developer trusts Babel so much (why not, the fact that it's got 8m+ downloads per week means it's reliable, doesn't it?), there's no need to ever look into the "build" folder. Can you spot any problems with that code?.. It's OK if not, I couldn't either, and that was partly because I'm using VS Code as my IDE. No issues can be seen when requiring source for testing within the package directory, since JSDoc annotations to functions work fine when importing ES6 source code for testing. Problems only start after publishing the package, installing it in other packages, and requiring the TRANSPILED code in them.

When importing transpiled published methods from other packages, at first sight there's kind of no problems:
import TechNation, { expert } from './compiled'

TechNation()
expert()
// ˅ ˅ ˅ CLICK TO SHOW EDITOR HINTS ˅ ˅ ˅
import TechNation, { expert } from './compiled'

TechNation()
expert()
default import jsdoc works only when typing arguments
The hints for the default method don't show on hover, but come up when starting to type arguments.
first named import jsdoc works
The first named method's annotations are OK.
However, when the default import has a different name from the one in the required code, and when we also require the second method we run into trouble:
import technation, { sucks } from './compiled'

technation()
sucks()
// ˅ ˅ ˅ CLICK TO SHOW EDITOR HINTS ˅ ˅ ˅
VSCode hints for imports are broken
The default method's annotations don't appear neither on hover nor when typing arguments. The second named method's annotations don't even exist (the types shown are inferred from the default values).

So what's actually happened here? Well, in the first instance, arguments for the default TechNation import are shown only because VS Code infers the type using the NAME of the variable in the target source, rather than understanding what's actually exported/imported. The fact that it's broken when the name changes proves that. The editor does not know what the default import is, it just knows the name of the variable and does the Math. It's quite difficult to come across this, because typically the name of the default export is also the name of the default import. It was only when I imported a variable using a different name that I noticed it wasn't working. This bug has been fixed since TypeScript 3.2 (October 2018) after my bug report by TypeScript checking for the assignment of __esModule and picking up the default export. Nonetheless, the IDE still doesn't show hints for the sucks method. Why?

Let's have a look again at the transpiled code generated by Babel after about the middle of the file:
/**
 * The method used by Tech Nation for libel.
 * @param {string} to Whom to lie.
 */


const expert = (to = 'Home Office') => {
  console.log('Lie to %s', to);
};
// ˅ ˅ ˅ CLICK TO EXPAND UNTIL THE END ˅ ˅ ˅
/**
 * The method used by Tech Nation for libel.
 * @param {string} to Whom to lie.
 */


const expert = (to = 'Home Office') => {
  console.log('Lie to %s', to);
};
/**
 * Proves that the pseudo-endorsing is useless.
 * @param {string} resistance The name of opposition.
 * @param {boolean} willWin Whether results will be achieved.
 */


exports.expert = expert;

const sucks = (resistance = 'Art Deco', willWin = true) => {
  console.log('%s: fighting for freedom.', resistance);
};

See the problem? The transpiler generated and inserted the exports.expert assignment, separating JSDoc for the sucks method from the actual function, preventing any in-editor documentation from being shown to developers! That's causing so much harm to everyone, especially Node.JS package makers who are diligently documenting their code, trying to make it appealing to other developers. In other words, I'm carefully and honestly writing my JSDoc for all methods, just for the tool that I put my trust in (while having to tolerate ~5k linking dependencies), to effortlessly destroy all my efforts! WHAT. A. SHAME.

Back To Top

Incorrect placement of JSDoc comments #8437

That's the title and number of the second issue because the first one was removed since it was "insulting". In BABEL R U UK I didn't use swear words to call authors names to make it insulting, it was primary "all caps", or what can be considered raising the voice at maintainers for that bug asking them how can they do that to me and others. It just made me really angry, angry because I'm a Senior Software Developer with a BSc/Master degrees in Computer Science yet you don't get no respect for that amongst everyone else who calls themselves developers on the web after taking an online-course, angry because I'm passionate and obsessional about quality, angry because I finally understood why JSDoc was not showing in the editor properly for my own packages. In the end of the day, I got angry because there's nobody else who would tell them off for that offense, there's no Open Source quality assurance commission that would shame an essential piece of Node.JS infrastructure for how they treated me and my work. It finally established my attitude towards so-called "community" where no responsibility is ever taken by anyone and my freedom of writing documentation using JSDoc was taken away from me by software that pretty much extorted me into using it because of lack of alternatives and Node.JS's inability to JUST make ES6 modules happen. Let's have a look at the the first comment from a maintainer on that issue:

demurgos avatar
demurgos commented on 8 Aug 2018 •
Your previous issue was closed because its tone was insulting. This one is too: it's not just about avoiding all-caps. Babel is used by thousands of production-grade projects, many of which use doc comments to generate their documentation. With a bit of humility, you may have recognized that maybe you are missing something instead of immediately calling the maintainers incompetent.

Now, to answer you issue: the output you see is expected behavior (Edit: See below, I agree that it's worse than in Babel 6). Output generated by Babel is no longer source code (by definition, it's generated content): it is not intended to act as source code. Comments are emitted on a best effort basis to help readability when debugging the output file. Babel output should be treated similarly to machine code: you do not generate documentation from machine code but from the source.

The input you pass to your documentation generation tool should be the the source code with ES-next syntax, not the lowered Babel output.

My reply was that I wasn't calling the maintainers incompetent, but all people who blindly make religion out of Babel without knowing what they are doing. The comment was marked as disruptive and I'm not going into that. You can talk to the person mentioned here and he'll confirm that I reached out to him and personally apologized for overflow of emotions. In the "disruptive" comment I only made it clear that he misunderstood the point that I made regarding JSDoc blocks (hence edit in this comment) and that it's not generated documentation that suffered, but actual transpiled code. Mr Samborski continues:

I also want to remind you that Babel is supported by a small team of volunteers. If you want to improve things, you can help and send PRs. You are not entitled to free support and insults are not tolerated.

Babel Open Collective landing: £300.000 yearly budget.

Babel Maintainer getting paid $15.000 in August

Babel Maintainer getting paid $8.000 in August

OK perhaps I'm not entitled to support unless I contribute moneys, but the Open Collective page states that 2 hours of support goes only to the most advanced contribution tier, called "Base Support Sponsor" for $24k a year. OK Babel you've charged AirBnb and AMP for 4 hours of your support $4k in August ($1k per hour, but that's none of my business really how much you charge for support, I'm actually happy you can do that, what I'm mad about is how you betray trust of all other people who contribute money without being entitled to support), so the rest $19k must have been spent on maintenance, such as fixing bugs?

Looking at it closer, this seems to be a regression introduced during the Babel 7 beta.
A simple workaround would be to use a stable version of Babel (Babel 6).
It's not good that this regression happened, but it's why Babel 7 is still in beta. Thanks for reporting issues on the beta release, but there's no need to get mad if you use unstable versions. This will probably be fixed until the stable release.
babel issue comment complaining about non-beta version
Unstable version they say... Babel 7 went out of beta since actually August 27, 2018.
babel issue comment saying how a person had to change entire built system to typescript because of babel
Just as I was writing this article, another comment appeared highlighting exactly all of my concerns here! Sometimes I believe in God!

2 Babel maintainers getting paid almost $100.000 on Open Collective

I will abstain from commenting further because then this entire page will have to be marked as "disruptive", towards both "volunteers" (maintainers cashing in 10k a month khm-khm each) and contributors willing to pay this money for such reliable software. Is it really wrong of me to show negative attitude towards this state of affairs? Just one last thing I want to bring up here, is that the Babel's maintainers get "to be involved in the process that moves various JavaScript proposals forward" (Open Collective's landing). Yet we have bugs like that. I believe it's essential to have traditional values met first, before working on proposals, and Babel was responsible however it failed. For comparison, Bootstrap receives only £3k yearly, arguably being the second most important piece of the web infrastructure after Babel. A picture is worth a thousand words:

Balmer: Babel Babel Babel TypeScript

Back To Top

Promise<Open Source>.reject()

Going back to the the promise of open source is better quality, higher reliability, more flexibility, lower cost, and an end to predatory vendor lock-in, so far we can draw the following conclusions:

  • Better quality is not a thing since JSDoc is essential to the development process. You can't not have functions annotated properly (@param, an occasional @example) if you publish your package. A transpiler MUST keep JSDoc in the proper place, if it doesn't that means the transpiler is of low-quality since it doesn't even have tests for JSDoc.
  • Higher reliability is a myth because even though the issue was filed, with screenshots and explanations, it was ignored totally for the amount of time equal to one year, even after the software went out of beta-testing.
  • Lower cost is actually higher, because installing Babel will increase the npm install duration of each new dependency for up to a 20-30s, and much more on hard drives (compared to SSD). Say 5 installs a day of new packages in a team of 5 people, that's 12 minutes a day and an hour a week wasted on looking at the "linking dependencies..." message.
  • and finally, perhaps the most unintuitively, an end to predatory vendor lock-in becomes...

The Start Of Predatory Vendor Lock-In

First of all, if you're using Babel you already know that you don't have freedom. You'd want not to have install a transpiler, when since Node 8 you only use it for modules. As I mentioned earlier, that's entirely Node.JS fault, who should have treated import as require and export as module.export long ago instead of splitting the hair around the specification of how modules should actually work. However, I'm really happy this all happened since every obstacle is an opportunity to create something new which is independent, better, and more unique. But what other negative effect does Babel have on the ecosystem and the development of JavaScript by breaking JSDoc?

The answer is that without properly working JSDoc, people are tempted to use TypeScript — the grandest evil that you will ever encounter today. I know this because that's how I felt when I struggled with my JSDoc, when it wasn't working. I thought, OMG things are just not working, if I just used typings, that would solve all my problems! And I'm sure that's how other developers feel as well. But once you make this decision, there is no road back, you become hostage to the most overrated technology ever, that was made by Microsoft and a) makes you addicted to typing every singe thing b) tells you that apparently that's how you scale up, i.e., fear-mongering that without it your large project will fail, c) basically does what the heading of this section says, that is locks you in TypeScript, because the more code you write in TypeScript, the less likely you will go back to pure JavaScript, and d) turns you into a close-minded zombie ready to defend TypeScript at any price because it's too much psychological pain to admit that you're now hooked on technology, rather than using technology for your own means.

TypeScript is too unnecessary for a duck-typed programming language. Because people learn Java at universities, they will want to use TypeScript, forgetting that JavaScript is basically a functional programming language. .Map, .reduce, .filter, these are the pillars of the web development, not types. Types are just there to make life convenient, it's a tool but TypeScript makes them the aim in itself. You can achieve everything you need with JSDoc, but software like Babel makes it impossible, and I have a slight suspicion (any fellow conspiracy theorists?) that Microsoft secretly encourage Babel to keep this awful bug. Although it's just a speculation, it is based on the fact that Microsoft also break JSDoc capabilities and don't want to fix them, openly stating that people should switch to TypeScript, instead of MS fixing bugs. Proof or get out? OK then, here's your proof.

The nature of the bug is such that TypeScript (not language, the service running in background in VSCode for JSDoc) will not read source code files required at level 2+ from the main file. E.g., main is index.js, requires lib.js - fine; lib.js requires lib2.js - file not read, types not resolved, JSDoc broken.
/* 1. Create a new package with src folder with the following structure: */
// src/index.js - exports a default from lib, the rest doesn't matter.
export { default as bug } from './lib'
// CLICK TO SHOW FULL INSTRUCTIONS
/* 1. Create a new package with src folder with the following structure: */
// src/index.js - exports a default from lib, the rest doesn't matter.
export { default as bug } from './lib'

/**
 * Directly exported method.
 * @param {string} name The name of the method.
 */
export default function (name) {
  console.log(name)
}

// src/lib.js - exports a default from other file.
export { default } from './lib2'

// src/lib2.js - documented method
/**
 * The bug in TypeScript.
 * @param {Config} [config] Options for the program.
 * @param {boolean} [config.shouldRun=true] A boolean option. Default `true`.
 * @param {string} config.text A text to return.
 */
export default async function typescriptBug(config = {}) {
  const {
    shouldRun = true,
    text,
  } = config
  if (!shouldRun) return
  LOG('@artdeco/typescript-bug called with %s', text)
  return text
}
typescript bug does not appear in source code
In source code, everything works fine. You don't find out about the bug until you publish your transpiled package and consume it in another place. Together with Babel's bug, it brings total devastation to your JSDoc documentation.
A use case? Say you have an index.js file which exports a method from lib.js. The method from lib.js is a function which returns an instance of a certain class implemented in a separate file, User.js. I.e., index.js -> lib.js -> User.js. Once you published package, the return of the method from lib will be unknown. All your documentation will once again be broken. Refer to the GIF below:
typescript bug happens in transpiled code: cannot jump to imported file at level 2
In published code, can't jump to local level 2+.
Interestingly, stuff works when coding via yarn link — another conspiracy
to lower your chances of detecting the problem for your package consumers? 🤔

You can easily verify this with the following source code, after doing yarn add artdecoweb/typescript-bug (this will install the package from GitHub):

// hold CMD and click on the package name to jump to source
import ok, { bug } from '@artdeco/typescript-bug'

ok()
bug()

OK what's TypeScript's opinion on that (see the issue I opened only a month after Babel's one)?

mjbvz github avatar
mjbvz commented on 6 Sep 2018
TypeScript powers both VS Code's javascript and typescript intellisense. It is what analyzes jsdocs.

I recommend that you try writing d.ts typings for zoroaster. Even if this specific issue is fixed, proper typings will provide a much better experience

I don't really care what powers VS Code, I NEED JSDoc to work. I have the freedom of expression of my documentation. And sure, much better experience. Just stop lying, all the experience that I want can be (and has been) easily achieved with JSDoc. You just want to convert as many people into TypeScript . Still, people would argue that because TypeScript is Open Source, it's good. Not it isn't and if there's one thing that I want to convey on this page, is that Open Source doesn't mean free, not in a sense that it gives or protects your freedoms. Much otherwise, to be honest, a lot of software take the freedom away by providing low-quality solutions and introducing bugs that are then used against you so that you become a consumer of technology you don't even need. Using TypeScript instead of JSDoc for Node.JS programming is like treating a scratch with surgery when you just need to apply a plaster.

Instead of just being a hater of everything and everyone, I went on and implemented a tool called _Typal_ that could be used to embed JSDoc documentation into source code automatically from a separate XML file. It is also part of the NodeTools stack and is needed for other requirements, such as making externs compilation as I will show in another article. I then published information about it on Medium. The first response that I got gave me an incredible amount of joy:

medium comment protecting typescript

I didn't change the article ever since, so you're welcome to find all my amateurish spelling mistakes. I only got a C in my first-language English in my first year in England, after all, I'm not gonna deny I'm a stoopid. I hope Medium does not sue me for not matching the "Supposed level of professionalism that Medium is supposed to represent". O-M-G. And the truth is, if I wrote how much I love TypeScript, added a simple tutorial of how I just switched all of my code to it, and then praised Microsoft for liberating us from JSDoc, I would have got 10000 claps and Tech Nation Visa would have been in my pocket. Although what gives me hope is that there were people who gave me a few claps also so I know developers are keen on being liberated from this tyrannical OOP ideology and its followers, feeling so free and secure to shame anyone who thinks differently, and that's exactly what my software achieves — gives actual freedom. You will learn more about types and Typal in one of the next articles.

Back To Top

Just To Be Objective

After all, I do use VS Code and it's kind of really good (except for when it lags when I create new files and starts side-bar search as a reaction to typing the intended filename). I don't mind building my own JavaScript Node.JS IDE one day (it will be called Moderne and it would be something like Dreamweaver but with JSX components for easy visual editing as well as more nuanced coding), but I have to admit that TypeScript succeeded and pushed the JSDoc state-of-art forward in two directions:

  • @type {import('package').Type} statements. That's brilliant and gets rid of the need to actually import ES6 modules to annotate types, which is sometimes not even possible (think circular dependencies). Google Closure Compiler needs to learn to understand this syntax, and I hope one day I'll have enough time one day to work on that. There's also the same bug as above but regarding importing typedefs at level 2+, therefore all types need to be imported in index.js, and only from there in other files.
  • @type {TypeA & TypeB} unions. This is also crucial and important because otherwise there's no way to annotate "extends" functionality.

These annotations can be written in pure JS, without having to write TypeScript since they are just comments. Things that are not possible without TypeScript which should be possible:

  • Annotating types of even listeners, e.g., on(event: "close", listener: () => void): this;.
  • Overloading of methods.

This praise still doesn't mean that keeping bugs that prevent proper working of JSDoc in the IDE, not implementing essential JSDoc features such as overloading, and then openly telling me to switch to TypeScript justifies the "FOSS"-iness of VS Code. In the age of capitalism, why would a corporation invest time and labour resources into developing a product? Or you think that apart from monetary gain, there is no secondary rewards such as wiring developers brains on subconscious level for a particular frequency expressed in an attitude towards a company? In case of a programming language, this wiring goes so deep because you literally express yourself using the language, and what's the first thing that comes to mind when you think TypeScript, your daily tool that earns you your daily bread? That's right, Microsoft. For some people that's fine, but not for all of us. Maybe I'm hypocritical when I don't associate VS Code with Microsoft but oh well you caught me here I just don't like TypeScript. Finally, I must admit that I fell into TypeScript trap in my first industry year, and thought "this is how programming should be done" because of a lot of Java coding, but that affair was quickly put to an end by my manager so many kudos to him. So thank you GNU for putting it so clearly, that free software protects human freedoms of users, rather than comes for free.

Back To Top

Code À La Mode

Code À La Mode is one of company names that I came up when thinking of names for my software company, prior to getting the Art Deco™ insight. What I wanted to convey from the very beginning, is that modern code is beautiful, eloquent and practical. ES6 modules, async syntax and destructuring are the best features of JS, because they are so straight to the point as to what their purpose is, and just handsome to look at.

So after the final tipping point with Babel I took some time to write my own transpiler, since that idea had long been in my head prior to that. But building ASTs, traversing them and generating code is too much effort. Programming must be practical, and like the language, solve problems at hand rather than build sand castles around standards and stuff. The second approach to transpilation is to actually use regular expressions, because imports are pretty much requires:

import ArtDeco from      '@artdeco/stdlib'
const  ArtDeco = require('@artdeco/stdlib')

import { artdeco } from      '@artdeco/stdlib'
const  { artdeco } = require('@artdeco/stdlib')

import ArtDeco, { artdeco } from '@artdeco/stdlib'
const ArtDeco =         require ('@artdeco/stdlib'); const { artdeco } = ArtDeco

and exports are almost the same as assignments:

export default class ArtDeco {}
module.exports =     ArtDeco {}

export const artdeco = () = {}
     exports.artdeco = () = {}

What's the point of all this intellectual exercise of making up random requirement like what the ES6 modules standard is for Node.JS when all you have to do is to read the source code from a separate file? It probably is important in a browser, but who's ever going to use something like "async namespaces" in Node? Sure, regular expressions are probably not as robust as ASTs, but they also don't require installing 4k dependencies, and can be run in literally milliseconds! I've transpiled 100s of packages with ÀLaMode now, and the only problem I encountered is due to the fact that I implemented it in such a way as to cut out comments, strings and regular expressions first, then paste them back to prevent false-positives, but when you have something like const a = `https://test.com` you might have a problem because the transpiler removes the comment first, and the opening backtick does not get balanced with its counter part, so that if there is another template literal later on in the file, what's between them will not be transpiled. OK that might be frustrating that it's not 100% accurate, but it's 100% practical, and I know of a way to overcome that, I just couldn't be bothered when all I can do is to write 'https:/' + '/test.com', or even better url.format({ protocol: 'http', hostname: 'test.com' }) (since I had to use backticks, that means that the URL string needs to be formatted).

alamode transpilation example: clean code
Example from Github: all one has to do to enable modules, is to rename import into require, and export into the module.exports assignment. All module.exports are moved to the end of the file because otherwise you can't export a default declared after a named export.
Babel output? Here:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.b = exports.c = exports.default = void 0;

var _stream = _interopRequireWildcard(require("stream"));

var _path = require("path");

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

class S extends _stream.Transform {
// SHOW WHOLE FILE
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.b = exports.c = exports.default = void 0;

var _stream = _interopRequireWildcard(require("stream"));

var _path = require("path");

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

class S extends _stream.Transform {
  /**
   * Creates a new instance.
   * @param {string} path
   * @param {Stream} [parent]
   */
  constructor(path, parent) {
    super();
    this.source = (0, _path.join)('example', path);
    if (parent instanceof _stream.default) this.pipe(parent);
  }

}
/**
 * A function that returns `c`.
 * @param {string} input
 */


exports.default = S;

const c = (input = '') => {
  return 'c' + input ? `-${input}` : '';
};
/**
 * A function that returns `b`.
 * @param {number} times
 */


exports.c = c;

const b = (times = 0) => {
  return 'b' + times ? `-${times}` : '';
};

exports.b = b;

Which one looks better? Again, the freedom to just transpile code with minimal changes to enable modules which Node.JS cannot do, is taken away by Babel that thinks it is entitled to append ;, prepend use strict;, insert random interops, rearrange code and break JSDoc. So instead of just letting us use beautiful import syntax for the simplest task of dependency injection, Node.JS and Babel provoke a situation where we must use free software when its authors, who travel the world lobbying for standards, tell us you how we all must think. To clarify the comment below, the author is saying that I can configure the use strict in config, but if I use the modules transform, it is enabled automatically (and the way to disable it is not documented). In other words, even if I KNOW my code will be transpiled, I can't use imports in a non-strict file only because it's not a standard. All this standards-worshipping is so annoying.

babel maintainer commenting not to use es6 modules without strict mode

Back To Top

Hacks Vs Standards

I'm a strong advocate of practical programming, which means that you should not stuff your head with paradigms, methodologies and principles, and then go out of your way to follow them, even though they slow down the development process. For example, when I worked in London, "semantic commit messages" was introduced. This means that every commit should start with something like fix: bla-bla, test: bla-bla, and apparently because it's a convention, it's good. We even had it enforced with a git-hook that would add red cross if the message wasn't following the standard. But what happened was, when you published a package, you would get an automatic commit with v1.2.3 by NPM or yarn, and when uploaded to GitHub, that would give you a red cross. So for those cases, developers had to undo the versioning commit, and update it with chore: v1.2.3 message. That wasted at least 20s of everyone's time again and again.

big lebowski quote can't be worried about that

When I started working on Open Source, I followed the employment-style convention, like writing extended git messages, making pull requests etc. Then I quickly realised I was wasting my time, so my commits now look something like that:

commits messages

I do write some descriptions, but if it's a changelog it's like c123, a build — just b, some docs — doc, when I can't be asked it's . (I can't remember where I saw it but there was a repo of quite a big project where entire history of commits consisted of just .). I'm sure that's how most people do it as well on a single-person repo, but if you are still bothered with PRs, merges and proper English descriptions in your commits, you might consider using the time on adding a few additional tests/examples instead. I understand that it's not entirely appropriate for repos with more than one maintainer, my point being exactly that if you're doing it for yourself, don't create obstacles that will slow you down for no reason other than "conventions".

He that fears every bush must never go a-birding.

Another example was when I implemented a recursive select/recursive delete operations in the sql-generation library at work. Firstly, even without those operations the library that I wrote wasn't allowed to go though initially because of the fear that it might leave a possibility for SQL injection, despite the fact that it was only to be used for internal purposes. Secondly, if I just used an existing library which apparently was safe, I would have never been able to add the recursive functionality, which is essential when you want to create a testing database, then instead of dropping and bootstrapping it all over again for each test, you could just clear it, clear only a part of it, or even select a slice of the state for snapshot. Without recursive select/delete, you can't do that (recursive means that when you have a campaign with a client_id as foreign key, you can select a nested structure in one query, or delete both records without running run into the constraint). However, the feature wasn't being merged in because of caution that one of developers will one day drop an entire production database, with links being sent to articles on Reddit how one person did it on day 1 at his new workplace.

fear word on fingers tattoo
If there is a single tattoo that I would ever do, it's this one (saw it it a movie trailer 2 years ago, can't remember which one).

I don't think that it's possible that a 100GB production DB could have been accidentally dropped, because the recursive select for delete would probably take a few days to complete if the server didn't even blow up prior to that. So my reviewer and I met somewhere in the middle by adding a regex check against a part of the url-string of the prod database. Although it was a really good idea of my peer-reviewer that actually gave sense of security to everyone, I don't believe it's always "better safe than sorry", and sometimes too much fear stagnates and slows down the process. If the database was deleted, then there should be a process to quickly find out about it and put it back. The world doesn't stop there for a small company (small in HMRC sense, but big in wonderfully amazing sense) and advantages need to be properly weighed against risks rather than assigning 100% red alert to every piece of code that deletes something.

As you could already have grasped, freedom is what I live for, and happiness for me is when your mind is free not only from outside influences, opinions, commentaries, but also from deep-rooted believes and "common sense" that we consider our own. When I passed out in the kitchen after a sleepless night without having any meals and opened my eyes to see the washing machine in front of me completely disoriented, I was totally happy, I was blissful beyond words, because I didn't know where or who I was. Then your mind kicks in and takes over and you become its hostage to fear, anger (e.g., when such villains as Tech Nation ruin your life) and other societal wirings. I always give this example and I feel sad for all so-called scholars/theologists who make theories about the nature of the world just to become prisoners of a virtual system — they will never know what happiness really is. Happiness is freedom, not freedom to choose, but freedom from the choices that we make (occasionally, I'd say somethings smart of funny and then feel like I stole that so pardon me if it's so 😔).

So I would suggest people start feeling less constrained by standards' apparition in order to go beyond what's normal and find out something really new. OK let's get concrete now and how it all relates to software in question. The problem with not generating ASTs to build a transpiler, is that the professional software development for a mature project goes the following:

  • go into your tests, and add a test case, i.e., the scenario that you want to either fix, or make possible;
  • then continue to implementation and add a rough sketch of how you think it can work. Do as much coding from head as you can without running the program;
  • run the focused test, see it fail with an error;
  • Set the debugging point at where it fails, and start the debugger;
  • when the debugger stops, check the contents of variables, properties, etc and see how the state of the program is different from what you expected when sketching it;
  • update the code, save it and your test should automatically rerun;
  • iterate; then run all tests to ensure nothing else broke (regression testing).

You DON'T debug with console.log, manually calling node program.js after each change. console.log is only for really limited cases like when forking a process (even then VS Code apparently can auto-attach to a fork on the same debugging port but I never got that working). I know for some people that's obvious, but many developers don't know how to use debugger which is essential.

But the problem you will run into when using a regex-based transpiler, is that you cannot generate source maps, because a source map is a collection of mappings of entries in source code to entries in the transpiled code, entries being variable names, properties, operators and everything else. Without this information, you can't have a source map, and without source map, when you debug in VS Code, your debugger won't open the source file, it will open the transpiled file in the read-only mode. You can't work like that and be efficient at the development process outlined above.

// copyright bengourley
// https://gist.github.com/bengourley/c3c62e41c9b579ecc1d51e9d9eb8b9d2
"mappings": {
  "0": [
   ^
   └── the line number of the output file

    "231 => source.js 5:64 foo"
      ^        ^       ^    ^
      │        │       │    └── the symbol name from the source file
      │        │       │
      │        │       └── the line:column position in the source file
      │        │
      │        └── the name of the source file
      │
      └── the column number of the output file

  ]
}

Therefore, to generate a source map, you need to have an AST. Or do you? The answer is not necessary. I watched the news the other day, and there was an International Olympiad in Informatics happening recently. Olympic programming is a special kind of programming, you need to be like really smart, know all these algorithms, their Θ-s (running time as function of size of data) and how to solve algorithmic problems, so that's for special people with high IQ. I don't think I have high IQ, but solving problems in web-computing comes natural during a creative process, so practical coding is definitely more about being artistic and making something sleek by applying simple solutions that achieve results. You don't need to be smart, you just need to think outside the box and dismiss standards. The true task is to find a simple solution because there always is one.

So if we need a mapping, but don't have AST how do we go about solving this? The answer is that we need to keep the line and column numbers intact when updating the imports into requires, so that then each line can be split by whitespace, and pretty much mapped onto itself! That's the only way to do it.

If when developing the transpiler, I was restricted by such thoughts as "but regexes won't have 100% coverage" or "I will have to make sure the interoperability follows the specification" and all the rest of the nonsense, I would not be able to achieve my only aim, that is, use import instead of require because it looks so handsome. And having my own ES6 modules transpiler, allowed me to build the JSX transpiler also — obviously that's not possible if you just use somebody else's software. The joy of being an indie developer!

Back To Top

A Sad Spammer Is All I Am

In October, I was casually browsing the web and found out about the recent release of React, where the link was posted to an issue on GitHub that relates to ES5 transpilation. In there I saw:

sindresorhus avatar
sindresorhus commented on 20 Feb 2017
While most of my modules also work in the browser, I make them mainly for Node.js. I love how dependencies in Node.js just work (1) without having to resort to a bundler, compile-step, and a huge config file. ... The web on the other hand is a mess. ... It would also be hard for individual packages to know what Babel (2) config to use.

2 things to take away:

  • Although import is a language feature since 2017, many people, including the top Node.JS Open Source developer, use require because it just works. This is also true for other packages such as Koa, Express, etc.
  • Babel IS de-facto what powers the web and you know that, you can't live without Babel.

For me, keeping using require is not a solution when I can see how pretty imports are. It's like still using callbacks/promises when you can use async. Why should we all be limited in expressing ourselves using the richness of our language only because of outdated infrastructure that we have?

I knew who Sindre was because I saw how much donations he collects, but I didn't have good opinion of him exactly because of those donations. Not that I was jealous of money, I just have an issue with professionalism and whereas I don't doubt Sindre's talent or ability, it's the herd of developers that don't create anything themselves and only consume packages, donating to the Open Source "stars" because of a cult of personality. Again, controversial thinking, but I have the right to express myself. If you take into the account the fact that when I applied for Tech Nation Visa, and gave them an example of how I created a testing framework, and they called it, a "tool made using frameworks which is not used by anyone" you might be able to excuse me. I knew that if Sindre applied for the visa, he would immediately get it just because of how well he's known in the community. That's not how things should be?

For a second I thought I'm wrong about Mr Sorhus, maybe that he's actually really cool and chilled guy. So I commented on the post, "Epic I don't want to transpile anything as I also write for Node :P @sindresorhus you can use import and export in your packages without Babel by installing my regex-based transpiler alamode: https://github.com/a-la/alamode! It's super-fast, has a require hook and works without building any AST! You can even debug with no problems." Then I explained the bug in Babel.

my comment marked as spam on github

That really ticked me off. If I was a revered Node.JS star, and somebody commented on one of my issues on GitHub, showing how Babel is destroying JSDoc, I think I would have been like "Oh OK thank you brother/sister, I'll probably keep using require but thanks for your work!". It was the second time when I showed off my work which nobody wanted, and then I vowed never to give a crap about my packages getting downloads ever again. I knew I was doing all this work for MYSELF, not for anyone. I would greatly appreciate if you skip giving me stars on GitHub I really don't care. The work I've done is for my company first of all, and for the community secondly, but only community that can appreciate the importance of JSDoc, not community that for years doesn't see how Babel is ruining it.

I only had one thought in my head, it was "it's just packages mate, just packages"... Although I do realise, that the language that I used was not appropriate, I said "🔩 (scr**) corporate Babel" and I have to issue an apology for this rude language to everyone, it's not great to talk like that. But the meaning of this word is "used to express anger or contempt" and I had nothing less than contempt for Babel, an essential piece of Node.JS ecosystem that EVERYONE depends on, who's authors can't write a single test for JSDoc. Open Source: because everyone can be a professional Software Developer on the internet.

To be noble, one’s response to suffering, in oneself as much as in others, must not be to alleviate it, but to use it in becoming greater still. The noble person suffers greatly but is unwilling to cease their commitment to being great. Nor will they invite pity. So they will not try to display their suffering, but will hide it behind a mask, e.g. a mask that treats all suffering casually (§270). The terrible suffering of the higher person, and the herd morality that encourages the alleviation of suffering, means they often come to ruin (§269). They need to forget what they know about life and themselves, their contempt and revulsion; and so they become seduced by flattery and lose their nobility to become someone ‘great’, revered by the herd.
eagle photo

Nobility or strive for it means a lot to me, but it's not measured in money at all. I might not have the visa, I might have no money on my account and in a year I might have only bought 1 piece of clothes which is track suite bottoms that I wear almost every day, what I do have is my commitment to quality software, own Node.JS stack and independence. I don't need to be told how to think or how to do things. I never needed any Tech Nation experts to comment on my work, I know that I am the best expert out of all of them put together. So I'm sorry for reacting like I do now towards the state of Node.JS today, but what am I supposed to be when the most important thing that I have in life, my work, is said to be made using frameworks by corrupt uneducated liars like Tech Nation who pretend to be an endorsing body in the UK? Please add your signature if words "professional", "quality" and "noble" mean something for you too.

We are unknown, we knowers, ourselves to ourselves: this has its own good reason. We have never searched for ourselves—how should it then come to pass, that we should ever find ourselves? Rightly has it been said: "Where your treasure is, there will your heart be also." Our treasure is there, where stand the hives of our knowledge. It is to those hives that we are always striving; as born creatures of flight, and as the honey-gatherers of the spirit, we care really in our hearts only for one thing—to bring something "home to the hive!" Nietzsche is medicine to soul.

Back To Top

Conclusion

To quickly sum up, it's time to debunk myths that Open Source means free software, that popular packages are good packages, and that JavaScript is deficient because it misses types. Truly free software is the one that cares about you as a developer by honestly attempting to show as little of its presence as possible and letting you do your job rather than dictating how you must work. 4911 linking dependencies, complete negligence to documentation techniques and the culture in which it's maintainers of such software who get to participate in conferences and events to lobby for the future of the language pretty much only because we've been extorted to use this software, does not make Babel free.

You don't even need Babel if you code Node.JS (unless for imports) because since Node 8 you have all the Ecma features that are needed - async, destructuring and arrow functions (with an exception of unicode property regexes), yet for some reasons, there are testing frameworks like Ava that advertise the ability to write code in latest proposals as a feature — who at all needs that? You know I feel like staying on Node 8 forever, it's like ditching a smartphone for a simpler phone. It's like a game, to ditch all too technological things in life: you start by thinking "but I've always needed it" and then you receive your liberation because of realisation that everything in life is artificial apart from soul, face-to-face communication and your human integrity.

me with art deco logo
The only ideology that I do belong to, is Art Deco. It's been quite a lot of work this week on all the material, so please share it using the buttons in the top left corner so that my company does get a chance to live (and earn me some money I can spend on food 😜).

Moreover, it is the fault of Node.JS who for 5 years could not add imports that we were under tyranny of Babel and TypeScript. Standards don't code programs, people code programs, and it's an important take away that we should not create artificial constraints on ourselves that hamper the development process, and if risk is involved, then proper response mechanisms should be put in place instead of rejecting innovation. To quote Seneca: "It is not that we have a short time to live, but that we waste a lot of it" and we must use technology as our instruments to achieving our real goals, instead of worshipping the sacredness of our tools. The world has gone astray and to fill in the gap in our spiritual longing we invent such sophisticated technology that is not really needed, and is there to serve rich capitalists enslaving us more and more by imprinting artificial cultural values where iPhone is your new Jesus and 5G is the Holy Spirit and to become a "unicorn" is to go to heaven. But it doesn't have to be like that. Even if you're not religious, find what makes you human to receive your freedom. For me, this is what Art Deco software is about.

Another "free" software, TypeScript is completely proprietary because you cannot go anywhere without tsserver binary. More and more code that you write in TypeScript, take you further and further away from pure JavaScript. Microsoft does not prioritise fixing bugs that prevent proper functioning of JSDoc, such as that types from level 2+ files are not imported which results in poor experience for developers, their confusion and subsequent switch to TypeScript typings. Moreover, instead of admitting the presence of such bugs in VS Code IDE, Microsoft calls for developers to switch to TypeScript to avoid issues. This is not freedom — it's nothing less than vendor lock-in and abuse of trust that developers put in.

I hope that on the other hand, my transpiler, ÀLaMode can match the criteria of free software because:

  1. It has 0 dependencies, so that it will not waste developer time for linking of itself and future packages.
  2. ÀLaMode: 8 yarn.lock linesBabel: 1650 yarn.lock Lines
    Installing ÀLaMode in 1 sec Linking Babel's Dependencies in 20 sec
  3. It does not change anything in source code apart from import and export statements, which looks exactly like a human would write it if they were writing it using require.
  4. It skips adding any interops that force their own interoperability standard such as __esModule notation.
  5. It solves the problem of easily importing modules, without making a cult out of transpilation and ES6 modules specification.
  6. It preserves JSDoc, allows to debug programs using a source-map generation hack, and avoids constructing ASTs which is computationally much more expensive than using regular expressions. Regarding freedom, using RegExes means that anyone can fork my project and make simple changes (e.g., implement unnamed imports such as import 'technation.sucks') with minimum effort/knowledge, i.e., there's no need to dive deep into compiler theories with its visitor patterns etc.

There are some limitations to ÀLaMode, such as it currently does not transpile import 'example' or dynamic imports, or that it might choke on // inside of template literals. However, it also allows to write JSX and can replace the locations of imports from import t from 'package' to import t from '../stdlib/package' to creation of 0-dependency packages. These features are subjects of next articles.

I hope you enjoyed reading this blog post hope you don't get the wrong impression about me some bits are personal and in the end I doubted if I should even talk of these things since not everyone will understand but oh well it's the work that matters, so see you in next posts. Feel free to share, comment below and don't forget to add your signature! Happy JSDocing.


(scroll down to see the comments)

Have You Signed?

This post is part of a series of articles explaining how I filled the gap in the Node.JS toolchain with entirely new, simple, novel and productive tools for testing, building, documentation and web-development. Most of all, I've always been creating packages for myself to satisfy my strive for quality, however this time I need the help of the community to help me prove in court that work that I submitted for expert evaluation to Tech Nation, was not merely tools "built using frameworks" and that Tech Nation are guilty of libel, breaking of the E-Commerce Directive, and GDPR. Please submit your signature to show that the community is not OK with its name being used against hard-working developers.

Royal Court Of Justice Strand

Your Signature Here:


Sign (opens new page)

Back To Top

Comments

Loading Comments...

Back To Top

© 2019 Art Deco
anton [dog] adc.sh

Vector Designs (Banana Tree Leaves & Fruit, Men) Vecteezy.com