
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@mpt/webpack-canvas-loader
Advanced tools
Process files using the canvas api to cut, resize or apply filters on images.
Process files using the canvas api to cut, resize or apply filters on images.
npm i -D webpack-canvas-loader
const { createCanvas } = require("canvas");
// Webpack configuration:
rules: [
{
test: /\.(jpg|png)$/,
loader: "webpack-canvas-loader",
options: {
render({ image, emitJPEG, emitPNG }) {
// 'this' is the webpack loader context.
const width = 300;
const height = width / image.naturalWidth * image.naturalHeight;
const canvas = createCanvas(width, height);
const ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, width, height);
return emitJPEG(canvas, { quality: 0.9 });
}
}
}
]
// Importing an image:
import src from "./example.jpg";
const img = document.createElement("img");
img.src = src;
document.appendChild(img);
<string> - The output asset name. Default is "canvas.[contenthash].jpg|png" depending on the emit function that is used.<(context) => Promise<string>> - A function to render the image. The context object has the following properties:
<Image> - The source image object.<(canvas: Canvas, config: JpegConfig) => Promise<string>> or<(canvas: Canvas, config: PngConfig) => Promise<string>> - Emit a jpeg or png file. Returns a javascript expression that evaluates to the public path of the asset when bundled in webpack.Average image color could be used as a placeholder while an image is loading:
{
resourceQuery: /average-image-rgb/,
type: "javascript/auto",
loader: "webpack-canvas-loader",
options: {
render({ image }) {
const res = 10;
const ctx = createCanvas(res, res).getContext("2d");
ctx.drawImage(image, 0, 0, res, res);
const { data } = ctx.getImageData(0, 0, size, size);
let r = 0, g = 0, b = 0;
const points = res * res;
for (let i = 0; i < points; i++) {
r += data[i * 4];
g += data[i * 4 + 1];
b += data[i * 4 + 2];
}
return JSON.stringify(`rgb(${r / points | 0}, ${g / points | 0}, ${b / points | 0})`);
}
}
}
import average from "./image.jpg?average-image-rgb";
imagePlaceholder.style.backgroundColor = average;
In case you don't want to open up your image editing software for every new image or you want to provide individual variants for different media sizes.
In this example, the width and height is limited to a constant 1000 pixels, but you can refer to the resource query example below to make this limit configurable.
{
resourceQuery: /limit-image-size/,
type: "javascript/auto",
loader: "webpack-canvas-loader",
options: {
render({ image, emitJPEG }) {
const naturalSize = Math.max(image.naturalWidth, image.naturalHeight);
const size = Math.min(1000, naturalSize);
const width = image.naturalWidth / naturalSize * size;
const height = image.naturalHeight / naturalSize * size;
const ctx = createCanvas(width, height).getContext("2d");
ctx.drawImage(image, 0, 0, width, height);
return emitJPEG(ctx.canvas, { quality: 0.9 });
}
}
}
import url from "./image.jpg?limit-image-size";
In case you want to pass arguments to your render function, you can use the resource query.
const { parse } = require("querystring");
{
resourceQuery: /image-quality=/,
type: "javascript/auto",
loader: "webpack-canvas-loader",
options: {
render({ image, emitJPEG }) {
// Note, that "this" refers to the webpack loader context.
const query = parse(this.resourceQuery.slice(1));
const quality = query["image-quality"];
if (!(quality > 0 && quality <= 1)) {
throw new Error("Quality must be a number between 0 and 1.");
}
const ctx = createCanvas(image.naturalWidth, image.naturalHeight).getContext("2d");
ctx.drawImage(image);
return emitJPEG(ctx.canvas, { quality });
}
}
}
import url from "./image.jpg?image-quality=0.5";
FAQs
Process files using the canvas api to cut, resize or apply filters on images.
We found that @mpt/webpack-canvas-loader demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.