Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding an option to append a content hash to the end of font files for cache-busting on glyph changes #51

Merged
merged 10 commits into from
Nov 23, 2021
30 changes: 29 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const log = require('debug')('fontmin-webpack')

const _ = require('lodash')
Expand Down Expand Up @@ -27,6 +28,7 @@ class FontminPlugin {
autodetect: true,
allowedFilesRegex: null,
skippedFilesRegex: null,
appendHash: false,
},
options,
)
Expand Down Expand Up @@ -189,6 +191,7 @@ class FontminPlugin {
onAdditionalAssets(compilation) {
const allowedFiles = this._options.allowedFilesRegex
const skippedFiles = this._options.skippedFilesRegex
const appendHash = this._options.appendHash
const fontFiles = this.findFontFiles(compilation)
const glyphsInCss = this.findUnicodeGlyphs(compilation)
log(`found ${glyphsInCss.length} glyphs in CSS`)
Expand Down Expand Up @@ -219,13 +222,38 @@ class FontminPlugin {
.then(files => {
files.forEach(file => {
if (file.buffer.length > file.minified.length) {
compilation.assets[file.asset] = new RawSource(file.minified)
if (appendHash) {
const newAssetName = this.appendMinifiedFileHash(file)
compilation.assets[newAssetName] = new RawSource(file.minified)
this.hashifyFontReferences(file.asset, newAssetName, compilation.assets)
delete compilation.assets[file.asset]
} else {
compilation.assets[file.asset] = new RawSource(file.minified)
}
}
})
})
}, Promise.resolve())
}

appendMinifiedFileHash(file) {
const fileHash = crypto.createHash('md5').update(file.minified).digest('hex')
return file.asset.split('.').join(`-${fileHash}.`)
}

hashifyFontReferences(oldAssetName, newAssetName, assets) {
Object.keys(assets).forEach(
asset => {
const oldAssetNameRegex = new RegExp(oldAssetName.replace('.', '\\.'), 'g')
const assetSource = assets[asset].source().toString()

if (assetSource.match(oldAssetNameRegex)) {
assets[asset] = new RawSource(assetSource.replace(oldAssetNameRegex, newAssetName))
}
}
)
}

apply(compiler) {
compiler.hooks.thisCompilation.tap('FontminPlugin', compilation => {
compilation.hooks.additionalAssets.tapPromise('FontminPlugin', () => {
Expand Down
15 changes: 15 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,19 @@ describe('FontminPlugin', () => {
expect(svg.stats.size).to.be.equal(svgOriginal.stats.size)
})
})

describe('FontAwesome with appendHash option', () => {
it('should run successfully', function (done) {
this.timeout(60000)
const plugin = new Plugin({appendHash: true})
const config = _.cloneDeep(baseConfig)
testWithConfig(_.assign(config, {plugins: [plugin]}), done)
})

it('should append the hash to the ends of all refrences in all assets', () => {
const out = fs.readFileSync(DIST_FOLDER + '/out.js').toString()
fontStats.forEach(file => expect(out.match(file.filename)).to.be.ok)
fontStats.forEach(file => expect(out.match(file.filename.replace(/-([a-z]|[0-9])+\./, '.'))).to.not.be.ok)
})
})
})