Skip to content
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

Fix tree-shaking when importing govuk-frontend #4961

Merged
merged 10 commits into from
May 3, 2024
42 changes: 42 additions & 0 deletions .github/workflows/bundler-integrations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Bundler integrations

on:
workflow_call:
workflow_dispatch:

jobs:
test-tree-shaking:
name: Test tree shaking
runs-on: ubuntu-latest

env:
PUPPETEER_SKIP_DOWNLOAD: true

strategy:
fail-fast: false

matrix:
bundler:
- rollup
- webpack
- vite

steps:
- name: Checkout
uses: actions/checkout@v4.1.4

- name: Restore dependencies
uses: ./.github/workflows/actions/install-node

- name: Build GOV.UK Frontend
uses: ./.github/workflows/actions/build

- name: Build with bundler
run: npm run ${{matrix.bundler}} -w @govuk-frontend/bundler-integrations

# Check output for modules that should not be included
- name: Check output
working-directory: ./.github/workflows/bundler-integrations
run: |
! grep "Accordion" dist/${{matrix.bundler}}/single-component.js -q
grep "Accordion" dist/${{matrix.bundler}}/initAll.js -q
24 changes: 24 additions & 0 deletions .github/workflows/bundler-integrations/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@govuk-frontend/bundler-integrations",
"description": "Boilerplate to verify that GOV.UK Frontend works OK with main bundlers",
"private": true,
"scripts": {
"rollup": "npm run rollup:single-component && npm run rollup:initAll",
"rollup:single-component": "npm run rollup:cli -- -o dist/rollup/single-component.js ./src/single-component.mjs",
"rollup:initAll": "npm run rollup:cli -- -o dist/rollup/initAll.js ./src/initAll.mjs",
"rollup:cli": "rollup -c rollup.config.mjs",
"webpack": "webpack --mode production -o dist/webpack",
"vite": "vite build",
"clean": "del-cli dist",
"build:all": "concurrently \"npm run rollup\" \"npm run webpack\" \"npm run vite\" --names \"rollup,webpack,vite\" --prefix-colors \"red.dim,blue.dim,yellow.dim\""
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.2.3",
"concurrently": "^8.2.2",
"del-cli": "^5.1.0",
"govuk-frontend": "*",
"rollup": "^4.17.2",
"vite": "^5.2.10",
"webpack": "^5.91.0"
}
}
6 changes: 6 additions & 0 deletions .github/workflows/bundler-integrations/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import resolve from '@rollup/plugin-node-resolve'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment Rollup needs a plugin to resolve package from node_modules.


/** @type {import('rollup').RollupOptions} */
export default {
plugins: [resolve()]
}
4 changes: 4 additions & 0 deletions .github/workflows/bundler-integrations/src/initAll.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// An example of importing and initialising allcomponents via initAll
import { initAll } from 'govuk-frontend'

initAll()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// An example of importing a single component from govuk-frontend and initialising it
import { Button } from 'govuk-frontend'

const $buttons = document.querySelectorAll('[data-module="govuk-button"]')

$buttons.forEach(($button) => {
/* eslint-disable-next-line no-new */
new Button($button)
})
18 changes: 18 additions & 0 deletions .github/workflows/bundler-integrations/vite.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** @type {import('vite').UserConfig} */
// the default vite config used by the different test case configs

export default {
build: {
// Align output with other bundlers to facilitate testing
outDir: 'dist/vite',
assetsDir: '.',
Comment on lines +7 to +8
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment By default, Vite would output in dist and the compiled JavaScript in dist/assets. This makes it match the dist/<BUNDLER_NAME> convention from the other bundlers.

// Prevent minification so we can see actual class/function names
minify: false,
rollupOptions: {
input: ['./src/single-component.mjs', './src/initAll.mjs'],
output: {
entryFileNames: '[name].js'
}
}
}
}
18 changes: 18 additions & 0 deletions .github/workflows/bundler-integrations/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** @type {import('webpack').Configuration} */
module.exports = {
optimization: {
// Configure WebPack to drop exports that are not used from the code
// so we can disable Terser and still check what's being included
usedExports: true,
// Prevent minification so we can see what's going on in the built file
minimize: false
},
target: 'web',
entry: {
'single-component': './src/single-component.mjs',
initAll: './src/initAll.mjs'
},
output: {
filename: '[name].js'
}
}
8 changes: 8 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,11 @@ jobs:
# Run existing "Stats comment" workflow
# (after only install has been cached)
uses: ./.github/workflows/stats-comment.yml

bundler-integrations:
name: Bundler integrations
needs: [install, build]

# Run existing "Bundler integrations" workflow
# (after install and build have been cached)
uses: ./.github/workflows/bundler-integrations.yml
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ For advice on how to use these release notes see [our guidance on staying up to
We've made fixes to GOV.UK Frontend in the following pull requests:

- [#4942: Remove duplicate `errorMessage` argument for the password input component](https://github.com/alphagov/govuk-frontend/pull/4942) - thanks to [Tim South](https://github.com/tim-s-ccs) for contributing this change
- [#4961: Fix tree-shaking when importing `govuk-frontend`](https://github.com/alphagov/govuk-frontend/pull/4961)

## 5.3.1 (Fix release)

Expand Down
10 changes: 10 additions & 0 deletions docs/contributing/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,13 @@ This task will:
## Review app only

After building the project with `npm run build` the Express.js review app can be started with `npm start --workspace @govuk-frontend/review`. This prevents the Gulp tasks triggered by `npm start` from running.

## Bundler integration

After building the project with `npm run build`, you can verify that the `govuk-frontend` package will be consumed correctly by mainstream bundlers with `npm run <BUNDLER_NAME> --workspace @govuk-frontend/bundler-integrations` (where bundler name is one of `rollup`, `webpack` or `vite`).

This will use the specified bundler to compile both `.github/workflows/bundler-integrations/src/default.mjs` which is only importing one component, and `.github/workflows/bundler-integrations/src/initAll.mjs` which is importing and initialising all components via `initAll`. This helps us verify that [tree shaking] works as intended. The build output for both files is `.github/workflows/bundler-integrations/dist/<BUNDLER_NAME>/[name].js`. `default.js` should not contain the code of other components whilst `initAll.js` should contain the code for all the components.

You can also run `npm run build:all --workspace @govuk-frontend/bundler-integrations` to run all three bundlers in one go.

[tree shaking]: https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking
Loading