-
Notifications
You must be signed in to change notification settings - Fork 333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default to ES modules with single Rollup config #3726
Conversation
9d380ed
to
c3429f0
Compare
c3429f0
to
a27237f
Compare
55f3c63
to
596b797
Compare
a27237f
to
cea143d
Compare
cea143d
to
c17969c
Compare
29386b2
to
cf2e767
Compare
c17969c
to
175489a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks promising and super helpful for discussing #3721.
Regarding the output, so we're clear on what our options are, does that mean we have complete flexibility on:
- the format, between
esm
,cjs
,umd
andiife
via theformat
option - whether the
import
ed modules are bundled in the resulting file or left asimport
statements via thepreserveModules
option
I also like that we could move to a unique tree thanks to the ./*
path in the exports
(more related to #3482 that part).
Thanks @romaricpascal Yeah it's primarily to address this "modules versus bundles" thread which caught us out Historically we've bundled every JavaScript file separately into UMD, but now we can pick any module format and even CommonJS bundlers should be able to do tree-shaking |
fb27669
to
36ee87a
Compare
175489a
to
bca889a
Compare
36ee87a
to
3dcefb3
Compare
bca889a
to
d7e5a9f
Compare
I reckon
Would it be more idiomatic to go with |
@36degrees Yeah let's leave it for another PR Must have been intentional at some point and matches Sass |
f8bf269
to
4e7afc6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience as we worked through all of this @colinrotherham 🙌🏻
Last push removed the version suffix from the "browser ready" minified bundle: import { initAll } from '/javascripts/govuk-frontend.min.js' I've updated our decision document to reflect this: |
* ECMAScript (ES) modules as `*.mjs` * ECMAScript (ES) module bundles as `*.bundle.mjs` * Universal Module Definition (UMD) bundles as `*.bundle.js` But like we do for our GitHub release zip files also add a "ready to go" minified bundle for: * ECMAScript (ES) module bundle minified as `govuk-frontend.min.js` (Except unlike our GitHub release we don’t add a version number)
See Node.js documentation for conditional exports: https://nodejs.org/api/packages.html#conditional-exports >Providing a "default" condition ensures that any unknown JS environments are able to use this universal implementation, which helps avoid these JS environments from having to pretend to be existing environments in order to support packages with conditional exports.
We only import `common/index.mjs` but kept this module to avoid breaking changes in v4
We already provide ES modules for all our source files so don’t need to produce additional bundles for every helper and utility too
We no longer need a separate Rollup config for UMD
This is in preparation for the switch to ES modules as our default GitHub release flavour It ensures that export names (Accordion, Button, initAll, version etc) are maintained within the bundle, not just at export time
Alongside our UMD bundles we now have ES module bundles for completeness Although they’re not minified, browsers can now `await import()` ES module bundles without having to resolve and download imported child modules (including potentially `node_modules` for polyfills)
This runs the Rollup build for our GitHub release JavaScript `govuk-frontend-{{ version }}.min.js` into package too but without the version number
Rollup build is not necessary when `govuk-frontend.min.js` is already built
4e7afc6
to
754315c
Compare
We'll update our
☝️ It's still using the UMD + window globals approach but via |
This PR consolidates all
govuk-frontend
npm package JavaScript into thegovuk
directoryWe use Rollup to build JavaScript into the following formats + extensions:
*.mjs
*.bundle.mjs
*.bundle.js
But like we do for our GitHub release zip files also add a "ready to go" minified bundle for:
govuk-frontend.min.js
CommonJS compatibility
We've felt the pain of "ESM only" packages recently and know that CommonJS compatibility is important for both Node.js
require('govuk-frontend')
package resolution and for test runners that don't support ES modules yetBy dropping CommonJS and going "ESM only" we'd hit issues such as:
--experimental-vm-modules
--watch
mode only working with CommonJSAlthough more complex workarounds like Babel compiling ES modules to CommonJS can work instead
Legacy bundlers
Some bundlers like Browserify support
require('govuk-frontend')
but may need AMD not CommonJS format. Similarly the unpkg CDN falls back to expect a UMD bundle in package.json"main"
Package layout
Script includes
But by adding "ready to go" bundles
all.bundle.js
(UMD) andall.bundle.mjs
(ES module) we maintain non-bundler compatibility even when importing JavaScript directly (see README.md)✅ Rails Asset Pipeline using
//= require
to concatenate UMDall.bundle.js
✅ Browsers using dynamic
await import()
to load ES moduleall.bundle.mjs
✅ Browsers using
<script type="module">
to load ES moduleall.bundle.mjs
Note: Only
govuk-frontend.min.js
is minified, unlike other bundlesWindow globals
What do we do about UMD-only window globals likewindow.GOVUKFrontend.Accordion
?Regarding window globals we'll continue to support UMD bundles in v5 but will deprecate them in a future release