diff --git a/decision-records/007-javascript-file-formats.md b/decision-records/007-javascript-file-formats.md new file mode 100644 index 0000000..8ce997c --- /dev/null +++ b/decision-records/007-javascript-file-formats.md @@ -0,0 +1,119 @@ +# JavaScript file names and formats + +**Date:** 2023-06-27 + +**Status:** Accepted + +## Decision + +We will consolidate all published JavaScript in the [`govuk-frontend` npm package](https://www.npmjs.com/package/govuk-frontend) into a single `govuk` directory. + +We will publish JavaScript in the following formats: + +1. ECMAScript (ES) modules +2. ECMAScript (ES) modules, bundled +3. 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](https://github.com/alphagov/govuk-frontend/releases) JavaScript `govuk-frontend-${version}.min.js` to ECMAScript (ES) modules format and add it to the [`govuk-frontend` npm package](https://www.npmjs.com/package/govuk-frontend). + +We will deprecate the Universal Module Definition (UMD) format in a future release. + +For consistency, we will clearly update our file extensions to: + +1. Add prefix `.bundle` to bundled JavaScript file extensions +2. Add prefix `.min` to minified JavaScript file extensions +3. Always use `*.mjs` for ES modules (except for our [GitHub release](https://github.com/alphagov/govuk-frontend/releases), see constraints below) + +Further to our [decision to restructure `govuk-frontend`](./005-repository-organisation-for-v5.md), see the example directory listing below to show files in `govuk-frontend/dist` will be named: + +```shell +govuk-frontend/dist +└── govuk + ├── govuk-frontend-5.0.0.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 +``` + +## Rationale + +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](./006-javascript-compatibility.md) we may need to add polyfills or transpilation helpers in future. + +Service teams 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. + +## Risks and constraints + +### Browser Content-Type headers and `*.mjs` extensions + +This decision publishes our [GitHub release](https://github.com/alphagov/govuk-frontend/releases) JavaScript `govuk-frontend-${version}.min.js` into the [`govuk-frontend` npm package](https://www.npmjs.com/package/govuk-frontend). + +Whilst we've changed the minified bundle from UMD to ES module format, we've decided to keep the file extension as `*.js` until web server support for `*.mjs` content-type headers improves. + +For reference: + +* [Apache issue, resolved May 2022](https://bz.apache.org/bugzilla/show_bug.cgi?id=61383) +* [Nginx issue, unresolved](https://trac.nginx.org/nginx/ticket/2216) + +### Maintaining CommonJS compatibilty + +We know that CommonJS compatibility is important for both [Node.js `require('govuk-frontend')` package resolution](https://github.com/alphagov/govuk-frontend/issues/3755) 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: + +1. [Jest ECMAScript modules support](https://jestjs.io/docs/ecmascript-modules) needing `--experimental-vm-modules` +2. [Mocha current limitations](https://mochajs.org/#current-limitations) like [`--watch` mode](https://github.com/mochajs/mocha/issues/4374) only works with CommonJS + +We've maintained CommonJS support by continuing to package Universal Module Definition (UMD) bundles. + +## Alternatives considered + +### Using directories for JavaScript flavours + +TBC + +### Use file extensions for JavaScript flavours + +TBC + +### Deprecating Universal Module Definition (UMD) bundles in future + +We acknowledge that our plan to deprecate and remove Universal Module Definition (UMD) bundles in future may either be blocked or make it necessary to publish CommonJS `*.cjs` as an alternative. + +## Implications + + + +## Contributors + + +- Brett Kyle (@domoscargin) +- Colin Rotherham (@colinrotherham) +- Oliver Byford (@36degrees) +- Romaric Pascal (@romaricpascal) + +## Associated issues and pull requests (PRs) + + + +## Outcomes + +