@lipemat/js-boilerplate
Version:
Dependencies and scripts for a no config JavaScript app
81 lines (74 loc) • 2.06 kB
JavaScript
const crypto = require( 'node:crypto' );
const {Compilation, Compiler} = require( 'webpack' );
const WebpackAssetsManifest = require( 'webpack-assets-manifest' );
/**
* Webpack plugin for injecting the content hash into
* the manifest.json created by the `webpack-assets-manifest` plugin.
*
*
*/
class WebpackAssetsHash {
/**
* Pass the same constructed plugin provide to Webpack via
* the `webpack.dist` script.
*
* @param {WebpackAssetsManifest} manifest
*/
constructor( manifest ) {
this.assets = {};
this.manifest = manifest;
}
/**
* WebPack plugin entrypoint.
*
* @link https://webpack.js.org/contribute/writing-a-plugin/
*
* @param {Compiler} compiler
*/
apply( compiler ) {
this.manifest.hooks.transform.tap( 'WebpackAssetsHash', this.addHashToManifest.bind( this ) );
compiler.hooks.thisCompilation.tap( 'WebpackAssetsHash', compilation => {
compilation.hooks.processAssets.tap(
{
name: 'WebpackAssetsHash',
stage: Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
},
this.storeContentHash.bind( this, compilation ),
);
} );
}
/**
* Store the content hash of each asset in this class, so we
* can inject it into the manifest.json file.
*
* Hash matches Webpack [contenthash].
*
* @param {Compilation} compilation
*/
storeContentHash( compilation ) {
for ( const asset of compilation.getAssets() ) {
this.assets[ asset.name ] = crypto.createHash( 'md5' )
.update( asset.source.source() )
.digest( 'hex' )
.substring( 0, 20 );
}
}
/**
* Inject the `hash` of the content into the manifest.json
* file generated by webpack-assets-manifest.
*
* @param {Object} assets
*/
addHashToManifest( assets ) {
Object.keys( assets ).forEach( item => {
if ( this.assets[ item ] ) {
assets[ item ].hash = this.assets[ item ];
} else {
// If the content hash was added to the asset name prior to storing.
assets[ item ].hash = this.assets[ assets[ item ].src ];
}
} );
return assets;
}
}
module.exports = WebpackAssetsHash;