UNPKG

@tech-wizards/favicons-webpack-plugin

Version:

Let webpack generate all your favicons and icons for you

119 lines (112 loc) 4.71 kB
'use strict'; var path = require('path'); var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); module.exports.compileTemplate = function compileTemplate (options, context, compilation) { // The entry file is just an empty helper as the dynamic template // require is added in "loader.js" var outputOptions = { filename: options.statsFilename, publicPath: compilation.outputOptions.publicPath }; // Create an additional child compiler which takes the template // and turns it into an Node.JS html factory. // This allows us to use loaders during the compilation var compilerName = getCompilerName(context, outputOptions.filename); var childCompiler = compilation.createChildCompiler(compilerName, outputOptions); childCompiler.context = context; var singleEntryPlugin = new SingleEntryPlugin(context, '!!' + require.resolve('./favicons.js') + '?' + JSON.stringify({ outputFilePrefix: options.prefix, icons: options.icons, background: options.background, persistentCache: options.persistentCache, appName: options.title }) + '!' + options.logo); (compilation.hooks ? singleEntryPlugin.apply(childCompiler) : childCompiler.apply(singleEntryPlugin)); // Fix for "Uncaught TypeError: __webpack_require__(...) is not a function" // Hot module replacement requires that every child compiler has its own // cache. @see https://github.com/ampedandwired/html-webpack-plugin/pull/179 // (webpack 4 compliant + back compat) (childCompiler.hooks ? childCompiler.hooks.compilation.tap.bind(childCompiler.hooks.compilation, 'FaviconsWebpackPluginCompilation') : childCompiler.plugin.bind(childCompiler, 'compilation') )((compilation) => { if (compilation.cache) { if (!compilation.cache[compilerName]) { compilation.cache[compilerName] = {}; } compilation.cache = compilation.cache[compilerName]; } (compilation.hooks ? compilation.hooks.optimizeChunkAssets.tapAsync.bind(compilation.hooks.optimizeChunkAssets, 'FaviconsWebpackPluginOptimizeChunkAssets') : compilation.plugin.bind(compilation, 'optimize-chunk-assets') )((chunks, callback) => { if (!chunks[0]) { return callback(compilation.errors[0] || 'Favicons generation failed'); } var resultFile = chunks[0].files[0]; var resultCode = compilation.assets[resultFile].source(); var resultJson; try { /* eslint no-eval:0 */ var result = eval(resultCode); resultJson = JSON.stringify(result); } catch (e) { return callback(e); } compilation.assets[resultFile] = { source: function () { return resultJson; }, size: function () { return resultJson.length; } }; callback(null); }); }); // Compile and return a promise return new Promise(function (resolve, reject) { childCompiler.runAsChild(function (err, entries, childCompilation) { if (err) { return reject(err); } // Replace [hash] placeholders in filename // In webpack 4 the plugin interface changed, so check for available fns var outputName = compilation.mainTemplate.getAssetPath ? compilation.mainTemplate.hooks.assetPath.call(outputOptions.filename, { hash: childCompilation.hash, chunk: entries[0] }) : compilation.mainTemplate.applyPluginsWaterfall( 'asset-path', outputOptions.filename, { hash: childCompilation.hash, chunk: entries[0] }); // Resolve / reject the promise if (childCompilation && childCompilation.errors && childCompilation.errors.length) { var errorDetails = childCompilation.errors.map(function (error) { return error.message + (error.error ? ':\n' + error.error : ''); }).join('\n'); reject(new Error('Child compilation failed:\n' + errorDetails)); } else if (err) { reject(err); } else { resolve({ outputName: outputName, stats: JSON.parse(childCompilation.assets[outputName].source()) }); } }); }); }; /** * Returns the child compiler name e.g. 'html-webpack-plugin for "index.html"' */ function getCompilerName (context, filename) { var absolutePath = path.resolve(context, filename); var relativePath = path.relative(context, absolutePath); return 'favicons-webpack-plugin for "' + (absolutePath.length < relativePath.length ? absolutePath : relativePath) + '"'; }