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 as great for browser and CommonJs support but not ES6 Modules.
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.
Do you lose tree shaking by using 'rollup-plugin-commonjs'/UMD? I'm having to useimport Button from 'govuk-frontend/components/button/button'; rather than import { Button } from 'govuk-frontend' to only get the code I want.
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: https://github.com/alphagov/govuk-frontend/issues/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: Button, Radios, Checkboxes, ErrorSummary, that's about it. So to save on the bundle size I made a custom all.js file that only imports the components I need. The other reason we do this is that we have some custom components which use the same polyfills (and one that reuses Button) which can also be added to the same all.js file. The tree shaking will avoid bundling the same polyfills or components twice, resulting in a single small js bundle.
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 type: module in package.json
Sindre Sorhus鈥檚 FAQ. for more details
alternatively ship additional govuk-frontend-esm npm package
Most helpful comment
In our project we use very few govuk-frontend js modules:
Button,Radios,Checkboxes,ErrorSummary, that's about it. So to save on the bundle size I made a customall.jsfile that only imports the components I need. The other reason we do this is that we have some custom components which use the same polyfills (and one that reuses Button) which can also be added to the sameall.jsfile. The tree shaking will avoid bundling the same polyfills or components twice, resulting in a single small js bundle.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!