Journal
Blue Note Records: Beyond the Notes (on BBC Four)
The story behind Blue Note Records, founded in New York in 1939 by two German Jewish refugees who allowed their musicians complete artistic freedom, revolutionising jazz in the process.
A great watch with a fantastic back story, great interviews and amazing music including this from Art Blakey:
You don’t need a media query for that: #1 Inline content separators
Create a more flexible component which allows the text to wrap based on the content rather than the viewport size.
Here, Mandy Michael explores similar territory to Every Layout in suggesting that not all responsive pattern challenges require, or indeed are best served by, media queries.
The example here is a pipe-separated text pair (I could imagine an author and publish date meta line) which Mandy wants to wrap (with pipe separator hidden) only when the content and container require it, rather than based on the less-relevant viewport width.
She uses a clever combination of flex-wrap:wrap, generated content, padding, transform and overflow-y:hidden to achieve her goal.
(Via @Mandy_Kerr)
“Long Shot” DJ mix by The Nuclear Family
A mix of electronic, house and techno records I recorded at home in November 2019.
2019 has been a fairly quiet year for my and Tom’s record label The Nuclear Family. However with a couple of winter events coming up I wanted to share a little teaser mix to whet the collective appetite.
Inspiration
Earlier in the year I joined a fine bunch of pals on a night out at 69 at The Club, Paisley to hear resident DJs Martin and Euan plus a live performance from guest John Heckle. It was a fantastic night and particularly memorable for a couple of stellar tracks played by Euan. I tried to describe them to him afterwards but wasn’t sure if I was making much sense. Cut to a few months later and a mysterious parcel containing records I’ve never heard of arrives at my door. I was convinced that someone must have sent them to me in error until dropping the needle on the grooves and realising they were the tracks from that night at 69! Channeling Sherlock Holmes, I deduced that Euan – being the all-round good guy that he is – had bought and posted them to me as a souvenir of the night. What a guy!
And they are brilliant.
The first is Ricochet by Bambooman (a new name on me) on Matthew Herbert’s label, Accidental Jnr. It features a stuttering, percussive riff complimented by searing synth stabs – proper machine funk but with a heart. The second is a double-pack by the more familiar name of i:cube, with my favourite track Fractal P a dark, winding, bass-heavy trip reminiscent of ’91 classic Pressure Dub by Ability 11 but with its own distinct flavour.
I knew I definitely wanted those tracks in the mix.
Around those touchstones I added recent favourites from Joy O (under his Sin Falta alias), Phillip McGarva (the artist formerly known as Microworld) and Dego, plus a few oldies including Isolée’s Hermelin and Modern Tribe by Jellybean (AKA Glenn Underground).
In terms of kit, I recorded the mix on a pair of Technics 1210s and an Isonoe 420 mixer.
WAVE Web Accessibility Evaluation Tool
The featured article in this week’s Accessibility Weekly newsletter was on recent improvements to the WAVE suite of accessibility testing tools.
I can’t remember using WAVE before, however just one quick test of fuzzylogic.me using their online tool revealed an accessibility issue with the linked SVG logo in the header. A great catch, now fixed, from which I learned something new. I’ll certainly be adding WAVE to my accessibility testing toolbox from here on in.
WAVE is a suite of evaluation tools that help authors make their web content more accessible to individuals with disabilities. WAVE can identify many accessibility and Web Content Accessibility Guideline (WCAG) errors, but also facilitates human evaluation of web content. Our philosophy is to focus on issues that we know impact end users, facilitate human evaluation, and to educate about web accessibility.
Why much of the internet is closed off to blind people – BBC News
Following the recent watershed Domino’s Pizza case, BBC News reports that retailers in the USA & Canada are struggling to make their websites accessible and consumers are taking them to court.
"We've even been told by businesses before that they understand, but the fact is blind people are not a very big market," Mr Danielson says. "That's what we are dealing with."
Colors – a nicer color palette for the web
Skinning your prototypes just got easier - colors.css is a collection of skin classes to use while prototyping in the browser.
They also provide ninety examples of “A11Y compliant color combos” which is really handy.
“Gil Scott-Heron Saved Me”
From The Guardian in 2011, shortly after Gil Scott-Heron’s sad death, here’s a beautiful and moving account of how the musical legend offered hope and mentorship to a young man from Liverpool and in so doing turned his life around.
Thanks to Nick Peacock for sharing.
“Your interview test for junior developer” (from Bruce Lawson on Twitter)
"Ok, as part of your interview test for junior developer, we want you to put some words, an image and some links onto a webpage. We use Node, Docker, Kubernetes, React, Redux, Puppeteer, Babel, Bootstrap, Webpack,
<div>and<span>. Go!"
Bruce Lawson nicely illustrates how ridiculous many job adverts for web developers are. This (see video) never fails to crack me up. It’s funny ‘cos it’s true!
(via @brucel)
Progressively Enhanced JavaScript with Stimulus
I’m dipping my toes into Stimulus, the JavaScript micro-framework from Basecamp. Here are my initial thoughts.
I immediately like the ethos of Stimulus.
The creators’ take is that in many cases, using one of the popular contemporary JavaScript frameworks is overkill.
We don’t always need a nuclear solution that:
- takes over our whole front end;
- renders entire, otherwise empty pages from JSON data;
- manages state in JavaScript objects or Redux; or
- requires a proprietary templating language.
Instead, Simulus suggests a more “modest” solution – using an existing server-rendered HTML document as its basis (either from the initial HTTP response or from an AJAX call), and then progressively enhancing.
It advocates readable markup – being able to read a fragment of HTML which includes sprinkles of Stimulus and easily understand what’s going on.
And interestingly, Stimulus proposes storing state in the HTML/DOM.
How it works
Stimulus’ technical purpose is to automatically connect DOM elements to JavaScript objects which are implemented via ES6 classes. The connection is made by data– attributes (rather than id or class attributes).
data-controller values connect and disconnect Stimulus controllers.
The key elements are:
- Controllers
- Actions (essentially event handlers) which trigger controller methods
- Targets (elements which we want to read or write to, mapped to controller properties)
Some nice touches
I like the way you can use the connect() method – a lifecycle callback invoked whenever a given controller is connected to the DOM - as a place to test browser support for a given feature before applying a JS-based enhancement.
Stimulus also readily supports the ability to have multiple instances of a controller on the page.
Furthermore, actions and targets can be added to any type of element without the controller JavaScript needing to know or care about the specific element, promoting loose coupling between HTML and JavaScript.
Managing State in Stimulus
Initial state can be read in from our DOM element via a data- attribute, e.g. data-slideshow-index.
Then in our controller object we have access to a this.data API with has(), get(), and set() methods. We can use those methods to set new values back into our DOM attribute, so that state lives entirely in the DOM without the need for a JavaScript state object.
Possible Limitations
Stimulus feels a little restrictive if dealing with less simple elements – say, for example, a data table with lots of rows and columns, each differing in multiple ways.
And if, like in our data table example, that element has lots of child elements, it feels like there might be more of a performance hit to update each one individually rather than replace the contents with new innerHTML in one fell swoop.
Summing Up
I love Stimulus’s modest and progressive enhancement friendly approach. I can see me adopting it as a means of writing modern, modular JavaScript which fits well in a webpack context in situations where the interactive elements are relatively simple and not composed of complex, multidimensional data.
How to manage JavaScript dependencies
Managing JavaScript dependencies is about as much fun as a poke in the eye. However even if—like me—you prefer to keep things lean and dependency-free as far as possible, it’s something you’re going to need to do either in large work projects or as your personal side-project grows. In this post I tackle it head-on to reduce the problem to some simple concepts and practical techniques.
In modern JavaScript applications, we can add tried-and-tested open source libraries and utilities by installing packages from the NPM registry. This can aid development by letting you concentrate on your application’s unique features rather than reinventing the wheel for already-solved common tasks.
A typical example might be to add axios or node-fetch to a Node.js project to provide a means of making API calls.
We can use a package manager such as yarn or npm to install packages. When our package manager installs a package it logs it as a project dependency which is to say that the project depends upon its presence to function properly.
It then follows that anyone who wants to run the application should first install its dependencies.
And it’s the responsibility of the project owner (you and your team) to manage the project’s dependencies over time. This involves:
- updating packages when they release security patches;
- maintaining compatibility by staying on package upgrade paths; and
- removing installed packages when they are no longer necessary for your project.
While it’s important to keep your dependencies updated, in a recent survey by Sonatype 52% of developers said they find dependency management painful. And I have to agree that it’s not something I generally relish. However over the years I’ve gotten used to the process and found some things that work for me.
A simplified process
The whole process might go something like this (NB install yarn if you haven’t already).
# Start installing and managing 3rd-party packages.
# (only required if your project doesn’t already have a package.json)
yarn init # or npm init
# Install dependencies (in a project which already has a package.json)
yarn # or npm i
# Add a 3rd-party library to your project
yarn add package_name # or npm i package_name
# Add package as a devDependency.
# For tools only required in the local dev environment
# e.g. CLIs, hot reload.
yarn add -D package_name # or npm i package_name --save-dev
# Add package but specify a particular version or semver range
# https://devhints.io/semver
# It’s often wise to do this to ensure predictable results.
# caret (^) is useful: allows upgrade to minor but not major versions.
# is >=1.2.3 <2.0.0
yarn add package_name@^1.2.3
# Remove a package
# use this rather than manually deleting from package.json.
# Updates yarn.lock, package.json and removes from node_modules.
yarn remove package_name # or npm r package_name
# Update one package (optionally to a specific version/range)
yarn upgrade package_name
yarn upgrade package_name@^1.3.2
# Review (in a nice UI) all packages with pending updates,
# with the option to upgrade whichever you choose
yarn upgrade-interactive
# Upgrade to latest versions rather than
# semver ranges you’ve defined in package.json.
yarn upgrade-interactive -—latest
Responding to a security vulnerability in a dependency
If you host your source code on GitHub it’s a great idea to enable Dependabot. Essentially Dependabot has your back with regard to any dependencies that need updated. You set it to send you automated security updates by email so that you know straight away if a vulnerability has been detected in one of your project dependencies and requires action.
Helpfully, if you have multiple Github repos and more than one of those include the vulnerable package you also get a round-up email with a message something like “A new security advisory on lodash affects 8 of your repositories” with links to the alert for each repo, letting you manage them all at once.
Dependabot also works for a variety of languages and techologies—not just JavaScript—so for example in a Rails project it might email you to suggest bumping a package in your Gemfile.
Automated upgrades
Sometimes the task is straightforward. The Dependabot alert email tells you about a vulnerability in a package you explicitly installed and the diligent maintainer has already made a patch release available.
A simple upgrade to the relevant patch version would do the job, however Dependabot can even take care of that for you! Dependabot can automatically open a new Pull Request which addresses the vulnerability by updating the relevant dependency. It’ll give the PR a title like
Bump
lodashfrom4.17.11to4.17.19
You just need to approve and merge that PR. This is great; it’s really simple and takes care of lots of cases.
Note 1: if you work on a corporate repo that is not set up to “automatically open PRs”, often you can still take advantage of Github’s intelligence with just one or two extra manual steps. Just follow the links in your Github security alert email.
Note 2: Dependabot can also be set to do automatic version updates even when your installed version does not have a vulnerability. You can enable this by adding a dependabot.yml to your repo. But so far I’ve tended to avoid unpredictability and excess noise by having it manage security updates only.
Manual upgrades
Sometimes Dependabot will alert you to an issue but is unable to fix it for you. Bummer.
This might be because the package owner has not yet addressed the security issue. If your need to fix the situtation is not super-urgent, you could raise an issue on the package’s Github repo asking the maintainer (nicely) if they’d be willing to address it… or even submit a PR applying the fix for them. If you don’t have the luxury of time, you’ll want to quickly find another package which can do the same job. An example here might be that you look for a new CSS minifier package because your current one has a longstanding security issue. Having identified a replacement you’d then remove package A, add package B, then update your code which previously used package A to make it work with package B. Hopefully only minimal changes will be required.
Alternatively the package may have a newer version or versions available but Depandabot can’t suggest a fix because:
- the closest new version’s version number is beyond the allowed range you specified in
package.jsonfor the package; or - Dependabot can’t be sure that upgrading wouldn’t break your application.
If the package maintainer has released newer versions then you need to decide which to upgrade to. Your first priority is to address the vulnerability, so often you’ll want to minimise upgrade risk by identifying the closest non-vulnerable version. You might then run yarn upgrade <package…>@1.3.2. Note also that you may not need to specify a specific version because your package.json might already specify a semver range which includes your target version, and all that’s required is for you to run yarn upgrade or yarn upgrade <package> so that the specific “locked” version (as specified in yarn.lock) gets updated.
On other occasions you’ll read your security advisory email and the affected package will sound completely unfamiliar… likely because it’s not one you explicitly installed but rather a sub-dependency. Y’see, your dependencies have their own package.json and dependencies, too. It seems almost unfair to have to worry about these too, however sometimes you do. The vulnerability might even appear several times as a sub-dependency in your lock file’s dependency tree. You need to check that lock file (it contains much more detail than package.json), work out which of your top-level dependencies are dependent on the sub-dependency, then go check your options.
Update: use yarn why sockjs (replacing sockjs as appropriate) to find out why a module you don’t recognise is installed. It’ll let you know what module depends upon it, to help save some time.
When having to work out the required update to address a security vulnerability in a package that is a subdependency, I like to quickly get to a place where the task is framed in plain English, for example:
To address a vulnerability in
xmlhttprequest-sslwe need to upgradekarmato the closest available version above4.4.1where its dependency onxmlhttprequest-sslis>=1.6.2
Case Study 1
I was recently alerted to a “high severity” vulnerability in package xmlhttprequest-ssl.
Dependabot cannot update
xmlhttprequest-sslto a non-vulnerable version. The latest possible version that can be installed is1.5.5because of the following conflicting dependency:@11ty/eleventy@0.12.1requiresxmlhttprequest-ssl@~1.5.4via a transitive dependency onengine.io-client@3.5.1. The earliest fixed version is1.6.2.
So, breaking that down:
xmlhttprequest-sslversions less than1.6.2have a security vulnerability;- that’s a problem because my project currently uses version
1.5.5(via semver range~1.5.4), which I was able to see from checkingpackage-lock.json; - I didn’t explicitly install
xmlhttprequest-ssl. It’s at the end of a chain of dependencies which began at thedependenciesof the package@11ty/eleventy, which I did explicitly install; - To fix things I want to be able to install a version of Eleventy which has updated its own dependencies such there’s no longer a subdependency on the vulnerable version of
xmlhttprequest-ssl; - but according to the Dependabot message that’s not possible because even the latest version of Eleventy (0.12.1) is indirectly dependent on a vulnerable version-range of
xmlhttprequest-ssl(~1.5.4); - based on this knowledge, Dependabot cannot recommend simply upgrading Eleventy as a quick fix.
So I could:
- decide it’s safe enough to wait some time for Eleventy to resolve it; or
- request Eleventy apply a fix (or submit a PR with the fix myself); or
- stop using Eleventy.
Case Study 2
A while ago I received the following security notification about a vulnerability affecting a side-project repo.
dot-prop < 4.2.1 “Prototype pollution vulnerability in dot-prop npm package before versions 4.2.1 and 5.1.1 allows an attacker to add arbitrary properties to JavaScript language constructs such as objects.
I wasn’t familar with dot-prop but saw that it’s a library that lets you “Get, set, or delete a property from a nested object using a dot path”. This is not something I explicitly installed but rather a sub-dependency—a lower-level library that my top-level packages (or their dependencies) use.
Github was telling me that it couldn’t automatically raise a fix PR, so I had to fix it manually. Here’s what I did.
- looked in
package.jsonand found no sign ofdot-prop; - started thinking that it must be a sub-dependency of one or more of the packages I had installed, namely
express,hbs,requestornodemon; - looked in
package-lock.jsonand via a Cmd-F search fordot-propI found that it appeared twice; - the first occurrence was as a top-level element of
package-lock.jsons top-leveldependenciesobject. This object lists all of the project’s dependencies and sub-dependencies in alphabetical order, providing for each the details of the specific version that is actually installed and “locked”; - I noted that the installed version of
dot-propwas4.2.0, which made sense in the context of the Github security message; - the other occurrence of
dot-propwas buried deeper within the dependency tree as a dependency ofconfigstore; - I was able to work backwards and see that
dot-propis required byconfigstorethen Cmd-F search forconfigstoreto find that it was required byupdate-notifier, which is turn is required bynodemon; - I had worked my way up to a top-level dependency
nodemon(installed version1.19.2) and worked out that I would need to updatenodemonto a version that had resolved thedot-propvulnerability (if such a version existed); - I then googled “nodemon dot-prop” and found some fairly animated Github issue threads between Remy the maintainer of
nodemonand some users of the package, culminating in a fix; - I checked nodemon’s releases and ascertained that my only option if sticking with
nodemonwas to installv2.0.3—a new major version. I wouldn’t ideally install a version which might include breaking changes but in this casenodemonwas just adevDependency, not something which should affect other parts of the application, and a developer convenience at that so I went for it safe in the knowledge that I could happily remove this package if necessary; - I opened
package.jsonand withindevDependenciesmanually updatednodemonfrom^1.19.4to^2.0.4. (If I was in ayarncontext I’d probably have done this at the command line). I then rannpm i nodemonto reinstall the package based on its new version range which would also update the lock file. I was then prompted to runnpm audit fixwhich I did, and then I was done; - I pushed the change, checked my Github repo’s security section and noted that the alert (and a few others besides) had disappeared. Job’s a goodun!
Proactively checking for security vulnerabilities
It’s a good idea on any important project to not rely on automated alerts and proactively address vulnerabilities.
Check for vulnerabilities like so:
yarn audit
# for a specific level only
yarn audit --level critical
yarn audit --level high
Files and directories
When managing dependencies, you can expect to see the following files and directories.
package.jsonyarn.locknode_modules(this is the directory into which packages are installed)
Lock files
As well as package.json, you’re likely to also have yarn.lock (or package.lock or package-lock.json) under source control too. As described above, while package.json can be less specific about a package’s version and suggest a semver range, the lock file will lock down the specific version to be installed by the package manager when someone runs yarn or npm install.
You shouldn’t manually change a lock file.
Choosing between dependencies and devDependencies
Whether you save an included package under dependencies (the default) or devDependencies comes down to how the package will be used and the type of website you’re working on.
The important practical consideration here is whether the package is necessary in the production environment. By production environment I don’t just mean the customer-facing website/application but also the enviroment that builds the application for production.
In a production “build process” environment (i.e. one which likely has the environment variable NODE_ENV set to production) the devDependencies are not installed. devDependencies are packages considered necessary for development only and therefore to keep production build time fast and output lean, they are ignored.
As an example, my personal site is JAMstack-based using the static site generator (SSG) Eleventy and is hosted on Netlify. On Netlify I added a NODE_ENV environment variable and set it to production (to override Netlify’s default setting of development) because I want to take advantage of faster build times where appropriate. To allow Netlify to build the site on each push I have Eleventy under dependencies so that it will be installed and is available to generate my static site.
By contrast, tools such as Netlify’s CLI and linters go under devDependencies. Netlify’s build prorcess does not require them, nor does any client-side JavaScript.
Upgrading best practices
- Check the package CHANGELOG or releases on Github to see what has changed between versions and if there have been any breaking changes (especially when upgrading to the latest version).
- Use a dedicated PR (Pull Request) for upgrading packages. Keep the tasks separate from new features and bug fixes.
- Upgrade to the latest minor version (using
yarn upgrade-interactive) and merge that before upgrading to major versions (usingyarn upgrade-interactive -—latest). - Test your work on a staging server (or Netlify preview build) before deploying to production.