
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
Webpack plugin and loader in one. Use data from loaders in plugins and vice-versa.
Ploadin - Webpack PLugIN and LOADer in one. Use data from loaders in plugins and vice-versa.
Are you developing a complex plugin that needs to be used as both a plugin and a loader? ploadin got you covered:
Easily develop Webpack plugins that can access files passed through loaders.
Use instances of Ploadin subclasses both as plugins and loaders.
Plugin and loader methods share instance's state, so plugin behaviour can be modified based on data passed to loaders and vice versa.
npm install ploadin
# or
yarn add ploadin
Subclass Ploadin to create a class that can access both plugin and loader contexts.
Following example shows how to communicate between loader and plugin. Following happens in the example:
Ploadin is subclassed to PloadinSubclass so the loader and plugin methods can communicate.
Before compilation starts (and so before loaders are run),pitch data and loader behaviour are decided based on some conditions in apply.
When pitch is called, the method passes data from plugin down to other pitch methods
(Webpack docs on pitch).
When loader is called, the loader will skip its job if ignoreLoader was set to truthy.
After all is done, the state is reset in apply on compiler's afterCompile hook.
Notice that in
loaderandpitchmethods,thisrefers to thePloadininstance and notloaderContextas it is in Webpack loaders. TheloaderContextis, instead, passed as the first argument, so all other arguments are shifted by one.
// subclass.js
const { Ploadin, registerSubclass } = require('ploadin');
export class PloadinSubclass extends Ploadin {
constructor() {
this.pitchData = null;
this.ignoreLoader = false;
super();
}
// `apply` is plugin methods
apply(compiler) {
// Set data that pitch should pass on
compiler.hooks.beforeCompile.tapAsync(
'PloadinSubclass',
(stats, callback) => {
this.pitchData = { someData: compiler.xxx };
this.ignoreLoader = compiler.yyy;
callback();
},
);
// Clean up
compiler.hooks.afterCompile.tapAsync(
'SubclassPloadin',
(compilation, callback) => {
this.pitchData = null
this.ignoreLoader = false;
callback();
},
);
}
// `loader` and `pitch` are loader methods
loader(loaderContext, source, ...args) {
// Skip loader action based on some conditions
if (this.ignoreLoader) {
return source
}
// Process source here otherwise...
...
}
pitch(
loaderContext,
remainingRequest,
precedingRequest,
data
) {
// Pass data from plugin to pitch
Object.assign(data, this.pitchData);
}
}
// subclass.ts
import { Ploadin, registerSubclass } from 'ploadin';
export class PloadinSubclass extends Ploadin {
constructor() {
this.pitchData = null;
this.ignoreLoader = false;
super();
}
// `apply` is plugin methods
apply(compiler: Compiler) {
// Set data that pitch should pass on
compiler.hooks.beforeCompile.tapAsync(
'PloadinSubclass',
(stats, callback) => {
this.pitchData = { someData: compiler.xxx };
this.ignoreLoader = compiler.yyy;
callback();
},
);
// Clean up
compiler.hooks.afterCompile.tapAsync(
'SubclassPloadin',
(compilation, callback) => {
this.pitchData = null
this.ignoreLoader = false;
callback();
},
);
}
// `loader` and `pitch` are loader methods
loader(loaderContext: any, source?: string, ...args: any[]) {
// Skip loader action based on some conditions
if (this.ignoreLoader) {
return source
}
// Process source here otherwise...
...
}
pitch(
loaderContext,
remainingRequest: string,
precedingRequest: string,
data: any,
) {
// Pass data from plugin to pitch
Object.assign(data, this.pitchData);
}
}
To use as plugin, pass the instance itself as a plugin.
To use as loader, pass the asLoader property.
// webpack.config.js
const { PloadinSubclass } = require('./subclass');
const myPloadinSubclass = new PloadinSubclass();
module.exports = {
plugins: [
myPloadinSubclass,
],
module: {
rules: [
{
test: /\.js$/i, // some test
use: [
myPloadinSubclass.asLoader,
...
],
},
],
},
};
You can use multiple Ploadin subclasses, and even multiple instances of the same class, within the same config, they will not interfere.
// webpack.config.js
const { PloadinSubclass } = require('./subclass1');
const { AnotherPloadinSubclass } = require('./subclass2');
const myPloadinSubclass1 = new PloadinSubclass();
const myPloadinSubclass2 = new PloadinSubclass();
const anotherPloadin1 = new AnotherPloadinSubclass();
const anotherPloadin2 = new AnotherPloadinSubclass();
module.exports = {
plugins: [
myPloadinSubclass1,
myPloadinSubclass2,
anotherPloadin1,
anotherPloadin2
],
module: {
rules: [
{
test: /\.js$/i, // some test
use: [
myPloadinSubclass1.asLoader,
myPloadinSubclass2.asLoader,
anotherPloadin1.asLoader,
anotherPloadin2.asLoader,
...
],
},
],
},
};
TypeDoc documentation can be found here.
Ploadin class has following properties:
Loader object to be used in webpack config.
Following methods will be called if defined:
Data associated with the Ploadin class. The data returned by classOptions is
the same data (copy actually) of what is passed to registerSubclass.
Webpack plugin's apply method. See
Writing a Webpack plugin
for details.
Webpack loader's loader method. See Webpack loaders
for details.
Note that argument signature is shifted as
loaderContextis passed as first argument.this, instead, refers toPloadininstance.
Webpack loader's pitch method. See Webpack loader's pitch
for details.
Note that argument signature is shifted as
loaderContextis passed as first argument.this, instead, refers toPloadininstance.
PloadinReturns true if successfully registered, false if the class has been
registered before.
Normally, any class subclassing Ploadin is automatically registered with
instance-manager when a first instance is created. This is necessary so the
class and its instances can be looked up by indices.
You can register the class yourself. This enables you to optionally pass along options associated with the given class.
One use of this is to store options passed to class factory so we can associate the options with the dynamically-created class.
This package was prompted by the challenge of how to use and manage dynamically created Webpack plugins that need to access both loader and plugin contexts (similarly to how mini-css-extract-plugin needs access to both).
Webpack passes only JSON-serializable data to loaders, so loaders don't have direct access to plugins. And if you're dealing with dynamically-created classes, correctly matching loaders with their respective plugins gets more complicated.
This projects follows semantic versioning. The changelog can be found here.
If you want to contribute to the project or forked it, this guide will get you up and going.
This package is considered feature-complete. However, if you have ideas how it could be improved, please be sure to share it with us by opening an issue.
Contributions, issues and feature requests are welcome! Thank you ❤️
Feel free to dive in! See current issues, open an issue, or submit PRs.
How to report bugs, feature requests, and how to contribute and what conventions we use is all described in the contributing guide.
When contributing we follow the Contributor Covenant. See our Code of Conduct.
Contributions of any kind welcome. Thanks goes to these wonderful people ❤️
Generated using Hall of Fame.
Contribution type emoji legend
No additional contributors. Be the first one!
This project follows the all-contributors specification.
Give a ⭐️if this project helped you!
👤 Juro Oravec
Copyright © 2020 Juro Oravec.
This project is MIT licensed.
FAQs
Webpack plugin and loader in one. Use data from loaders in plugins and vice-versa.
The npm package ploadin receives a total of 35 weekly downloads. As such, ploadin popularity was classified as not popular.
We found that ploadin 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.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.