Skip to content

Instantly share code, notes, and snippets.

@i-like-robots
Last active May 6, 2020 14:09
Show Gist options
  • Save i-like-robots/9a460b55bcc34a38866b9cc163787639 to your computer and use it in GitHub Desktop.
Save i-like-robots/9a460b55bcc34a38866b9cc163787639 to your computer and use it in GitHub Desktop.
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const defaultOptions = {
basePath: './client/',
globPattern: '**/*.{png,jpg,jpeg,gif,webp,ico}'
};
class PageKitImagesPlugin {
constructor(options = {}) {
this.options = { ...defaultOptions, ...options };
}
apply(compiler) {
const isDevMode = compiler.options.mode === 'development';
// Maintain the path rather than flattening everything in case images have duplicate names
const outputFileName = isDevMode ? '[path][name].[ext]' : '[path][name].[contenthash:12].[ext]';
new CopyPlugin([
{
from: path.join(this.options.basePath, this.options.globPattern),
to: outputFileName,
transformPath: (targetPath) => {
// This removes the base path because we don't expect that to be there
return path.relative(this.options.basePath, targetPath);
}
}
]).apply(compiler);
}
}
module.exports = { PageKitImagesPlugin };
// This is intended to replace the use of the webpack-assets-manifest plugin which does not output all assets, e.g.
// those moved around by the copy plugin or pulled in.
//
// Although webpack-manifest-plugin does not output entrypoints like webpack-assets-manifest it does make the data
// available via its custom generator function.
const ManifestPlugin = require('webpack-manifest-plugin');
function groupFilesByType(files) {
const output = {};
files.forEach((file) => {
// remove the dot prefix
const extension = path.extname(file).slice(1);
if (Array.isArray(output[ext])) {
output[extension].push(file);
} else {
output[extension] = [ file ];
}
})
return output;
}
function createEntrypoints(entrypoints) {
const output = {};
for (const [ name, files ] of Object.entries(entrypoints)) {
output[name] = groupFilesByType(files);
}
return output;
}
class PageKitManifestPlugin {
constructor(options = {}) {
this.options = { ...defaultOptions, ...options };
}
apply(compiler) {
new ManifestPlugin({
generate: (manifest, files, entrypoints) => {
for (const { name, path } of files) {
manifest[name] = path;
}
manifest.entrypoints = createEntrypoints(entrypoints);
return manifest;
}
}).apply(compiler);
}
}
module.exports = { PageKitManifestPlugin };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment