Date: 2023-06-27
Status: Accepted
We will consolidate all published JavaScript in the govuk-frontend
npm package into a single govuk
directory.
We will publish JavaScript in the following formats:
- ECMAScript (ES) modules
- ECMAScript (ES) modules, bundled
- Universal Module Definition (UMD), bundled
We will use ECMAScript (ES) modules by default and only bundle JavaScript files that are considered "entry points" into GOV.UK Frontend, such as all.mjs
and exported components (for example accordion.mjs
).
We will change our GitHub release JavaScript govuk-frontend-${version}.min.js
to ECMAScript (ES) modules format and add it to the published govuk-frontend
npm package without a version number.
For consistency, we will clearly update our file extensions to:
- Add prefix
.bundle
to bundled JavaScript file extensions - Add prefix
.min
to minified JavaScript file extensions - Always use
*.mjs
for ES modules (except for our GitHub release, see constraints below)
See the example directory listing below to show how files in govuk-frontend/dist
will be named, further to our decision to restructure govuk-frontend
:
govuk-frontend/dist
└── govuk
├── govuk-frontend.min.js # ECMAScript (ES) module bundle, minified
│
├── all.mjs # ECMAScript (ES) module
├── all.bundle.mjs # ECMAScript (ES) module bundle
├── all.bundle.js # Universal Module Definition (UMD) bundle
│
└── components
├── accordion
│ ├── accordion.mjs # ECMAScript (ES) module
│ ├── accordion.bundle.mjs # ECMAScript (ES) module bundle
│ └── accordion.bundle.js # Universal Module Definition (UMD) bundle
│
└── button
├── button.mjs # ECMAScript (ES) module
├── button.bundle.mjs # ECMAScript (ES) module bundle
└── button.bundle.js # Universal Module Definition (UMD) bundle
We can avoid future breaking changes by changing file names and extensions to clearly show:
- different "flavours" of JavaScript like ES modules
- which files are standalone, bundled or minified
For example, as explained in our JavaScript browser compatibility decision we may need to add polyfills or transpilation helpers in future.
Service users can optionally either import *.bundle.mjs
(ES modules, bundled) or require *.bundle.js
(UMD, bundled) to include all the polyfills they need, or alternatively import *.mjs
(ES modules) to use their own bundler.
Due to poor web server Content-Type
header support for *.mjs
files, we've kept the *.js
extension for our GitHub release JavaScript govuk-frontend-${version}.min.js
bundle.
For reference:
We've changed our GitHub release JavaScript govuk-frontend-${version}.min.js
bundle format from Universal Module Definition (UMD) to ES modules, but there is a risk that service users will still require UMD.
We know that CommonJS compatibility is important for both Node.js require('govuk-frontend')
package resolution and for test runners that do not support ES modules yet.
For example, by making our npm package "ESM only" we'd hit issues such as:
- Jest ECMAScript modules support needing
--experimental-vm-modules
- Mocha current limitations like
--watch
mode only works with CommonJS
Due to this constraint we've maintained CommonJS support by continuing to package Universal Module Definition (UMD) bundles.
We considered using directories to show different JavaScript formats but preferred file names and extensions:
govuk-frontend/dist
└── govuk
├── cjs
├── mjs
└── umd
We considered always using *.js
file extensions and adding JavaScript formats as prefixes, but preferred using prefixes to clearly show standalone, bundled or minified files instead:
govuk-frontend/dist
└── govuk
├── all.cjs.js
├── all.mjs.js
└── all.umd.js
We acknowledge the Node.js support constraint above prevents us from removing CommonJS support. That said, we chose not to publish separate *.cjs
(CommonJS modules) since CommonJS support is still provided by our Universal Module Definition (UMD) bundles.
- Users that follow our Add the JavaScript file to your HTML or Importing JavaScript documentation will need to replace
govuk/all.js
withgovuk/all.bundle.js
. - Users that directly import/require
govuk/**/*.js
UMD bundles will need to add the.bundle
extension prefix asgovuk/**/*.bundle.js
. - Users that directly import
govuk-esm/**/*.mjs
ES modules will need to remove the-esm
directory suffix asgovuk/**/*.mjs
.
Note: Users that import/require govuk-frontend
by name are unaffected.
- Brett Kyle (@domoscargin)
- Colin Rotherham (@colinrotherham)
- Oliver Byford (@36degrees)
- Romaric Pascal (@romaricpascal)