Bun is released – let’s jump the hype (NO)!

Bun 1.0 was released. And again, the JS ecosystem did what they do best – fell up into hype.

I actually have no idea why this happens so much in JS world; maybe it’s a lack of maturity (I mean, Ruby also did the same in the past, then they figured out it’s not always a good idea to throw away everything when a new stuff appears), maybe it’s something else; maybe people are just desperate to have something better in the JS world – who knows?

Anyway, I decided to do some benchmark tests. I was already not impressed, because I did test Bun in the past, but let’s see what happens with this new version:
(more…)

CommonJS is not a problem – the Javascript ecosystem is

Recently I came across this post saying that CommonJS is hurting the JavaScript world. And while I do agree that the CommonJS specification was not a good one, I also disagree a lot with the article. As someone who have strong opinions about the subject, I decided to write a post about it.

So, here’s the problem: supposing that you have a legacy system that’s years old, and that basically is modular, meaning that people write extensions, or libraries, to that. Like for example, NodeJS’ CommonJS. Now, here’s the problem: if that legacy system is flawed, and you need to change somehow, and your solution is “let’s do something that is better in any way than the older model, it’s faster, etc, but also completely incompatible with the old stuff” – meaning that we have to rewrite everything to be able to be used on this new format – then you’re doing it wrong.
(more…)

The state of JS in 2021

So… I recently found out that I had no space left on my SSD. When I tried to debug what was consuming my space, my projects folder were the culprit. How? I mean, I take photos, store them in RAW format, so how source code can be consuming more than my photos?

Turns out that by running rm -Rf (find -name 'node_modules'), (FISH shell) I was able to free 20gb of space!

So… let’s see how bizarre is the Javascript ecosystem in 2021.

Strangely big libraries

Sometimes, when I have to generate projects, they ask me to install yo. Yo is just a CLI to run generators – it does not include any generator. Yo occupies 89mb of space in my disk. Installing the react-webpack (manually by running npm i generator-react-webpack, because otherwise yo will try to install globally) means that your node_modules now occupies 180mb.

Let’s thing a little bit about this number: Windows XP, minimalist install without any add-on, requires 1.5gb of space. So a SINGLE GENERATOR occupies 12% of a full operating system.

So, create-react-app is more gentle – it just installs under 5.3mb. Generating a react app creates a node_modules folder with… 242mb. One of the dependencies is global-modules, that is just a single file with an if to define how to call things. It’s also only used in a single file – react-dev-utils/printHostingInstructions.js – in the folllowing code:
(more…)

There’s a little Haskell in your Javascript

This may seem a little strange, but althrough Javascript is a dynamic language, with very loose typing (automatic convertions, equals signs that only works on arrays/numbers/undefined/nil), lots of things that are “falsy” by default, with the new promise-based approach of Javascript, the language is borrowing some very interesting concepts from Haskell.

And yes, this is a great thing. And yes, this will probably change the way we program.

Let’s begin by talking about Javascript, and its new features. Old async-javascript code was probably like this:

some_io_function(function(result) {
  find_name_in_db(result.person_id, function(name) {
    console.log(name);
  })
});

Now, it’s like this:

some_io_function()
  .then((result) => find_name_in_db(result.person_id))
  .then(console.log)

And, with new ES6 features:

async () => {
  var result = await some_io_function();
  var name = await find_name_in_db(result.person_id);
  console.log(name)
}

Now, what does this have to do with Haskell? Multiple things, but the most important: Functors!
(more…)

Resourceful Web

Todos sabem que, com o tempo, os frameworks web evoluem. Porém, o que poucas pessoas percebem é que além das mudanças nas APIs e na estrutura dos programas feitos com o framework, há uma mudança também nas idéias dos desenvolvedores e até mesmo nas metáforas que o sistema usou para definir-se. E o Rails não é exceção.

Por exemplo, no Ruby on Rails versão 1.x, a idéia do framework era a construção de aplicações web. Para tal, a idéia era que a aplicação fosse simples e divertida de desenvolver. Além disso, havia a idéia de web-services, XML-RPC e SOAP que nunca pegaram direito no mundo Rails (mas que estavam presentes na versão 1.x). Depois, na versão 2.x, surgiu o conceito de RESTful (em contraponto aos web-services do Rails 1) e, junto com ele, o conceito de “resource” ou “recurso”. Já no Rails 3, surgiu a idéia de separar o Javascript do HTML usando o conceito de Unobtrusive Javascript (Javascript não-intrusivo), e junto com essa idéia, veio a substituição do prototype pelo jQuery (que torna certas operações envolvendo AJAX mais fáceis). Junto também com a substituição por jQuery, o scaffold passou a fazer os controllers responderem por HTML e JSON, ao invés de HTML e XML como no rails 2.x.

E é essa a mudança mais importante.

Vamos começar pensando: qual seria o motivo de renderizar um JSON? A resposta é simples: JSON é mais fácil de ser entendido pelo browser, por Javascript, e por aplicativos de terceiros tais como em iOS ou Android. Antes, responder por XML não tinha aplicação real nenhuma nos próprios aplicativos Rails, e ficavam apenas como forma de comunicação com sistemas de terceiros (o velho “big design up front“) que nem sempre ocorriam. E hoje, renderizar JSON está muito pouco utilizado mesmo no mundo Rails, e há um motivo para isso:

Não sabemos o que é um “resource”.
(more…)

