Skip to content

Commit

Permalink
Implement cache busting with an assets-manifest and hashed js/css fil…
Browse files Browse the repository at this point in the history
…e names (#137)

* implement asset manifest helper

* linter

* linter
  • Loading branch information
colegoldsmith authored May 30, 2024
1 parent 7a64518 commit 626aeb3
Show file tree
Hide file tree
Showing 9 changed files with 617 additions and 15 deletions.
21 changes: 18 additions & 3 deletions gulp.d/tasks/build-preview-pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ const { Transform } = require('stream')
const map = (transform = () => {}, flush = undefined) => new Transform({ objectMode: true, transform, flush })
const vfs = require('vinyl-fs')
const yaml = require('js-yaml')
const { execSync } = require('child_process')

const ASCIIDOC_ATTRIBUTES = { experimental: '', icons: 'font', sectanchors: '', 'source-highlighter': 'highlight.js' }

module.exports = (src, previewSrc, previewDest, sink = () => map()) => (done) =>
Promise.all([
loadSampleUiModel(previewSrc),
toPromise(
merge(compileLayouts(src), registerPartials(src), registerHelpers(src), copyImages(previewSrc, previewDest))
merge(
compileLayouts(src),
registerPartials(src),
registerHelpers(src, previewDest),
copyImages(previewSrc, previewDest)
)
),
])
.then(([baseUiModel, { layouts }]) => {
Expand Down Expand Up @@ -91,12 +97,15 @@ function registerPartials (src) {
)
}

function registerHelpers (src) {
function registerHelpers (src, previewDest) {
handlebars.registerHelper('resolvePage', resolvePage)
handlebars.registerHelper('resolvePageURL', resolvePageURL)
handlebars.registerHelper('assets-manifest', (assetPath) => assetsManifest(assetPath, previewDest))
return vfs.src('helpers/*.js', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
handlebars.registerHelper(file.stem, requireFromString(file.contents.toString()))
if (!(file.stem === 'assets-manifest')) {
handlebars.registerHelper(file.stem, requireFromString(file.contents.toString()))
}
next()
})
)
Expand All @@ -119,6 +128,12 @@ function compileLayouts (src) {
)
}

function assetsManifest (assetPath, previewDest) {
const manifestPath = execSync(`find ${previewDest} -name assets-manifest.json`).toString().trim()
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))
return manifest[assetPath]
}

function copyImages (src, dest) {
return vfs
.src('**/*.{png,svg}', { base: src, cwd: src })
Expand Down
25 changes: 21 additions & 4 deletions gulp.d/tasks/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const map = (transform) => new Transform({ objectMode: true, transform })
const through = () => map((file, enc, next) => next(null, file))
const uglify = require('gulp-uglify')
const vfs = require('vinyl-fs')
const hash = require('gulp-hash')
const tailwindconfig = require('../lib/preview.tailwind.config')

module.exports = (src, dest, preview) => () => {
Expand Down Expand Up @@ -72,20 +73,36 @@ module.exports = (src, dest, preview) => () => {
.pipe(bundle(opts))
.pipe(uglify({ output: { comments: /^! / } }))
// NOTE concat already uses stat from newest combined file
.pipe(concat('js/site.js')),
.pipe(concat('js/site.js'))
.pipe(hash({ template: '<%= name %>-<%= hash %><%= ext %>' }))
.pipe(vfs.dest(dest))
.pipe(hash.manifest('assets-manifest.json', { append: true }))
.pipe(vfs.dest(dest)),
vfs
.src('js/vendor/*([^.])?(.bundle).js', { ...opts, read: false })
.pipe(bundle(opts))
.pipe(uglify({ output: { comments: /^! / } })),
.pipe(uglify({ output: { comments: /^! / } }))
.pipe(hash({ template: '<%= name %>-<%= hash %><%= ext %>' }))
.pipe(vfs.dest(dest))
.pipe(hash.manifest('assets-manifest.json', { append: true }))
.pipe(vfs.dest(dest)),
vfs
.src('js/vendor/*.min.js', opts)
.pipe(map((file, enc, next) => next(null, Object.assign(file, { extname: '' }, { extname: '.js' })))),
.pipe(map((file, enc, next) => next(null, Object.assign(file, { extname: '' }, { extname: '.js' }))))
.pipe(hash({ template: '<%= name %>-<%= hash %><%= ext %>' }))
.pipe(vfs.dest(dest))
.pipe(hash.manifest('assets-manifest.json', { append: true }))
.pipe(vfs.dest(dest)),
// NOTE use the next line to bundle a JavaScript library that cannot be browserified, like jQuery
//vfs.src(require.resolve('<package-name-or-require-path>'), opts).pipe(concat('js/vendor/<library-name>.js')),
vfs.src('./tailwind.config.js').pipe(concat('js/tailwind.config.js')),
vfs
.src(['css/site.css', 'css/vendor/*.css'], { ...opts, sourcemaps })
.pipe(postcss((file) => ({ plugins: postcssPlugins, options: { file } }))),
.pipe(postcss((file) => ({ plugins: postcssPlugins, options: { file } })))
.pipe(hash({ template: '<%= name %>-<%= hash %><%= ext %>' }))
.pipe(vfs.dest(dest))
.pipe(hash.manifest('assets-manifest.json', { append: true }))
.pipe(vfs.dest(dest)),
vfs.src('font/*.{ttf,woff*(2)}', opts),
vfs.src('img/**/*.{gif,ico,jpg,png,svg}', opts).pipe(
preview
Expand Down
4 changes: 2 additions & 2 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

const { parallel, series, watch } = require('gulp')
const { series, watch } = require('gulp')
const createTask = require('./gulp.d/lib/create-task')
const exportTasks = require('./gulp.d/lib/export-tasks')
const log = require('fancy-log')
Expand Down Expand Up @@ -91,7 +91,7 @@ const buildPreviewPagesTask = createTask({
const previewBuildTask = createTask({
name: 'preview:build',
desc: 'Process and stage the UI assets and generate pages for the preview',
call: parallel(buildTask, buildPreviewPagesTask),
call: series(buildTask, buildPreviewPagesTask),
})

const previewServeTask = createTask({
Expand Down
Loading

0 comments on commit 626aeb3

Please sign in to comment.