alphagov / govuk-frontend

GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.
https://frontend.design-system.service.gov.uk/
MIT License
1.18k stars 325 forks source link

4.1.0 does not bundle with esbuild #2634

Closed tvararu closed 2 years ago

tvararu commented 2 years ago

Description of the issue

4.1.0 does not bundle successfully with esbuild.

Steps to reproduce the issue

Minimal repro repository: https://github.com/tvararu/govuk-frontend-esbuild-test

// index.js
import { initAll } from "govuk-frontend";

initAll();
# build script
"build": "esbuild index.js --bundle"

Actual vs expected behaviour

See https://github.com/tvararu/govuk-frontend-esbuild-test/actions for a successful build with 4.0.1 vs a failing one with 4.1.0.

Example failing build output:

$ node -v
v18.1.0
$ yarn
yarn install v1.22.19
[1/5] Validating package.json...
[2/5] Resolving packages...
success Already up-to-date.
Done in 0.08s.
$ yarn build
yarn run v1.22.19
$ esbuild index.js --bundle
✘ [ERROR] Could not resolve "./common"
    node_modules/govuk-frontend/govuk-esm/all.mjs:1:32:
      1 │ import { nodeListForEach } from './common'
        ╵                                 ~~~~~~~~~~
✘ [ERROR] Could not resolve "./components/accordion/accordion"
    node_modules/govuk-frontend/govuk-esm/all.mjs:2:22:
      2 │ import Accordion from './components/accordion/accordion'
        ╵                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
✘ [ERROR] Could not resolve "./components/button/button"
    node_modules/govuk-frontend/govuk-esm/all.mjs:3:19:
      3 │ import Button from './components/button/button'
        ╵                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
✘ [ERROR] Could not resolve "./components/details/details"
    node_modules/govuk-frontend/govuk-esm/all.mjs:4:20:
      4 │ import Details from './components/details/details'
        ╵                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
✘ [ERROR] Could not resolve "./components/character-count/character-count"
    node_modules/govuk-frontend/govuk-esm/all.mjs:5:27:
      5 │ import CharacterCount from './components/character-count/character-count'
        ╵                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
✘ [ERROR] Could not resolve "./components/checkboxes/checkboxes"
    node_modules/govuk-frontend/govuk-esm/all.mjs:6:23:
      6 │ import Checkboxes from './components/checkboxes/checkboxes'
        ╵                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 of 12 errors shown (disable the message limit with --log-limit=0)
node:child_process:855
    throw err;
    ^
Error: Command failed: /home/deity/git/govuk-frontend-esbuild-test/node_modules/esbuild-linux-64/bin/esbuild index.js --bundle
    at checkExecSyncError (node:child_process:817:11)
    at Object.execFileSync (node:child_process:852:15)
    at Object.<anonymous> (/home/deity/git/govuk-frontend-esbuild-test/node_modules/esbuild/bin/esbuild:172:28)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Module._load (node:internal/modules/cjs/loader:827:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47 {
  status: 1,
  signal: null,
  output: [ null, null, null ],
  pid: 83518,
  stdout: null,
  stderr: null
}
Node.js v18.1.0
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Environment (where applicable)

$ node -v
v18.1.0
$ yarn -v
1.22.19
$ cat package.json
{
  "dependencies": {
    "esbuild": "^0.14.39",
    "govuk-frontend": "4.1.0"
  },
  "scripts": {
    "build": "esbuild index.js --bundle"
  }
}
tvararu commented 2 years ago

Found the solution:

esbuild index.js --bundle --resolve-extensions=.mjs,.js

It's the esbuild version of the same thing the guidance suggests for webpack: https://frontend.design-system.service.gov.uk/importing-css-assets-and-javascript/#import-javascript-using-a-bundler

From the esbuild docs https://esbuild.github.io/api/#resolve-extensions

Note that esbuild deliberately does not include the new .mjs and .cjs extensions in this list. Node's resolution algorithm doesn't treat these as implicit file extensions, so esbuild doesn't either. If you want to import files with these extensions you should either explicitly add the extensions in your import paths or change this setting to include the additional extensions that you want to be implicit.

Commit with green passing build: https://github.com/tvararu/govuk-frontend-esbuild-test/commit/0681217a81e9c8e5983490ebd68fcb56a8da63cd

Closing this issue, but happy I wrote this out for posterity or in case it helps others.

Maybe the govuk-frontend docs could be updated to include a note about esbuild, next to the webpack one?