import fs from 'fs' ; import path from 'path' ; import type HtmlWebpackPlugin from 'html-webpack-plugin' ; import { Compiler , Compilation , sources } from 'webpack' ; export class AppIconPlugin { htmlWebpackPlugin : typeof HtmlWebpackPlugin ; iconPath : string ; name : string ; constructor ( htmlWebpackPlugin , iconPath ) { this . htmlWebpackPlugin = htmlWebpackPlugin ; this . iconPath = iconPath ; this . name = 'app-icon' ; } apply ( compiler ) { const { publicPath } = compiler . options . output ; const iconName = path . basename ( this . iconPath ) ; compiler . hooks . compilation . tap ( this . name , ( compilation ) => { this . htmlWebpackPlugin . getHooks ( compilation ) . alterAssetTagGroups . tap ( this . name , data => { data . headTags . unshift ( { tagName : 'link' , voidTag : true , attributes : { rel : 'apple-touch-icon' , sizes : '180*180' , href : `${ publicPath as string }${ iconName }` , } , meta : { } , } ) ; return data ; } ) ; } ) ; compiler . hooks . thisCompilation . tap ( 'app-icon' , ( compilation ) => { compilation . hooks . processAssets . tap ( { name : 'app-icon' , stage : Compilation . PROCESS_ASSETS_STAGE_PRE_PROCESS , } , assets => { const source = fs . readFileSync ( this . iconPath ) ; assets [ iconName ] = new sources . RawSource ( source , false ) ; } ) ; } ) ; } }