-
Notifications
You must be signed in to change notification settings - Fork 328
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
Cannot import standard ES6 modules from npm #711
Comments
Add Rollup plugins, includes commonjs plugins since GOV.UK Frontend is currently shipped as UMD. See alphagov/govuk-frontend#711 for more details.
Add Rollup plugins, includes commonjs plugins since GOV.UK Frontend is currently shipped as UMD. See alphagov/govuk-frontend#711 for more details.
Do you lose tree shaking by using 'rollup-plugin-commonjs'/UMD? I'm having to use |
Yeah I believe that's the only way currently to achieve what you'd get for free with tree shaking. |
Would be good to also think about how polyfills would be treeshaking as part of this work: #710 |
A possible way to test tree shaking: https://twitter.com/Rich_Harris/status/1031220091940204546?s=17 |
In our project we use very few govuk-frontend js modules: Unforuntatley the only way to achieve this is to add this Github repo as a npm depency, as the unbundled source is not included in the npm package and using the individually bundled components does not take advantage of tree shaking, bloating out the total bundle size. This also presents us with some problems:
So in an ideal world the unbundled component js would be included in the govuk-frontend npm package in a way in which it could be imported as an ES6 module. This could also allow serving the ES6 modules directly over HTTP2 in the future, falling back to the bundle. I'd be happy to help on the implementation of this if an approach could be agreed. Thanks! |
direction most packages are moving to is to specify |
I did some testing last year to verify that directly including the ES6 modules from I also saw that there was about a ~20% reduction in the size of the resulting JavaScript file, although this is a bit arbitrary since I only tested the import of two components (the accordion and the character count). I also had a bit of a dig through what the removed JS consisted of and agreed with @andymantell's assessment that it seems to be mainly made up of the duplicated polyfills. I haven't assessed the |
I had a quick look at using
|
I've got a WIP branch with some hacky non-functional bare bones approaches that I was going to run by the team.
Doesn't really work - we're rolling up file by file, so all the polyfill duplication still happens, and you lose the opportunity for other services to roll their own bundling.
Big questions here are how to correctly target the
The published package becomes a lot larger and there's presumably going to be a lot of namespacing issues. Could the JS files only be separated into another folder with an entry point file? |
Playing around with esm modules in govuk-frontend. Based on original work by @domoscargin who did the initial investigation into different approaches for this. This commit explores option 3 more. #711 (comment)
@domoscargin and I have been testing this approach with the following bundlers: Webpack; Parcel; Rollup; esbuild. Setting
|
This is all looking really good to me. I did notice a couple of things on the Design System branch (possibly because it's using an older pre-release?):
Not sure if either of these things are actually issues, but thought they were worth flagging. |
@36degrees Good shout on For the other point, importing from Does that make sense? |
Summary of changesWe're proposing to add a new In order to support both the UMD we currently ship, and these new ESM files, we will add the following to our
Setting the Because of the way we include polyfills in our JavaScript, we also need to set |
@andymantell @gunjam @matthewblewitt This may be of interest to you as people who have previously been active on this issue. The Design System team is working on a solution for publishing our JavaScript as ES Modules (ESM) alongside the Universal Module Definition (UMD) we currently ship. Using a bundler with ES Modules also helps reduce duplication of things like polyfills. We're looking for your feedback on any issues you might have when upgrading your service to use this new functionality. Let us know by commenting on this Github issue, or email us at [email protected]. Tell us your thoughts by Tuesday 19th April 2022. ⏭ To update to the pre-release, run To take advantage of this new functionality, you’ll need to update your JavaScript to use
To import specific components:
You may also need to make changes to your JavaScript bundler configuration file, such as telling it to look out for the |
Playing around with esm modules in govuk-frontend. Based on original work by @domoscargin who did the initial investigation into different approaches for this. This commit explores option 3 more. #711 (comment)
Playing around with esm modules in govuk-frontend. Based on original work by @domoscargin who did the initial investigation into different approaches for this. This commit explores option 3 more. #711 (comment)
Playing around with esm modules in govuk-frontend. Based on original work by @domoscargin who did the initial investigation into different approaches for this. This commit explores option 3 more. #711 (comment)
Hey! Thanks so much for this work, once released this should allow me install the govuk-frontend module properly again rather than include a tagged point in the repo to get the original source. I'm gonna make a branch on our frontend project to test it out and see if these changes will fit neatly into my build. |
Hi, So I seem to have an issue where I can't import any files directly from their file paths while exports is set in the package.json: "exports": {
"import": "./govuk-esm/all.mjs"
}, This seems to restrict the node-resolve plugin of rollup from importing anything other than that file. If I remove the exports from the package.json it works fine. For context this is what I'm trying to do in a custom all.js (import the GOVUK components I wish to init, along with an HMRC component and some that are custom to the service): import { nodeListForEach } from 'govuk-frontend/govuk-esm/common.mjs';
import { Button, Checkboxes, ErrorSummary, Radios, SkipLink } from 'govuk-frontend';
import TimeoutDialog from 'hmrc-frontend/hmrc/components/timeout-dialog/timeout-dialog';
import PrintButton from './js/print-button';
import SaveLink from './js/save-link';
import TimeoutButton from './js/timeout-button';
import CookieBanner from './js/cookie-banner'; Rollup cannot resolve common.mjs, or any of the polyfills which I am importing in the custom modules (eg cookie-banner) as they do not appear in the package.json exports block (I assume). I'm working on a branch of an internal project, but I'll set up a small public repo with an example if it helps. Thanks |
I've setup a small repo with an example project, it won't build, but if you go into the node_modules folder and delete the exports property from the govuk-frontend package.json it will build fine. Of course there's probably a way to work around this, but I dunno what it is yet. A solution vaugely formed in my mind but then I immediately forgot what it was, maybe it'll come back to me tomorrow. Thanks again. |
Hey @gunjam, thanks for investigating, and taking the time to set up a nice example. This is intended behaviour - importing from In fact, as part of our work to update our browser support and fix up some of our JavaScript, we'll likely be proposing some changes to polyfills, which would affect your project. We'll put out a more detailed proposal of our changes for feedback soon. |
Oh I see! Since I was @d in this thread I assumed it was related to my previous comment. |
What
At the moment if you try to import using our documentation using a standard ES6 bundler such as Rollup it will fail.
This is because we ship our bundles as UMD, which is great for browser and CommonJs support but not ES6 Modules (better for build pipelines).
This means our current guidance around rollup is misleading and only works when compiling from source.
We could consider adding more real world examples that import the package directly to ensure what we recommend is tested.
I'm not sure if we should be publishing these as
.mjs
files, which seems to be what Node.js is going towards.Why
Some users rely on getting modules directly from
/src
, which we don't recommend and don't want to encourage. Many of these users say they're running outdated versions. We should make it easier for them to import as standard ES6 modules.Done when
/src
type: module
in the package.json/src
)The text was updated successfully, but these errors were encountered: