Sunday, February 2, 2025

snip snip

6 CSS Snippets Every Front-End Developer Should Know In 2025. All good stuff, but sometimes I can't shake the feeling that animations and transitions were easier in JQuery - admittedly CSS is much more declertive but things like transitions can seem a lot more intuitive to write as a verb of script - stuff that happens - rather than a noun of styling, stuff that is.

Thursday, January 30, 2025

npm note

 At my new job we use veracode to scan for vulnerabilities, including npm packages that are children of packages we use.

those seem a little tricky... I think the options are:
1. tell veracode to ignore it IF its dev dependency/internal tool only
2. upgrade the parent package(s) and hope it pulls a more recent version
3. use { "overrides" : "foo":"1.0.0" } (new since 2021 NPM v8.3.0)

everything is a little fraught but that last one seems the most promising to me.

(via Stack Overflow What is the role of the package-lock.json? )

Tuesday, January 21, 2025

surveying eslint-disables across a code base

An architect was mentioning some counts of eslint-disables in our code base, and I wanted to take a closer look.

(I know different devs have different intuitions about the criticality of some of these rules: I know for me, if there's a trade off between "concise, more readable code that keeps attention to what's actually new" vs "well-enforced lint standards and rigorously enforced strong typing at every level that MIGHT help turn a runtime error into a buildtime problem", I lean towards the former.)

I started by recursive grepping for those lines, and putting them into a .txt file so future steps would be faster:

grep -r "eslint-disable" | grep -v node_modules/   >  ~/raw.txt

I then used CoPilot to come up with a node.js script to break up the lines and do counts by subproject in the monorepo:)

const fs = require('fs');
const readline = require('readline');

// Create a read stream for raw.txt
const fileStream = fs.createReadStream('raw.txt');

// Create an interface to read the file line by line
const rl = readline.createInterface({
  input: fileStream,
  crlfDelay: Infinity
});

// Initialize the counts and totalCounts objects
const counts = {};
const totalCounts = {};

// Process each line
rl.on('line', (line) => {
  // Split the line on whitespace
  const sections = line.split(/\s+/);

  const regex = /\.\/([^\/]+\/[^\/]+)\//;
  const match = sections[0].match(regex);

  if (!match) {
    console.log(`NO MATCH FOR ${line}\n`);
    return;
  }

  const appOrLib = match[1];

  const offset = sections.findIndex(section => section.startsWith('eslint-disable'));

  if (offset === -1) {
    console.log(`NO MATCH FOR ${line}\n`);
  } else {
    // Join the remaining parts on " ", ignoring "*/"
    const remainingParts = sections.slice(offset + 1).filter(part => part !== '*/');
    const joinedParts = remainingParts.join(' ');

    // Split each remaining part on "," and treat them separately
    const finalParts = joinedParts.split(',').map(part => part.trim());

    // Initialize the appOrLib object if it doesn't exist
    if (!counts[appOrLib]) {
      counts[appOrLib] = {};
      totalCounts[appOrLib] = 0;
    }

    finalParts.forEach(part => {
      const key = part || '[EMPTY]';
      if (!counts[appOrLib][key]) {
        counts[appOrLib][key] = 0;
      }
      counts[appOrLib][key]++;
      totalCounts[appOrLib]++;
    });
  }
});

// Print the counts object when done
rl.on('close', () => {
  for (const appOrLib in counts) {
    console.log(`${appOrLib}: ${totalCounts[appOrLib]}`);
    const sortedKeys = Object.keys(counts[appOrLib]).sort((a, b) => counts[appOrLib][b] - counts[appOrLib][a]);
    sortedKeys.forEach(key => {
      console.log(`\t${key}: ${counts[appOrLib][key]}`);
    });
  }
});

Thursday, January 2, 2025

thumbs way up

When you enjoy thinking about UI/UX, it's fun and instructive to see evolutions in products you use every day, and think about what their designers were trying to accomplish, and what you might think they could do better.

So in FB Messenger, they recently changed the "send message" button - I believe that previously it was inactive until you typed some message content. Now it's a "thumbs up" button when the message body is empty, which sends a big thumbs up (btw, isn't that a rude gesture in some cultures? I was just googling to see if FB uses anything different elsewhere...)

So I noticed this on accident, when I see I had sent a big thumbs up between 2 of my own messages... (I quote "The Tao of Programming": "A program should follow the 'Law of Least Astonishment'. What is this law? It is simply that the program should always respond to the user in the way that astonishes him least.")

So, on the one hand, I could see that an easy general "OK" response is potentially useful, and a little easier to get to here than the usual "reaction" picker for previous messages. On the other hand... it seems weird to just make that the default message - especially to ones own messages. When you accidentally send one against your own message, it seems weirdly insecure or self-aggrandizing.

I wonder if they considered changing the "just send a thumbs up" function to activate only after the other person has written something back? That seems like a more useful scenario. But I guess would make the UI even more chaotic and unpredictable.