Skip to content

Commit

Permalink
Merge pull request #1152 from nhsuk/source-maps
Browse files Browse the repository at this point in the history
Output source maps and use minified code in examples
  • Loading branch information
colinrotherham authored Feb 20, 2025
2 parents b435457 + 8fa840c commit d42bfa7
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 62 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

:new: **New features**

- Output source maps and use minified code in examples ([PR 1152](https://github.com/nhsuk/nhsuk-frontend/pull/1152))

:wrench: **Fixes**

We've configured our build tasks to use [Browserslist](https://browsersl.ist) for browser compatibility. This change was introduced in [pull request #1135: Configure Browserslist for build tooling](https://github.com/nhsuk/nhsuk-frontend/issues/1135)
Expand Down
4 changes: 2 additions & 2 deletions app/_templates/layout.njk
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<link type="font/woff2" href="https://assets.nhs.uk/fonts/FrutigerLTW01-55Roman.woff2" rel="preload" as="font" crossorigin>
<link type="font/woff2" href="https://assets.nhs.uk/fonts/FrutigerLTW01-65Bold.woff2" rel="preload" as="font" crossorigin>

<link href="{{ baseUrl }}assets/nhsuk.css" rel="stylesheet">
<link href="{{ baseUrl }}stylesheets/nhsuk-{{ version }}.min.css" rel="stylesheet">

<script src="{{ baseUrl }}assets/nhsuk.js" defer></script>
<script src="{{ baseUrl }}javascripts/nhsuk-{{ version }}.min.js" defer></script>

<link rel="shortcut icon" href="{{ baseUrl }}assets/favicons/favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="{{ baseUrl }}assets/favicons/apple-touch-icon-180x180.png">
Expand Down
8 changes: 4 additions & 4 deletions docs/contributing/tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ To run a gulp task, run `npx gulp <task_name>` on the command line.
| task | action |
| ------------ | ---------------------------------------------------------------------- |
| `default` | Serve the documentation on port 3000. Recompile when there are changes |
| `style` | Compiles CSS |
| `build` | Compiles CSS and JS |
| `bundle` | Creates distributable CSS and JS files in `dist/` |
| `style` | Compiles CSS only, including minified files in `dist/` |
| `script` | Compiles JS only, including minified files in `dist/` |
| `build` | Deletes `dist/` contents then runs `style` and `script` |
| `zip` | Creates a distributable zip file in `dist/` |
| `watch` | Recompile distributables when there are changes |
| `watch` | Runs `style` and `script` when there are changes |
| `docs:build` | Recompile documentation |
| `docs:watch` | Recompile documentation when there are changes |
| `docs:serve` | Serve documentation on port 3000 |
Expand Down
159 changes: 111 additions & 48 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
const { join, relative } = require('path')
const { cwd } = require('process')
const { Transform } = require('stream')
const { fileURLToPath } = require('url')

const autoprefixer = require('autoprefixer')
const cssnano = require('cssnano')
const gulp = require('gulp')
const postcss = require('gulp-postcss')
const rename = require('gulp-rename')
const gulpSass = require('gulp-sass')
const terser = require('gulp-terser')
const PluginError = require('plugin-error')
const dartSass = require('sass')
const webpack = require('webpack-stream')

Expand Down Expand Up @@ -35,38 +41,81 @@ const sass = gulpSass(dartSass)
/* Build the CSS from source */
function compileCSS(done) {
return gulp
.src(['packages/nhsuk.scss'])
.pipe(sass().on('error', done))
.src(['packages/nhsuk.scss'], {
sourcemaps: true
})
.pipe(
sass({
sourceMap: true,
sourceMapIncludeSources: true
}).on('error', (error) => {
done(
new PluginError('compileCSS', error.messageFormatted, {
showProperties: false
})
)
})
)
.pipe(
new Transform({
objectMode: true,

// Make source file:// paths relative
transform(file, enc, cb) {
if (file.sourceMap?.sources) {
file.sourceMap.sources = file.sourceMap.sources.map((path) =>
relative(join(cwd(), 'dist'), fileURLToPath(path))
)
}

cb(null, file)
}
})
)
.pipe(postcss([autoprefixer()]))
.pipe(gulp.dest('dist/'))
.pipe(
gulp.dest('dist/', {
sourcemaps: '.'
})
)
}

/* Minify CSS and add a min.css suffix */
function minifyCSS() {
return gulp
.src([
'dist/*.css',
'!dist/*.min.css' // don't re-minify minified css
])
.src(
[
'dist/*.css',
'!dist/*.min.css' // don't re-minify minified css
],
{ sourcemaps: true }
)
.pipe(postcss([cssnano()]))
.pipe(
rename({
suffix: `-${version}.min`
})
)
.pipe(gulp.dest('dist/'))
.pipe(
gulp.dest('dist/', {
sourcemaps: '.'
})
)
}

/**
* JavaScript tasks
*/

/* Use Webpack to build and minify the NHS.UK components JS. */
function webpackJS() {
function webpackJS(done) {
return gulp
.src('./packages/nhsuk.js')
.src('./packages/nhsuk.js', {
sourcemaps: true
})
.pipe(
webpack({
devtool: 'source-map',
mode: 'production',
module: {
rules: [
Expand All @@ -84,24 +133,49 @@ function webpackJS() {
minimize: false // minification is handled by terser
},
output: {
filename: 'nhsuk.js'
filename: 'nhsuk.js',

// Make source webpack:// paths relative
devtoolModuleFilenameTemplate(info) {
return relative(join(cwd(), 'dist'), info.absoluteResourcePath)
}
},
stats: {
colors: true,
errors: false
},
target: 'browserslist'
}).on('error', (error) => {
done(
new PluginError('webpackJS', error, {
showProperties: false
})
)
})
)
.pipe(
gulp.dest('./dist', {
sourcemaps: '.'
})
)
.pipe(gulp.dest('./dist'))
}

/* Minify the JS file for release */
function minifyJS() {
return gulp
.src([
'dist/*.js',
'!dist/*.min.js' // don't re-minify minified javascript
])
.src(
[
'dist/*.js',
'!dist/*.min.js' // don't re-minify minified javascript
],
{ sourcemaps: true }
)
.pipe(
terser({
format: { comments: false },
sourceMap: {
includeSources: true
},

// Compatibility workarounds
ecma: 5,
Expand All @@ -110,23 +184,14 @@ function minifyJS() {
)
.pipe(
rename({
suffix: '.min'
suffix: `-${version}.min`
})
)
.pipe(gulp.dest('dist/'))
}

/* Version the JS file for release */
function versionJS() {
return gulp
.src('dist/nhsuk.min.js')
.pipe(
rename({
basename: `nhsuk-${version}`,
extname: '.min.js'
gulp.dest('dist/', {
sourcemaps: '.'
})
)
.pipe(gulp.dest('dist/'))
}

/**
Expand All @@ -148,25 +213,30 @@ function assets() {

/* Copy JS files into their relevant folders */
function jsFolder() {
return gulp
.src('dist/*.min.js', { ignore: 'dist/nhsuk.min.js' })
.pipe(gulp.dest('dist/js/'))
return gulp.src('dist/*.min.{js,js.map}').pipe(gulp.dest('dist/js/'))
}

/* Copy CSS files into their relevant folders */

function cssFolder() {
return gulp.src('dist/*.min.css').pipe(gulp.dest('dist/css/'))
return gulp.src('dist/*.min.{css,css.map}').pipe(gulp.dest('dist/css/'))
}

async function createZip() {
const { default: zip } = await import('gulp-zip')

return gulp
.src(['dist/css/*.min.css', 'dist/js/*.min.js', 'dist/assets/**'], {
base: 'dist',
encoding: false
})
.src(
[
'dist/css/*.min.{css,css.map}',
'dist/js/*.min.{js,js.map}',
'dist/assets/**'
],
{
base: 'dist',
encoding: false
}
)
.pipe(zip(`nhsuk-frontend-${version}.zip`))
.pipe(gulp.dest('dist'))
}
Expand All @@ -183,17 +253,10 @@ gulp.task('clean:zip', async () => {
return clean(['dist/{assets,css,js}', 'dist/*.zip'])
})

gulp.task('style', compileCSS)
gulp.task('style', gulp.series([compileCSS, minifyCSS]))
gulp.task('script', gulp.series([webpackJS, minifyJS]))

gulp.task(
'build',
gulp.series(['clean', gulp.parallel([compileCSS, webpackJS])])
)

gulp.task(
'bundle',
gulp.series(['build', gulp.parallel([minifyCSS, minifyJS]), versionJS])
)
gulp.task('build', gulp.series(['clean', gulp.parallel(['style', 'script'])]))

gulp.task(
'zip',
Expand All @@ -206,8 +269,8 @@ gulp.task(

gulp.task('watch', () =>
Promise.all([
gulp.watch(['packages/**/*.scss'], compileCSS),
gulp.watch(['packages/**/*.js'], webpackJS)
gulp.watch(['packages/**/*.scss'], gulp.series(['style'])),
gulp.watch(['packages/**/*.js'], gulp.series(['script']))
])
)

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"node": ">=20.0.0"
},
"scripts": {
"build": "gulp bundle docs:build --color --series",
"build": "gulp build docs:build --color --series",
"prestart": "npm run build",
"start": "gulp --color",
"lint": "npm run lint:js && npm run lint:css && npm run lint:prettier",
Expand Down
16 changes: 9 additions & 7 deletions tasks/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const nunjucks = require('nunjucks')
const PluginError = require('plugin-error')

const validatorConfig = require('../.htmlvalidate')
const { version } = require('../package.json')

/**
* Compile Nunjucks into HTML
Expand All @@ -29,7 +30,8 @@ async function buildHTML() {
const { name, dir } = parse(path)

const html = env.render(path, {
baseUrl: '/nhsuk-frontend/'
baseUrl: '/nhsuk-frontend/',
version
})

const destPath = join('dist/app', dir)
Expand Down Expand Up @@ -71,8 +73,8 @@ async function validateHTML() {
*/
function copyCSS() {
return gulp
.src('dist/*.css')
.pipe(gulp.dest('dist/app/assets'))
.src('dist/*.min.{css,css.map}')
.pipe(gulp.dest('dist/app/stylesheets'))
.pipe(browserSync.stream())
}

Expand All @@ -81,8 +83,8 @@ function copyCSS() {
*/
function copyJS() {
return gulp
.src('dist/*.js')
.pipe(gulp.dest('dist/app/assets'))
.src('dist/*.min.{js,js.map}')
.pipe(gulp.dest('dist/app/javascripts'))
.pipe(browserSync.stream())
}

Expand Down Expand Up @@ -137,8 +139,8 @@ gulp.task('docs:watch', () =>
Promise.all([
gulp.watch(['app/**/*.njk'], buildHTML),
gulp.watch(['dist/**/*.html']).on('change', browserSync.reload),
gulp.watch(['dist/*.css'], copyCSS),
gulp.watch(['dist/*.js'], copyJS),
gulp.watch(['dist/*.min.{css,css.map}'], copyCSS),
gulp.watch(['dist/*.min.{js,js.map}'], copyJS),
gulp.watch(['packages/assets/**/*'], copyBinaryAssets)
])
)
Expand Down

0 comments on commit d42bfa7

Please sign in to comment.