Skip to content

Commit

Permalink
Add decision record about JavaScript file names and formats
Browse files Browse the repository at this point in the history
  • Loading branch information
colinrotherham committed Jul 4, 2023
1 parent b5a86f8 commit fb73771
Showing 1 changed file with 119 additions and 0 deletions.
119 changes: 119 additions & 0 deletions decision-records/007-javascript-file-formats.md
Original file line number Diff line number Diff line change
@@ -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

<!-- Impacts of this decision. -->

## Contributors

<!-- Who made this decision. -->
- Brett Kyle (@domoscargin)
- Colin Rotherham (@colinrotherham)
- Oliver Byford (@36degrees)
- Romaric Pascal (@romaricpascal)

## Associated issues and pull requests (PRs)

<!-- Add links to any related GitHub issues and / or PRs. -->

## Outcomes

<!-- Note any outcomes or consequences of the decision . -->

0 comments on commit fb73771

Please sign in to comment.