Skip to content

Instantly share code, notes, and snippets.

@bebraw
Created March 26, 2018 15:13
Show Gist options
  • Save bebraw/19482ac8de5e06068c65e1ee648f9b96 to your computer and use it in GitHub Desktop.
Save bebraw/19482ac8de5e06068c65e1ee648f9b96 to your computer and use it in GitHub Desktop.
const path = require('path');
const { RawSource } = require('webpack-sources');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// Patch MiniCssExtractPlugin to skip writing CSS loading runtime.
// The idea is to `loadAsync` callback to control the behavior.
class CssExtractPlugin extends MiniCssExtractPlugin {
constructor(...args) {
super(...args);
// name -> chunk
// This is an object because getCssChunkObject
// gets called twice! -> No duplicates.
this.cssChunks = {};
}
apply(compiler) {
super.apply(compiler);
const captureCss = this.options.captureCss || (() => {});
compiler.plugin('emit', (compilation, cb) => {
captureCss(compilation, Object.values(this.cssChunks));
cb();
});
}
getCssChunkObject(mainChunk) {
const ret = {};
const loadAsync = this.options.loadAsync || (() => true);
for (const chunk of mainChunk.getAllAsyncChunks()) {
if (loadAsync(chunk)) {
// This has to do with MiniCssExtractPlugin
// internals and it tells it to load this CSS async
// eslint-disable-next-line no-unused-vars
for (const module of chunk.modulesIterable) {
ret[chunk.id] = 1;
break;
}
} else {
// The code assumes only one extracted CSS file per split point
const cssFileName = getCssFileName(chunk);
if (cssFileName) {
this.cssChunks[cssFileName] = chunk;
}
}
}
return ret;
}
}
module.exports = CssExtractPlugin;
module.exports.writeManifest = function writeManifest(outputFile) {
return (compilation, cssChunks) => {
// eslint-disable-next-line no-param-reassign
compilation.assets[outputFile] = new RawSource(
JSON.stringify(
{
'~extracted': {
css: cssChunks.map(getCssFileName)
}
},
null,
2
)
);
};
};
function getCssFileName(chunk) {
const filteredCss = chunk.files.filter(file => path.extname(file) === '.css');
return filteredCss[0];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment