diff --git a/package.json b/package.json index 89b435dd..435fb010 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "favicons-webpack-plugin", - "version": "5.0.0-alpha.12", + "version": "5.0.0-alpha.13", "description": "Let webpack generate all your favicons and icons for you", "main": "src/index.js", "files": [ diff --git a/src/cache.js b/src/cache.js index 1a0a2477..c5ac7d34 100644 --- a/src/cache.js +++ b/src/cache.js @@ -20,7 +20,7 @@ const faviconCache = new WeakMap(); * * @template TResult * - * @param {string[]} absoluteFilePaths - file paths used used by the generator + * @param {string[]} absoluteFilePaths - file paths used used by the generator * @param {any} pluginInstance - the plugin instance to use as cache key * @param {boolean} useWebpackCache - Support webpack built in cache * @param {WebpackCompilation} compilation - the current webpack compilation @@ -81,7 +81,13 @@ function runCached( // Start generating the favicons const faviconsGenerationsPromise = useWebpackCache - ? runWithFileCache(absoluteFilePaths, compilation, idGenerator, eTags, generator) + ? runWithFileCache( + absoluteFilePaths, + compilation, + idGenerator, + eTags, + generator + ) : readFiles(absoluteFilePaths, compilation).then(fileContents => generator(fileContents, idGenerator(fileContents)) ); diff --git a/src/index.js b/src/index.js index 2fccc530..c1371383 100644 --- a/src/index.js +++ b/src/index.js @@ -82,7 +82,10 @@ class FaviconsWebpackPlugin { } if (typeof this.options.manifest === 'string') { - this.options.manifest = path.resolve(compiler.context, this.options.manifest); + this.options.manifest = path.resolve( + compiler.context, + this.options.manifest + ); } // Hook into the webpack compilation @@ -273,16 +276,22 @@ class FaviconsWebpackPlugin { * Generate the favicons * * @param {{content: Buffer | string, hash: string}} logo - * @param {Buffer | string} manifest + * @param {Buffer | string} baseManifest - the content of the file from options.manifest * @param {import('webpack').Compilation} compilation * @param {string} outputPath */ - generateFavicons(logo, manifest, compilation, outputPath) { + generateFavicons(logo, baseManifest, compilation, outputPath) { const resolvedPublicPath = getResolvedPublicPath( logo.hash, compilation, this.options ); + /** @type {{[key: string]: any}} - the parsed manifest from options.manifest */ + const parsedBaseManifest = + typeof this.options.manifest === 'string' + ? JSON.parse(baseManifest.toString() || '{}') + : this.options.manifest || {}; + switch (this.getCurrentCompilationMode(compilation.compiler)) { case 'light': if (!this.options.mode) { @@ -293,6 +302,7 @@ class FaviconsWebpackPlugin { return this.generateFaviconsLight( logo.content, + parsedBaseManifest, compilation, resolvedPublicPath, outputPath @@ -303,7 +313,7 @@ class FaviconsWebpackPlugin { return this.generateFaviconsWebapp( logo.content, - manifest ? JSON.parse(manifest.toString()) : this.options.manifest, + parsedBaseManifest, compilation, resolvedPublicPath, outputPath @@ -317,12 +327,14 @@ class FaviconsWebpackPlugin { * it is the default mode for development * * @param {Buffer | string} logoSource + * @param {{[key: string]: any}} baseManifest * @param {import('webpack').Compilation} compilation * @param {string} resolvedPublicPath * @param {string} outputPath */ async generateFaviconsLight( logoSource, + baseManifest, compilation, resolvedPublicPath, outputPath @@ -331,15 +343,34 @@ class FaviconsWebpackPlugin { const faviconName = `favicon${faviconExt}`; const RawSource = compilation.compiler.webpack.sources.RawSource; + const tags = [``]; + const assets = [ + { + name: path.join(outputPath, faviconName), + contents: new RawSource(logoSource, false) + } + ]; + + // If the manifest is not empty add it also to the light mode + if (Object.keys(baseManifest).length > 0) { + tags.push(''); + assets.push({ + name: path.join(outputPath, 'manifest.json'), + contents: new RawSource( + JSON.stringify(mergeManifests(baseManifest, { + icons: [{ + src: faviconName + }] + }), null, 2), + false + ) + }); + } + return { publicPath: resolvedPublicPath, - assets: [ - { - name: path.join(outputPath, faviconName), - contents: new RawSource(logoSource, false) - } - ], - tags: [``] + assets, + tags }; } diff --git a/test/manifest.light.file.test.js b/test/manifest.light.file.test.js new file mode 100644 index 00000000..52cbea96 --- /dev/null +++ b/test/manifest.light.file.test.js @@ -0,0 +1,29 @@ +const test = require('ava'); +const path = require('path'); +const fs = require('fs-extra'); +const FaviconsWebpackPlugin = require('../'); + +const { logo, generate, mkdir, snapshotCompilationAssets } = require('./util'); + +test.beforeEach(async t => (t.context.root = await mkdir())); + +test('should generate a result with custom manifest values', async t => { + const dist = path.join(t.context.root, 'dist'); + const compilationStats = await generate({ + context: t.context.root, + output: { + path: dist + }, + plugins: [ + new FaviconsWebpackPlugin({ + logo, + mode: 'light', + manifest: path.resolve(__dirname, './fixtures/manifest.json') + }) + ] + }); + + snapshotCompilationAssets(t, compilationStats); +}); + +test.afterEach(t => fs.remove(t.context.root)); diff --git a/test/manifest.light.test.js b/test/manifest.light.test.js new file mode 100644 index 00000000..3276e3b8 --- /dev/null +++ b/test/manifest.light.test.js @@ -0,0 +1,39 @@ +const test = require('ava'); +const path = require('path'); +const fs = require('fs-extra'); +const FaviconsWebpackPlugin = require('../'); + +const { logo, generate, mkdir, snapshotCompilationAssets } = require('./util'); + +test.beforeEach(async t => (t.context.root = await mkdir())); + +test('should generate a result with custom manifest values', async t => { + const dist = path.join(t.context.root, 'dist'); + const compilationStats = await generate({ + context: t.context.root, + output: { + path: dist + }, + plugins: [ + new FaviconsWebpackPlugin({ + logo, + mode: 'light', + manifest: { + name: 'FaviconsDemo', + short_name: 'FaviconsDemo', + description: 'Just a demo', + dir: 'auto', + lang: 'en', + display: 'standalone', + background_color: '#fff', + theme_color: '#fff', + orientation: null + } + }) + ] + }); + + snapshotCompilationAssets(t, compilationStats); +}); + +test.afterEach(t => fs.remove(t.context.root)); diff --git a/test/snapshots/html.false.test.js.snap b/test/snapshots/html.false.test.js.snap index dfbcee80..b9a897cf 100644 Binary files a/test/snapshots/html.false.test.js.snap and b/test/snapshots/html.false.test.js.snap differ diff --git a/test/snapshots/manifest.light.file.test.js.md b/test/snapshots/manifest.light.file.test.js.md new file mode 100644 index 00000000..de58cf46 --- /dev/null +++ b/test/snapshots/manifest.light.file.test.js.md @@ -0,0 +1,42 @@ +# Snapshot report for `test/manifest.light.file.test.js` + +The actual snapshot is saved in `manifest.light.file.test.js.snap`. + +Generated by [AVA](https://ava.li). + +## should generate a result with custom manifest values + +> Snapshot 1 + + [ + 'assets/favicon.png', + 'assets/manifest.json', + 'main.js', + ] + +> Snapshot 2 + + [ + { + assetName: 'assets/favicon.png', + content: 'png 874x989', + }, + { + assetName: 'assets/manifest.json', + content: `{␊ + "name": "FaviconsDemo",␊ + "short_name": "FaviconsDemo",␊ + "description": "A manifest used for unit-testing",␊ + "dir": "auto",␊ + "lang": "en",␊ + "display": "standalone",␊ + "background_color": "#fff",␊ + "theme_color": "#fff",␊ + "icons": [␊ + {␊ + "src": "favicon.png"␊ + }␊ + ]␊ + }`, + }, + ] diff --git a/test/snapshots/manifest.light.file.test.js.snap b/test/snapshots/manifest.light.file.test.js.snap new file mode 100644 index 00000000..1d4f6ffa Binary files /dev/null and b/test/snapshots/manifest.light.file.test.js.snap differ diff --git a/test/snapshots/manifest.light.test.js.md b/test/snapshots/manifest.light.test.js.md new file mode 100644 index 00000000..09c350a2 --- /dev/null +++ b/test/snapshots/manifest.light.test.js.md @@ -0,0 +1,42 @@ +# Snapshot report for `test/manifest.light.test.js` + +The actual snapshot is saved in `manifest.light.test.js.snap`. + +Generated by [AVA](https://ava.li). + +## should generate a result with custom manifest values + +> Snapshot 1 + + [ + 'assets/favicon.png', + 'assets/manifest.json', + 'main.js', + ] + +> Snapshot 2 + + [ + { + assetName: 'assets/favicon.png', + content: 'png 874x989', + }, + { + assetName: 'assets/manifest.json', + content: `{␊ + "name": "FaviconsDemo",␊ + "short_name": "FaviconsDemo",␊ + "description": "Just a demo",␊ + "dir": "auto",␊ + "lang": "en",␊ + "display": "standalone",␊ + "background_color": "#fff",␊ + "theme_color": "#fff",␊ + "icons": [␊ + {␊ + "src": "favicon.png"␊ + }␊ + ]␊ + }`, + }, + ] diff --git a/test/snapshots/manifest.light.test.js.snap b/test/snapshots/manifest.light.test.js.snap new file mode 100644 index 00000000..aacb2858 Binary files /dev/null and b/test/snapshots/manifest.light.test.js.snap differ diff --git a/test/snapshots/publicpath.test.js.snap b/test/snapshots/publicpath.test.js.snap index bed123ff..b0145d7e 100644 Binary files a/test/snapshots/publicpath.test.js.snap and b/test/snapshots/publicpath.test.js.snap differ diff --git a/test/snapshots/publicpathLight.test.js.snap b/test/snapshots/publicpathLight.test.js.snap index 76775676..38306034 100644 Binary files a/test/snapshots/publicpathLight.test.js.snap and b/test/snapshots/publicpathLight.test.js.snap differ