Skip to content

Commit

Permalink
feat: generate custom manifest in light mode
Browse files Browse the repository at this point in the history
  • Loading branch information
jantimon committed Jan 29, 2021
1 parent 03c3514 commit db677fc
Show file tree
Hide file tree
Showing 12 changed files with 203 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": [
Expand Down
10 changes: 8 additions & 2 deletions src/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
);
Expand Down
53 changes: 42 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -293,6 +302,7 @@ class FaviconsWebpackPlugin {

return this.generateFaviconsLight(
logo.content,
parsedBaseManifest,
compilation,
resolvedPublicPath,
outputPath
Expand All @@ -303,7 +313,7 @@ class FaviconsWebpackPlugin {

return this.generateFaviconsWebapp(
logo.content,
manifest ? JSON.parse(manifest.toString()) : this.options.manifest,
parsedBaseManifest,
compilation,
resolvedPublicPath,
outputPath
Expand All @@ -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
Expand All @@ -331,15 +343,34 @@ class FaviconsWebpackPlugin {
const faviconName = `favicon${faviconExt}`;
const RawSource = compilation.compiler.webpack.sources.RawSource;

const tags = [`<link rel="icon" href="${faviconName}">`];
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('<link rel="manifest" href="manifest.json">');
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: [`<link rel="icon" href="${faviconName}">`]
assets,
tags
};
}

Expand Down
29 changes: 29 additions & 0 deletions test/manifest.light.file.test.js
Original file line number Diff line number Diff line change
@@ -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));
39 changes: 39 additions & 0 deletions test/manifest.light.test.js
Original file line number Diff line number Diff line change
@@ -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));
Binary file modified test/snapshots/html.false.test.js.snap
Binary file not shown.
42 changes: 42 additions & 0 deletions test/snapshots/manifest.light.file.test.js.md
Original file line number Diff line number Diff line change
@@ -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"␊
}␊
]␊
}`,
},
]
Binary file added test/snapshots/manifest.light.file.test.js.snap
Binary file not shown.
42 changes: 42 additions & 0 deletions test/snapshots/manifest.light.test.js.md
Original file line number Diff line number Diff line change
@@ -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"␊
}␊
]␊
}`,
},
]
Binary file added test/snapshots/manifest.light.test.js.snap
Binary file not shown.
Binary file modified test/snapshots/publicpath.test.js.snap
Binary file not shown.
Binary file modified test/snapshots/publicpathLight.test.js.snap
Binary file not shown.

0 comments on commit db677fc

Please sign in to comment.