Unobtrusive Javascript

Um monte de gente tem falado sobre Unobtrusive Javascript (ou UJS, para simplificar), mas há poucos que mencionam COMO fazer. Da mesma forma, o próprio Rails parece não ser muito decidido às melhores práticas (o que, sinceramente, é uma pena dada a idéia original do Rails de facilitar o desenvolvimento web). Aliás, talvez algumas mudanças do Rails valeriam para outro post, mas por hora, vamos para UJS.

A idéia do UJS, basicamente, é não misturar Javascript com HTML nas views. O que, sinceramente, é uma ótima idéia ao meu ver. O problema é como fazer isso de forma não-traumática. Para este exemplo, vamos ver inicialmente qual era a abordagem que eu usei, no passado, sobre UJS:

Antes, eu usava algum helper do Rails e criava as tags tipo <a href="algumaUrl" data-remote="true>, e no controller eu pedia para renderizar um template .js.erb. Isso trazia diversos problemas, por exemplo:

$('div').html(&quot;&lt;%= @user.name %&gt;&quot;);

Mas se o usuário tiver espaços no nome, precisaremos de "escape_javascript"… e aí começam alguns antipatterns (imagine HTML+ERB, mas dessa vez com todos os problemas de Javascript incorporados).

O ideal, e algo que tanto o Twitter como outros serviços web estão fazendo, é manter uma API web que renderiza os dados, e seu ambiente web nada mais é do que uma interface que consome esses dados (e renderiza algo na tela). Para esse exemplo, só vou usar jQuery e nada de Rails/Ruby/Whatever…
(more…)

Testando Javascript no Rails

Continuando os estudos com Javascript e Ruby, esses dias tive um problema bem chato: existe uma gem (muito boa, por sinal) para Rails chamada “cells“, que basicamente cria uma camada, semelhante a “mini controllers” para coisas específicas em Rails (tipo “sidebar”, “carrinhos de compra”, “menus” e outras funcionalidades que são, basicamente, fragmentos de “views”, normalmente feitas com a combinação “partials+helpers” mas que ficam relativamente difíceis de testar). Junto com o Cells, foi criado o Apotomo, uma gem para criar “widgets”, e aí que está o problema: testar um widget. Claro, é possível testá-lo com integration test, mas “unit-tests”, quando envolvem Javascript+Rails, envolvem HTML Fixtures, linguagens de teste diferentes, enfim, nada produtivo.

Aí, entrou a gem Johnson. Basicamente, é um interpretador Javascript dentro de Ruby, de forma que seja possível rodar código JS dentro do Ruby (e o resultado vem como uma Ruby String, ou um Numeric, enfim). Já falei sobre isso quando estudei “The Ruby Racer” e os testes com V8 no Ruby, até me interessei pelo “env.js”, porém na época a versão que rodava com Johson estava muito ruim ainda (e infelizmente, ainda está)

Porém, o novo Env.JS (1.3) já roda no Johnson. E está muito melhor.
(more…)

Closures, Functions e Programação Funcional em Javascript

Estes dias, tive que fazer um código que achei que seria muito complicado, e que deveria rodar num browser. A idéia é que, dependendo do que foi digitado em uma determinada caixa de texto, um pedaço de uma página deveria mudar. Até aí, tudo bem, o problema é que o pedaço que deveria mudar deveria agrupar informações de outras caixas de texto, e outras regras confusas. Achei uma solução muito simples e prática, e gostaria de dividí-la. Mas antes, vamos simplificar o escopo:

Imagine que há uma página, no qual há um botão “adicionar”. Ao clicar nele, ele adiciona um “select” (sexo) e uma caixa de texto com observações ou qualquer outra coisa. Podem ser adicionados tantos elementos como se achar necessário. Para cada elemento alterado, deve ser exibido um sumário na tela de baixo (observações), digamos, concatenando o sexo e as observações. A parte difícil é: quando qualquer elemento for mudado, APENAS o sumário relativo àquele conjunto de elementos (sexo e observação) deve ser alterado, e também, quando eu estiver editando as observações (ou o sexo), o sumário deve ficar em negrito. Para simplificar (e rodar em vários browser) usarei a biblioteca Javascript chamada Prototype (não usarei o JQuery porque seria jogar uma bomba numa mosca), e a idéia é escrever apenas o código relativo às edições (porque é isso que pega). Portanto, para quem quiser, basta pegar o gist do Github http://gist.github.com/658668 para ter um esqueleto do programa (basta abrir o .html em qualquer browser).
(more…)

Monkey-Patch seguro, em Javascript

Continuando os estudos com Javascript, diversas coisas interessantes, que pareciam acessíveis apenas aos programadores de Ruby, Perl e outras linguagens mais flexíveis podem ser feitas também na linguagem. O problema é que, normalmente, é difícil de usar isso em bibliotecas que já existem, principalmente porque a maioria dos códigos em Javascript ou não seguem boas-práticas ou simplesmente são escritos de forma diferente do que vou apresentar aqui, porém vale pela dica. Um exemplo bem simples, pensando na seguinte API:

objeto = {
  valor: 10,
  incrementar: function(v) { 
    if(!v) v = 1;
    valor += v;
  },
  raizQuadrada: function() {
    Math.sqrt(incrementar(4));
  }
}

Para implementá-la, em Javascript, há várias formas. Simulando o comportamento que eu fiz no post passado, é possível usar o seguinte formato:
(more…)