• Writing

    When React parent components need to know their children

    In React, it’s always preferable to maintain a linear data flow. If a parent needs something, lift the state instead of smuggling it back up. All rules are made to be broken, though.

  • Writing

    Module System Dependency Injection in React & Friends

    What does 'use the module system for global dependency injection' actually mean, and is it a good substitute for real DI?

  • Note

    Vitest async fixture destructuring

    Vitest’s custom fixture support is great. Originally inspired by Playwright’s fixture setup, it’s now evolved into an auto-typed flexible builder:

    const test = baseTest
      .extend('client', () =>  new UserClient())
      .extend('user', async ({ client }) => client.getUser())
    
    test('Does the thing', async ({ user }) => {
      // No need to await user, it's already resolved.
    })TypeScript

    I’ve long wondered how they manage to lazily initialise fixtures based on object destructuring — even with a Proxy or similar it’s not possible to hide the async part. Today I finally took a look, and it’s actually pretty cursed:

    // https://github.com/vitest-dev/vitest/blob/v4.1/packages/runner/src/fixture.ts#L646
    let fnString = filterOutComments(implementation.toString())TypeScript

    The trick is to stringify the function and extract with regex the names of the fixtures requested. Vitest can then build up the fixture dependency tree and resolve these before passing them to your test fixture.

    It’s also why this doesn’t work:

    test('Does the thing', async (ctx) => {
      // No proxy magic or anything wild, so this won't work -
      // only the function arguments are parsed.
      const { user } = ctx
    })TypeScript

    Turns out Playwright does the extact same thing.

  • Writing

    Progressive enhancement options for traditional server-rendered sites

    What's the best way to progressively enhance a traditional server-rendered application with client-side JavaScript in 2023? Despite their glacial adoption, web components remain the closest we have to a platform-native solution.

  • Writing

    Stubbing GraphQL using Playwright

    A more ergonomic solution to stubbing out multiple GraphQL responses using Playwright.

  • Writing

    Locking body scroll for modals on iOS

    Revisiting old solutions for preventing background scrolling from within modal dialogs & overlays.

  • Writing

    Leveraging extends to infer return types

    In many statically typed languages, once we accept a generalised interface as a parameter we lose the ability to retrieve concrete values from our return type. Not so in TypeScript.

  • Writing

    Defining 'integration' tests

    What is an integration test? Everyone uses the term, but few seem to agree on the definition. Does the awkward filling of the testing pyramid still have value today, or is it too murky to be of real value?

  • Writing

    An Opinionated Guide to Unit Testing

    A language-agnostic guide on how to write maintainable, loosely-coupled unit tests which provide confidence and reduce fragility.

  • Writing

    Frontend Predictions for 2022

    Thoughts on what we might see in the coming year, including the return of micro-frontends, functional JavaScript & the demise of the Jamstack as we know it.

  • Writing

    Wrapping text inside an SVG using CSS

    Using two SVGs and shape-outside to wrap text inside a shape.

  • Writing

    Stubbing GraphQL using Cypress

    A more ergonomic solution to stubbing out multiple GraphQL responses using Cypress.

  • Writing

    Avoiding FOUT with Async CSS

    Fighting blocking resources and the fabled flash-of-unstyled-text with Adobe Fonts.

  • Writing

    The jest.mock() escape hatch

    Mocking concrete dependencies is a code-smell.