Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Webpack additional compilation pass
const PLUGIN_NAME = 'MY_WEBPACK_PLUGIN';
class MyWebpackPlugin {
constructor() {
this.cssReady = false;
this.cssFiles = [];
}
apply(compiler) {
compiler.hooks.watchRun.tap(PLUGIN_NAME, () => {
this.cssReady = false;
});
compiler.hooks.compilation.tap(
PLUGIN_NAME,
(compilation, { normalModuleFactory }) => {
// copied from DefinePlugin
compilation.dependencyFactories.set(ConstDependency, new NullFactory());
compilation.dependencyTemplates.set(
ConstDependency,
new ConstDependency.Template()
);
const handler = parser => {
parser.hooks.expression
.for('CSS_FILES')
.tap(PLUGIN_NAME, expr => {
return ParserHelpers.toConstantDependency(
parser,
JSON.stringify(this.cssFiles)
)(expr);
});
};
normalModuleFactory.hooks.parser
.for('javascript/auto')
.tap(PLUGIN_NAME, handler);
normalModuleFactory.hooks.parser
.for('javascript/dynamic')
.tap(PLUGIN_NAME, handler);
normalModuleFactory.hooks.parser
.for('javascript/esm')
.tap(PLUGIN_NAME, handler);
// END copied from DefinePlugin
compilation.hooks.needAdditionalPass.tap(PLUGIN_NAME, () => {
if (!this.cssReady) {
this.cssReady = true;
return true;
}
});
}
);
compiler.hooks.emit.tap(PLUGIN_NAME, compilation => {
if (!this.cssReady) {
this.cssFiles = Object.keys(compilation.assets)
.filter(file => file.endsWith('.css'))
.map(file => compilation.options.output.publicPath + file);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment