For a project I'm working on, I've developed a plugin that handles the swapping of content in a specific JSON file after all modules are bundled. This is achieved through 2 steps: a loader that replaces the content with a placeholder, and the plugin that replaces the placeholder.
The loader function is as follows:
const loader = function(source) {
this.clearDependencies();
return JSON.stringify('REGENERATED_JSON');
};
And the plugin function looks something like this:
compilation.hooks.optimizeChunkAssets.tapAsync(PLUGIN_NAME, (chunks, callback) => {
chunks.forEach((chunk) => {
chunk.files.forEach((filePath) => {
const asset = compilation.assets[filePath];
const source = asset.source();
replacements.forEach((id) => {
const pattern = 'JSON.parse(""\\"REGENERATED_JSON\\""")';
const index = source.indexOf(pattern);
if (index < 0) return;
const content = JSON.stringify(json_content, null, 2);
const updatedSource = new ReplaceSource(asset);
updatedSource.replace(index, index + pattern.length, content);
compilation.assets[filePath] = updatedSource;
});
});
});
callback();
});
This code does have some drawbacks:
- It is fragile because it relies on a JSON.parse call. I couldn't find a way to make webpack treat the file as JavaScript after importing it as JSON.
- The content hash is not being rebuilt, nor is the file size assessment, so webpack may not accurately assess the size of the JSON content.
Is there a solution within webpack to address these issues?