RSS Amplifier

Blog

Massimiliano Mirra

Notebooks

massimilianomirra.comSource feed ↗19 posts

Dormant Last read · last published · next check
Read 5 days ago and current, but nothing has been published for 23 months.

Written by

Latest posts

Expressive components in vanilla React, part 2: IO objects

Approximate reading time: 4-5 minutes. Full example code available as codesandbox and repository . In the first part , we saw how to take a fundamental, but usually implicit aspect of a component — the “phases” it can go through — and make it explicit, both to fellow developers and to developer tools; and how the increase in clarity translates into maintainability and reason-ability. In this part,…

Expressive components in vanilla React, part 1: TypeStates

Approximate reading time: 5 minutes. Full example code available as codesandbox and repository . If you’ve written anything but the most basic component, you know that logic in React can turn opaque real fast: you begin with a few booleans — tracking whether a menu is open, whether a request is loading. You throw in some hooks: data fetching, form validation, accessing URL parameters. Soon you’re…

Faster, simpler tests with explicit IO channels

Something that frustrates even the most honest effort to enact an efficient testing strategy is misunderstanding this: prepare input run computation assert output For this: prepare arguments run function assert return value But arguments aren’t the only way data gets into a function. This is input: const activateUser = async ( userId : string ) => { // ... const blockedUserIds : string [] =…

The process.env frontend time bomb (plus: a sustainable definition of “fixed”)

When I open a file and see process.env used like this, I know I’m in trouble: function Cart () { useEffect ( () => { fetch ( `${ process . env . REACT_APP_API_BASE_URL } /cart ` ) . then ( ( res ) => { // ... Why? Well, suppose I offer you a strategy to make your app work locally, yet break in production, in a way that your users will notice but you won’t, is hard to debug, and is guaranteed to…

Test-driven development of NextJS API routes

NextJS’s conventions are not TDD-friendly, but with some work and a little structure we can enjoy a smooth red-green ride. Let’s say we need a NextJS API route that gives us dictionary definitions. The route handler should validate the request, query a 3rd-party dictionary API, extract desired data from the response, and relay it to the front end. We want a fast feedback loop and low chances of…

How two lines of TypeScript can make a bug go from “undetected in production” to “impossible to introduce”

I recently started hosting AMA-style cafe chats with developers at various stages of their journey, about software engineering and anything else within my technical experience. Below are some notes from the chat on Nov 16th, 2022. Imagine you feed this to your front-end i18n library: const i18enStrings = { " home.title " : " Life, universe, and everything " , " home.subtitle " : " A guide " , } ;…

“I never did any formal design, where can I start?”

I recently started hosting AMA-style cafe chats with developers at various stages of their journey, about software engineering and anything else within my technical experience. Below are some rough & rapid-fire notes from the chat on Oct 21st, 2022. “I never did any formal design, where can I start?” A dead-easy yet high-return strategy : take a core functionality of the system (e.g. “purchasing…

Emacs package quickstart with Eldev

Install Eldev Eldev is make (and then some) for Emacs Lisp development. curl -fsSL https://raw.github.com/doublep/eldev/master/webinstall/eldev | sh The eldev executable will be installed in ~/.local/bin . Create a project directory ~ /projects$ mkdir emacs-simple-calculator ~ /projects$ cd emacs-simple-calculator ~ /projects/emacs-simple-calculator$ git init Create the main project file…

“I’ve got a React codebase, I want to introduce tests, where do I start?”

I recently started hosting AMA-style cafe chats with developers at various stages of their journey, about software engineering and anything else within my technical experience. Below are some rough & rapid-fire notes from the chat on Oct 21st, 2022. Getting started You can test at various levels, from an individual function that knows nothing about browsers to an entire application running in a…

TDD and (vs?) testing

I recently started hosting AMA-style cafe chats with developers at various stages of their journey, about software engineering and anything else within my technical experience. Below are some rough & rapid-fire notes from the chat on Oct 21st, 2022. “Why test?” Tricky question because it puts you in the mindset of writing test code after application code (rarely you’d think IRL of testing…

Four patterns for developer-friendly, production-grade NodeJS services

[Originally written for people onboarding a project I’ve been leading, to explain why services are structured the way they are, and to provide a set of reasoned guidelines.] 1. Decouple service configuration, definition, creation, and startup If your index.ts looks like this: import express from " express " ; const app = express () ; app . get ( " / " , ( req , res ) => { /* ... */ } ) ; app .…

Comment the code that is not there

I recently wrote code similar to this: const App = ( props ) => { return ( < ThemeProvider theme ={ theme }> < PageContent {... props } /> </ ThemeProvider > ) } const PageContent = ({ Component , pageProps }) => { const getLayout = Component . getLayout ?? ( ( page ) => page ) return getLayout ( < Component {... pageProps } /> ) } If it were my first time reading it, I’d think that the…

Mocking window.ethereum in Playwright for end-to-end dApp testing

web3-mock supports Cypress and JSDOM test environments out of the box. However, I prefer Playwright to those as it provides a compelling set of benefits: familiar Jest matchers, a fixture-based runner, and execution in multiple real browser environments. Getting web3-mock to work with Playwright requires setup that is minimal but not obvious, hence this quick note. The test definitions configures…

[draft] Structuring projects to guide and inform (for React applications)

Structure describes and prescribes; it tells about the system while nudging you into thinking of, and using it, in a certain way—hopefully, a way that was chosen deliberately, wisely, and points toward the pit of success . Discussion of React project structures usually centers on the descriptive (“what does folder/file X contain?”) with an intent of easing navigation (“where do I find…

Bi-dimensional commit messages

The “conventional commit” format advocates prefixing commit messages with keywords to give both humans and machines a quick idea of what’s affected: 41e7be2 feat: notify user on new messages f3b33ab build: enable caching to decrease build times 7501fb2 fix(api): detect invalid query parameter f5baa4d docs: typo 06e851a perf(ui): optimize loading time The keyword mostly answers the question: “How…

Faster interactive development in Storybook

(The following is expanded from my comment at #storybook/10987 ) Storybook provides, among other things, a canvas to develop UI components interactively and in isolation. In any kind of digital work, interactivity comes not only from the absence of manual steps between making a change and seeing the outcome, but also from a feedback loop tight enough to keep your mind on the task: a word processor…

Data that grows together, goes together

Stateful systems that get into inconsistent states are a frequent source of bugs. Making conceptually interdependent data also programmatically interdependent is one way of addressing the root of the problem. When a bug breaks production, it’s good to ask: “Why didn’t a test catch that?”. An even better question is “Why did the code build at all?”, but it isn’t asked nearly as often. Why? Perhaps…

Lightweight external command integration in Emacs via compilation mode

For many tasks in a developer’s day, a well-tuned compilation mode is more efficient than reaching for a shell (fewer keystrokes, less context switching) and lighter on the brain than specialized major modes (no new key bindings). Emacs’s “compilation” mode is not limited to running compilers. You can run bundlers for front-end development, test runners for red-green-refactor TDD, project-wide…

The dangers of greedy functions

Functions that ask for more than they need trick the developer into writing unnecessary code. At best, this slows down future development; at worst, it harms runtime qualities: of the present system. Imagine that you inherited this code: const post = await api . fetchPostById ( ' abc123 ' ) // => { // id: 'abc123', // title: 'The dangers of greedy functions', // authorName: 'Max' // } const…