Skip to content

Commit

Permalink
Migrate Gulp and Node.js build tasks to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
colinrotherham committed Nov 21, 2022
1 parent e72c9b0 commit b6f06dd
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 195 deletions.
1 change: 1 addition & 0 deletions config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const rootPath = dirname(__dirname)
* Config root paths
*/
const configPaths = {
root: rootPath,
src: join(rootPath, 'src'),
config: join(rootPath, 'config'),
node_modules: join(rootPath, 'node_modules'),
Expand Down
8 changes: 4 additions & 4 deletions docs/contributing/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ npm scripts are defined in `package.json`. These trigger a number of Gulp tasks.
- copy Nunjucks component template/macro files, including JSON configs
- copy GOV.UK Prototype Kit config files
- copy JavaScript ESM source files
- compile JavaScript ESM to CommonJS (`gulp js:compile`)
- compile JavaScript ESM to CommonJS
- runs `npm run test:build:package` (which will test the output is correct)

**`npm run build:dist` will do the following:**
- output files into `./dist`, or another location via the `--destination` flag
- clean the `./dist` folder
- compile JavaScript and Sass, including documentation (`gulp compile`)
- copy fonts and images (`gulp copy:assets`)
- copy fonts and images
- append version number from `package/package.json` to compiled JavaScript and CSS files
- runs `npm run test:build:dist` (which will test the output is correct)

Expand All @@ -68,14 +68,14 @@ This task will:

This task will:
- check Sass code quality via Stylelint (`npm run lint:scss`)
- compile Sass to CSS (`gulp scss:compile`) into `./public`, or another location via the `--destination` flag
- compile Sass to CSS into `./public`, or another location via the `--destination` flag
- compile Sass documentation into `./sassdoc`

**`gulp scripts`**

This task will:
- check JavaScript code quality via ESLint (`npm run lint:js`) (using JavaScript Standard Style)
- compile JavaScript ESM to CommonJS (`gulp js:compile`) into `./public`, or another location via the `--destination` flag
- compile JavaScript ESM to CommonJS into `./public`, or another location via the `--destination` flag
- compile JavaScript documentation into `./jsdoc`

**`gulp compile`**
Expand Down
47 changes: 17 additions & 30 deletions gulpfile.js → gulpfile.mjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
const { join } = require('path')
const gulp = require('gulp')
const taskListing = require('gulp-task-listing')
const configPaths = require('./config/paths.js')
const { destination } = require('./tasks/task-arguments.js')
const slash = require('slash')
import gulp from 'gulp'
import taskListing from 'gulp-task-listing'

// Gulp sub-tasks
require('./tasks/gulp/compile-assets.js')
require('./tasks/gulp/copy-to-destination.js')
require('./tasks/gulp/watch.js')
import { compileJavaScripts, compileStylesheets } from './tasks/gulp/compile-assets.mjs'
import { copyAssets, copyFiles } from './tasks/gulp/copy-to-destination.mjs'
import { watch } from './tasks/gulp/watch.mjs'

// Node tasks
const { updateDistAssetsVersion } = require('./tasks/asset-version.js')
const { updatePrototypeKitConfig } = require('./tasks/prototype-kit-config.js')
const { clean } = require('./tasks/clean.js')
const { npmScriptTask } = require('./tasks/run.js')
import { updateDistAssetsVersion } from './tasks/asset-version.mjs'
import { updatePrototypeKitConfig } from './tasks/prototype-kit-config.mjs'
import { clean } from './tasks/clean.mjs'
import { npmScriptTask } from './tasks/run.mjs'

/**
* Umbrella scripts tasks (for watch)
Expand All @@ -23,7 +19,7 @@ const { npmScriptTask } = require('./tasks/run.js')
gulp.task('scripts', gulp.series(
npmScriptTask('lint:js', ['--silent']),
npmScriptTask('build:jsdoc', ['--silent']),
'js:compile'
compileJavaScripts
))

/**
Expand All @@ -33,25 +29,16 @@ gulp.task('scripts', gulp.series(
gulp.task('styles', gulp.series(
npmScriptTask('lint:scss', ['--silent']),
npmScriptTask('build:sassdoc', ['--silent']),
'scss:compile'
compileStylesheets
))

/**
* Copy assets task
* Copies assets to taskArguments.destination (dist)
*/
gulp.task('copy:assets', () => {
return gulp.src(slash(join(configPaths.assets, '**/*')))
.pipe(gulp.dest(slash(join(destination, 'assets'))))
})

/**
* Compile task for local & heroku
* Runs JavaScript and Sass compilation, including documentation
*/
gulp.task('compile', gulp.series(
'js:compile',
'scss:compile',
compileJavaScripts,
compileStylesheets,
npmScriptTask('build:jsdoc', ['--silent']),
npmScriptTask('build:sassdoc', ['--silent'])
))
Expand All @@ -63,7 +50,7 @@ gulp.task('compile', gulp.series(
gulp.task('dev', gulp.series(
clean,
'compile',
'watch',
watch,
npmScriptTask('serve', ['--silent', '--workspace', 'app'])
))

Expand All @@ -73,8 +60,8 @@ gulp.task('dev', gulp.series(
*/
gulp.task('build:package', gulp.series(
clean,
'copy:files',
'js:compile',
copyFiles,
compileJavaScripts,
updatePrototypeKitConfig
))

Expand All @@ -85,7 +72,7 @@ gulp.task('build:package', gulp.series(
gulp.task('build:dist', gulp.series(
clean,
'compile',
'copy:assets',
copyAssets,
updateDistAssetsVersion
))

Expand Down
18 changes: 7 additions & 11 deletions tasks/asset-version.js → tasks/asset-version.mjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const { rename, writeFile } = require('fs/promises')
const { basename, join } = require('path')
const { EOL } = require('os')
import { readFile, rename, writeFile } from 'fs/promises'
import { basename, join } from 'path'
import { EOL } from 'os'

const configPaths = require('../config/paths.js')
const { destination, isDist } = require('./task-arguments.js')
import configPaths from '../config/paths.js'
import { destination, isDist } from './task-arguments.mjs'

// Update assets' version numbers
// Uses the version number from `package/package.json` and writes it to various places
async function updateDistAssetsVersion () {
const pkg = require(join(configPaths.package, 'package.json'))
export async function updateDistAssetsVersion () {
const pkg = JSON.parse(await readFile(join(configPaths.package, 'package.json'), 'utf8'))

if (!isDist) {
throw new Error('Asset versions can only be applied to ./dist')
Expand Down Expand Up @@ -38,7 +38,3 @@ async function updateDistAssetsVersion () {
}

updateDistAssetsVersion.displayName = 'update-dist-assets-version'

module.exports = {
updateDistAssetsVersion
}
20 changes: 8 additions & 12 deletions tasks/clean.js → tasks/clean.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const { basename, join } = require('path')
const del = require('del')
const slash = require('slash')
import { basename, join } from 'path'
import del from 'del'
import slash from 'slash'

import { destination } from './task-arguments.mjs'

const { destination } = require('./task-arguments.js')
const cleanPath = slash(destination)

function paths () {
export function paths (cleanPath) {
const param = [slash(join(cleanPath, '**/*'))]

// Preserve package files
Expand All @@ -21,13 +22,8 @@ function paths () {
return param
}

function clean () {
return del(paths())
export function clean () {
return del(paths(cleanPath))
}

clean.displayName = `clean:${basename(cleanPath)}`

module.exports = {
paths,
clean
}
12 changes: 4 additions & 8 deletions tasks/clean.unit.test.js → tasks/clean.unit.test.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
describe('Clean task', () => {
beforeEach(() => {
jest.resetModules()
})
import { paths } from './clean.mjs'

describe('Clean task', () => {
it.each(
[
{
Expand All @@ -28,9 +26,7 @@ describe('Clean task', () => {
paths: ['custom/location/here/**/*']
}
]
)('cleans destination "$destination"', async ({ destination: mockDestination, paths }) => {
jest.mock('./task-arguments.js', () => ({ destination: mockDestination }))
const clean = await import('./clean.js')
expect(clean.paths()).toEqual(paths)
)('cleans destination "$destination"', async ({ destination, paths: pathsExpected }) => {
expect(paths(destination)).toEqual(pathsExpected)
})
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const { readFile } = require('fs/promises')
const { join } = require('path')
import { readFile } from 'fs/promises'
import { join } from 'path'

const configPaths = require('../../../config/paths.js')
const { getListing } = require('../../../lib/file-helper')
import configPaths from '../../../config/paths.js'
import { getListing } from '../../../lib/file-helper.js'

describe('dist/', () => {
const pkg = require(join(configPaths.package, 'package.json'))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const { readFile } = require('fs/promises')
const { join } = require('path')
import { readFile } from 'fs/promises'
import { join } from 'path'

const configPaths = require('../../../config/paths.js')
const { filterPath, getDirectories, getListing, mapPathTo } = require('../../../lib/file-helper')
const { componentNameToJavaScriptClassName, componentNameToJavaScriptModuleName } = require('../../../lib/helper-functions')
import configPaths from '../../../config/paths.js'
import { filterPath, getDirectories, getListing, mapPathTo } from '../../../lib/file-helper.js'
import { componentNameToJavaScriptClassName, componentNameToJavaScriptModuleName } from '../../../lib/helper-functions.js'

const { renderSass } = require('../../../lib/jest-helpers')
import { renderSass } from '../../../lib/jest-helpers.js'

describe('package/', () => {
let listingSource
Expand Down
69 changes: 40 additions & 29 deletions tasks/gulp/compile-assets.js → tasks/gulp/compile-assets.mjs
Original file line number Diff line number Diff line change
@@ -1,42 +1,47 @@
const { getListing } = require('../../lib/file-helper')
const { componentNameToJavaScriptModuleName } = require('../../lib/helper-functions')

const { join, parse } = require('path')

const gulp = require('gulp')
const sass = require('gulp-sass')(require('node-sass'))
const plumber = require('gulp-plumber')
const postcss = require('gulp-postcss')
const rollup = require('gulp-better-rollup')
const gulpif = require('gulp-if')
const uglify = require('gulp-uglify')
const minimatch = require('minimatch')
const merge = require('merge-stream')
const rename = require('gulp-rename')
const slash = require('slash')

const configPaths = require('../../config/paths.js')
const { destination, isDist, isPackage } = require('../task-arguments.js')
import { getListing } from '../../lib/file-helper.js'
import { componentNameToJavaScriptModuleName } from '../../lib/helper-functions.js'

import { join, parse } from 'path'

import gulp from 'gulp'
import gulpSass from 'gulp-sass'
import nodeSass from 'node-sass'
import plumber from 'gulp-plumber'
import postcss from 'gulp-postcss'
import rollup from 'gulp-better-rollup'
import gulpif from 'gulp-if'
import uglify from 'gulp-uglify'
import minimatch from 'minimatch'
import merge from 'merge-stream'
import rename from 'gulp-rename'
import slash from 'slash'

import configPaths from '../../config/paths.js'
import { destination, isDist, isPackage } from '../task-arguments.mjs'

const sass = gulpSass(nodeSass)

/**
* Compile Sass to CSS task
*
* @returns {import('stream').Stream} Output file stream
*/
gulp.task('scss:compile', function () {
export function compileStylesheets () {
const destPath = isPackage
? join(destination, 'govuk')
: destination

// Release distribution
if (isDist) {
return merge(
compileStyles(
compileStylesheet(
gulp.src(`${slash(configPaths.src)}/govuk/all.scss`)
.pipe(rename({
basename: 'govuk-frontend',
extname: '.min.css'
}))),

compileStyles(
compileStylesheet(
gulp.src(`${slash(configPaths.src)}/govuk/all-ie8.scss`)
.pipe(rename({
basename: 'govuk-frontend-ie8',
Expand All @@ -48,23 +53,25 @@ gulp.task('scss:compile', function () {

// Review application
return merge(
compileStyles(
compileStylesheet(
gulp.src(`${slash(configPaths.app)}/assets/scss/app?(-ie8).scss`)),

compileStyles(
compileStylesheet(
gulp.src(`${slash(configPaths.app)}/assets/scss/app-legacy?(-ie8).scss`), {
includePaths: ['node_modules/govuk_frontend_toolkit/stylesheets', 'node_modules']
}),

compileStyles(
compileStylesheet(
gulp.src(`${slash(configPaths.fullPageExamples)}/**/styles.scss`)
.pipe(rename((path) => {
path.basename = path.dirname
path.dirname = 'full-page-examples'
})))
)
.pipe(gulp.dest(slash(destPath)))
})
}

compileStylesheets.displayName = 'compile:scss'

/**
* Compile Sass to CSS helper
Expand All @@ -73,7 +80,7 @@ gulp.task('scss:compile', function () {
* @param {import('node-sass').Options} [options] - Sass options
* @returns {import('stream').Stream} Output file stream
*/
function compileStyles (stream, options = {}) {
function compileStylesheet (stream, options = {}) {
return stream
.pipe(plumber((error) => {
console.error(error.message)
Expand All @@ -88,8 +95,10 @@ function compileStyles (stream, options = {}) {

/**
* Compile JavaScript ESM to CommonJS task
*
* @returns {Promise<import('stream').Stream>} Output file stream
*/
gulp.task('js:compile', async () => {
export async function compileJavaScripts () {
const destPath = isPackage
? join(destination, 'govuk')
: destination
Expand Down Expand Up @@ -136,4 +145,6 @@ gulp.task('js:compile', async () => {
}))
.pipe(gulp.dest(slash(join(destPath, modulePath))))
}))
})
}

compileJavaScripts.displayName = 'compile:js'
Loading

0 comments on commit b6f06dd

Please sign in to comment.