alphagov / govuk-prototype-kit

Rapidly create HTML prototypes of GOV.UK services
https://prototype-kit.service.gov.uk
MIT License
306 stars 236 forks source link

Investigate the NHS fork of the Kit #2167

Open ruthhammond opened 1 year ago

ruthhammond commented 1 year ago

What

We investigate how the NHS fork of the Kit has been built. What features there are and why. Also considering how these features might be used by other departments i.e. common functionality.

Linked to #2166 and should be worked on simultaneously.

Why

So we understand how we should design the user experience of creating prototypes using different plugins to GOV.UK Frontend

Who

Done when

nataliecarey commented 1 year ago

Here's the approach we used when building the spike and it's what I'd recommend for the solution when we build it. I'm using the term variants to describe plugins that specify how a newly created kit should function.

It needs to be democratic in the way that plugins are democratic - anyone should be able to create a variant without it being centrally approved.

The Prototype Kit itself is the vanilla (default) variant, but it is a variant just like any other.

Variants can build upon other variant - particularly relevant for people building on top of the vanilla kit.

Variants come from a config file similar to the govuk-prototype-kit.config.json in the root of NPM modules.

We need to support specific versions in the same way as NPM does.

A variant should be able to specify:

So that means that people can create the following variants:

HMRC

Just a normal kit but with hmrc-frontend pre-installed.

NHS

A kit without govuk-frontend installed, but with nhsuk-frontend (https://www.npmjs.com/package/nhsuk-frontend) pre-installed.

There are custom starter files defined in nhsuk-frontend, depending on the config that's either instead of or on top of the normal files.

An example of the interface I'm picturing

HMRC

govuk-prototype-kit.variant.json

{
  "inheritFrom": ["govuk-prototype-kit"],
  "installedPackages": [
    "__INHERIT__",
    "hmrc-frontend"
  ]
}

NHS Frontend

govuk-prototype-kit.variant.json

{
  "inheritFrom": ["govuk-prototype-kit"],
  "installedPackages": [
    "nhsuk-frontend"
  ],
  "starterFileDirectories": [
    "__INHERIT__",
    "/prototoype-kit-starter-files"
  ],
  "postCreateScripts": [
    "__INHERIT__",
    "/prototype-kit-editStarterFiles"
  ],
  "pluginListUrls": [
    "https://service-manual.nhs.uk/design-system/prototype-kit-plugins.json"
  }
}

Files inside the prototype-kit-starter-files directory would be copied after the core kit files, that means they can just override individual files like layout.html.

postCreateScripts would run afterwards - e.g. to update the package.json.

GOV.UK Prototype Kit

govuk-prototype-kit.variant.json

{
  "installedPackages": [
    "govuk-frontend",
    "@govuk-prototype-kit/common-templates"
  ],
  "starterFileDirectories": [
    "/prototype-starter"
  ],
  "postCreateScripts": 
    "/bin/postCreate"
  ],
  "pluginListUrls": [
    "https://prototype-kit.service.gov.uk/prototype-kit-plugins.json"
  },
  "defaultVersionControl": "git"
}

/bin/postCreate would contain most of what's in runInit (bin/cli#L330-L333)

CLI Interface

npx govuk-prototype-kit create --variant=nhsuk-frontend npx govuk-prototype-kit create --variant=hmrc-frontend npx govuk-prototype-kit create --variant=github:hmrc/hmrc-frontend#branch-name npx govuk-prototype-kit create is equivalent to npx govuk-prototype-kit create --variant=govuk-prototype-kit

About inheritance

That's the plan I have, the importance of __INHERIT__ is that the variant creator gets to decide whether they run theirs before or after ours or not at all. The inheritFrom property brings over everything from our variant file by default, but if it's overridden with something that doesn't define INHERIT then our one isn't used.

For example: Both NHS and HMRC examples above inherit the git, if they didn't want that they can override it.