Skip to content

Commit

Permalink
Merge pull request #3833 from alphagov/es-module-import
Browse files Browse the repository at this point in the history
  • Loading branch information
colinrotherham authored Jun 22, 2023
2 parents 73a6a39 + f1a0637 commit 51461de
Show file tree
Hide file tree
Showing 24 changed files with 102 additions and 95 deletions.
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ module.exports = function (api) {

const presets = [
['@babel/preset-env', {
exclude: [
'transform-dynamic-import'
],
targets: {
node: 'current'
}
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/govuk-frontend-review/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineConfig(({ i: input }) => ({
* Output options
*/
output: {
format: 'iife',
format: 'es',

/**
* Output plugins
Expand Down
2 changes: 1 addition & 1 deletion packages/govuk-frontend-review/src/app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export default async () => {
const componentName = req.params.componentName
const exampleName = req.params.exampleName || 'default'

const previewLayout = res.locals.componentData?.previewLayout || 'layout'
const previewLayout = res.locals.componentData?.previewLayout

const exampleConfig = res.locals.componentData?.examples.find(
example => example.name.replace(/ /g, '-') === exampleName
Expand Down
5 changes: 1 addition & 4 deletions packages/govuk-frontend-review/src/javascripts/all.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
import * as GOVUKFrontend from 'govuk-frontend'

// @ts-expect-error Manually add globals to window for tests
window.GOVUKFrontend = GOVUKFrontend
export * from 'govuk-frontend'
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layouts/" + previewLayout + ".njk" %}
{% extends "layouts/" + previewLayout | default('layout') + ".njk" %}

{% set bodyClasses %}
{{ bodyClasses }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@
{% endblock %}

{% block bodyEnd %}
<script type="module" src="/javascripts/all.min.js"></script>
<script type="module" src="/javascripts/all.bundle.min.mjs"></script>
<script type="module">
import { initAll } from '/javascripts/all.bundle.min.mjs'
const $scope = document.getElementById('scoped')
window.GOVUKFrontend.initAll({
scope: $scope
})
initAll({ scope: $scope })
</script>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@

{% block bodyEnd %}
<!-- block:bodyEnd -->
<script type="module" src="/javascripts/all.min.js"></script>
<script type="module">window.GOVUKFrontend.initAll()</script>
<script type="module" src="/javascripts/all.bundle.min.mjs"></script>
<script type="module">
import { initAll } from '/javascripts/all.bundle.min.mjs'
initAll()
</script>
<!-- endblock:bodyEnd -->
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@

{% block bodyEnd %}
<!-- block:bodyEnd -->
<script type="module" src="/javascripts/all.min.js"></script>
<script type="module">window.GOVUKFrontend.initAll()</script>
<script type="module" src="/javascripts/all.bundle.min.mjs"></script>
<script type="module">
import { initAll } from '/javascripts/all.bundle.min.mjs'
initAll()
</script>
<!-- endblock:bodyEnd -->
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -937,18 +937,19 @@
{% endblock %}

{% block bodyEnd %}
<script type="module" src="/javascripts/all.min.js"></script>
<script type="module" src="/javascripts/all.bundle.min.mjs"></script>
<script type="module">
window.GOVUKFrontend.initAll({
import { initAll } from '/javascripts/all.bundle.min.mjs'
initAll({
accordion: {
i18n: {
showAllSections: "Dangos adrannau",
hideAllSections: "Cuddio adrannau",
showAllSections: 'Dangos adrannau',
hideAllSections: 'Cuddio adrannau',
},
"i18n.showSection": "Dangos",
"i18n.showSectionAriaLabel": "Dangos adran",
"i18n.hideSection": "Cuddio",
"i18n.hideSectionAriaLabel": "Cuddio adran"
'i18n.showSection': 'Dangos',
'i18n.showSectionAriaLabel': 'Dangos adran',
'i18n.hideSection': 'Cuddio',
'i18n.hideSectionAriaLabel': 'Cuddio adran'
}
})
</script>
Expand Down
7 changes: 5 additions & 2 deletions packages/govuk-frontend-review/src/views/layouts/_generic.njk
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
{% set mainClasses = 'govuk-main-wrapper--auto-spacing' %}

{% block bodyEnd %}
<script type="module" src="/javascripts/all.min.js"></script>
<script type="module">window.GOVUKFrontend.initAll()</script>
<script type="module" src="/javascripts/all.bundle.min.mjs"></script>
<script type="module">
import { initAll } from '/javascripts/all.bundle.min.mjs'
initAll()
</script>
{% endblock %}
32 changes: 20 additions & 12 deletions packages/govuk-frontend-review/src/views/tests/boilerplate.njk
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Test Boilerplate</title>
<link rel="stylesheet" href="/stylesheets/app.min.css">
</head>
<body class="govuk-template__body">
<script>document.body.className += ' js-enabled' + ('noModule' in HTMLScriptElement.prototype ? ' govuk-frontend-supported' : '');</script>
{% extends "component-preview.njk" %}

{% set pageTitle = "Test boilerplate" %}
{% block pageTitle %}{{ pageTitle }} - GOV.UK{% endblock %}

{% block head %}
{{ super() }}
<script type="importmap">
{ "imports": { "govuk-frontend": "/javascripts/all.bundle.min.mjs" } }
</script>
{% endblock %}

{% block content %}
<div class="app-whitespace-highlight">
<h1 class="govuk-heading-l">Test boilerplate</h1>
<p class="govuk-body">
Used during testing to inject rendered components and test specific configurations
</p>
<div id="slot"></div>
<script type="module" src="/javascripts/all.min.js"></script>
</body>
</html>
</div>
{% endblock %}

{% block bodyEnd %}
<script type="module" src="/javascripts/all.bundle.min.mjs"></script>
{% endblock %}
4 changes: 2 additions & 2 deletions packages/govuk-frontend-review/tasks/scripts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export const compile = (options) => gulp.series(
destPath: join(options.destPath, 'javascripts'),
configPath: join(options.basePath, 'rollup.config.mjs'),

// Rename with `*.min.js` extension
// Rename with `*.bundle.min.mjs` extension
filePath ({ dir, name }) {
return join(dir, `${name}.min.js`)
return join(dir, `${name}.bundle.min.mjs`)
}
})
),
Expand Down
2 changes: 1 addition & 1 deletion packages/govuk-frontend/postcss.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import autoprefixer from 'autoprefixer'
import cssnano from 'cssnano'
import cssnanoPresetDefault from 'cssnano-preset-default'
import { pkg } from 'govuk-frontend-config'
import { isDev } from 'govuk-frontend-tasks/helpers/task-arguments.mjs'
import { isDev } from 'govuk-frontend-tasks/helpers/task-arguments.js'
import postcss from 'postcss'
import scss from 'postcss-scss'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ describe('/components/button', () => {
it('does not prevent further JavaScript from running', async () => {
await goTo(page, '/tests/boilerplate')

const result = await page.evaluate((component) => {
const namespace = 'GOVUKFrontend' in window
? window.GOVUKFrontend
: {}
const result = await page.evaluate(async (exportName) => {
const namespace = await import('govuk-frontend')

// `undefined` simulates the element being missing,
// from an unchecked `document.querySelector` for example
new namespace[component](undefined).init()
new namespace[exportName](undefined).init()

// If our component initialisation breaks, this won't run
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,17 +648,14 @@ describe('Character count', () => {
// Override maxlength to 10
maxlength: 10
},
initialiser ({ config, namespace }) {
const $component = document.querySelector('[data-module]')

initialiser ($module) {
// Set locale to Welsh, which expects translations for 'one', 'two',
// 'few' 'many' and 'other' forms – with the default English strings
// provided we only have translations for 'one' and 'other'.
//
// We want to make sure we handle this gracefully in case users have
// an existing character count inside an incorrect locale.
$component.setAttribute('lang', 'cy')
new namespace.CharacterCount($component, config).init()
$module.setAttribute('lang', 'cy')
}
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { goToComponent, goToExample, renderAndInitialise } = require('govuk-frontend-helpers/puppeteer')
const { goToComponent, goToExample, renderAndInitialise, goTo } = require('govuk-frontend-helpers/puppeteer')
const { getExamples } = require('govuk-frontend-lib/files')

describe('Error Summary', () => {
Expand Down Expand Up @@ -82,14 +82,14 @@ describe('Error Summary', () => {

describe('using JavaScript configuration, with no elements on the page', () => {
it('does not prevent further JavaScript from running', async () => {
const result = await page.evaluate((component) => {
const namespace = 'GOVUKFrontend' in window
? window.GOVUKFrontend
: {}
await goTo(page, '/tests/boilerplate')

const result = await page.evaluate(async (exportName) => {
const namespace = await import('govuk-frontend')

// `undefined` simulates the element being missing,
// from an unchecked `document.querySelector` for example
new namespace[component](undefined).init()
new namespace[exportName](undefined).init()

// If our component initialisation breaks, this won't run
return true
Expand Down
24 changes: 9 additions & 15 deletions packages/govuk-frontend/src/govuk/components/globals.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ describe('GOV.UK Frontend', () => {
let exported

beforeEach(async () => {
await goTo(page, '/')
await goTo(page, '/tests/boilerplate')

// Exported via global (e.g GOVUKFrontend.initAll)
exported = await page.evaluate(() => 'GOVUKFrontend' in window
? Object.keys(window.GOVUKFrontend)
: undefined
// Exports available via browser dynamic import
exported = await page.evaluate(async () =>
Object.keys(await import('govuk-frontend'))
)
})

it('exports `initAll` function', async () => {
await goTo(page, '/')

const typeofInitAll = await page.evaluate((utility) => {
const namespace = 'GOVUKFrontend' in window
? window.GOVUKFrontend
: {}
await goTo(page, '/tests/boilerplate')

const typeofInitAll = await page.evaluate(async (utility) => {
const namespace = await import('govuk-frontend')
return typeof namespace[utility]
}, 'initAll')

Expand Down Expand Up @@ -52,10 +48,8 @@ describe('GOV.UK Frontend', () => {
const components = exported
.filter(method => !['initAll', 'version'].includes(method))

const componentsWithoutInitFunctions = await page.evaluate((components) => {
const namespace = 'GOVUKFrontend' in window
? window.GOVUKFrontend
: {}
const componentsWithoutInitFunctions = await page.evaluate(async (components) => {
const namespace = await import('govuk-frontend')

return components.filter(component => {
const prototype = namespace[component].prototype
Expand Down
1 change: 1 addition & 0 deletions shared/helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"devDependencies": {
"@axe-core/puppeteer": "^4.7.3",
"cheerio": "^1.0.0-rc.12",
"govuk-frontend": "*",
"govuk-frontend-config": "*",
"govuk-frontend-lib": "*",
"jest-axe": "^7.0.1",
Expand Down
22 changes: 7 additions & 15 deletions shared/helpers/puppeteer.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,8 @@ async function axe (page, overrides = {}) {
* @param {object} options - Render and initialise options
* @param {object} options.params - Nunjucks macro params
* @param {object} [options.config] - Component instantiation config
* @param {(context: { config?: object, namespace: object }) => void} [options.initialiser] - A function that'll run in the
* browser to execute arbitrary initialisation. Receives an object with the
* passed configuration as `config` and the GOVUKFrontend global as `namespace`
* @param {($module: Element) => void} [options.initialiser] - A function that'll run in the
* browser to execute arbitrary initialisation
* @returns {Promise<import('puppeteer').Page>} Puppeteer page object
*/
async function renderAndInitialise (page, componentName, options) {
Expand All @@ -92,22 +91,15 @@ async function renderAndInitialise (page, componentName, options) {
}, html)

// Run a script to init the JavaScript component
await page.evaluate((componentClassName, options) => {
const $component = document.querySelector('[data-module]')

// Check for window global
if (!('GOVUKFrontend' in window) || !window.GOVUKFrontend[componentClassName]) {
throw new Error(`Global 'window.GOVUKFrontend.${componentClassName}' not found`)
}
await page.evaluate(async (exportName, options) => {
const $module = document.querySelector('[data-module]')

if (options.initialiser) {
return options.initialiser({
config: options.config,
namespace: window.GOVUKFrontend
})
options.initialiser($module)
}

new window.GOVUKFrontend[componentClassName]($component, options.config).init()
const namespace = await import('govuk-frontend')
new namespace[exportName]($module, options.config).init()
}, componentNameToClassName(componentName), options)

return page
Expand Down
9 changes: 8 additions & 1 deletion shared/helpers/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"extends": "../../tsconfig.base.json",
"include": ["**/*.js", "**/*.mjs", "../config", "../lib"]
"include": [
"**/*.js",
"**/*.mjs",
"../config",
"../lib",
"../../packages/govuk-frontend"
],
"exclude": ["./dist/**", "../../packages/govuk-frontend/dist/**"]
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import parser from 'yargs-parser'
const parser = require('yargs-parser')

// Non-flag arguments as tasks
const { _: tasks } = parser(process.argv)

// Check for development task
export const isDev = tasks.includes('dev')
module.exports.isDev = tasks.includes('dev')
Loading

0 comments on commit 51461de

Please sign in to comment.