PromucFlow_constructor/app/client/webpack/IconChunkNamingPlugin.js
Satish Gandham 83538ad74d
feat: Bundle optimization and first load improvements (#21667)
Co-authored-by: Ivan Akulov <mail@iamakulov.com>
Co-authored-by: Satish Gandham <hello@satishgandham.com>
Co-authored-by: Ivan Akulov <iamakulov@outlook.com>
Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
Co-authored-by: Shrikant Sharat Kandula <shrikant@appsmith.com>
Co-authored-by: somangshu <somangshu.goswami1508@gmail.com>
2023-05-11 10:56:03 +05:30

70 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* We use `importSvg()` and `importRemixIcon()` utilities to code-split icons away.
* This plugin renames the chunks that contain these icons from
* 35140.dfd465bd.chunk.js
* to
* icon.dfd465bd.chunk.js
* to make it easier to filter them out in the network tab.
*
* Why do it here and not in `chunkFilename`, as canonically intended? Because
* we have lots of icons, and, as of Mar 2023, V8 (the JS engine in Chrome)
* cant handle that: https://bugs.chromium.org/p/v8/issues/detail?id=13887
*/
class IconChunkNamingPlugin {
apply(compiler) {
const webpackConfig = compiler.options;
if (
// checking only for the `[contenthash` part because
// the ending might be dynamic: `]` or `:8]` or `:some-other-number]`
!webpackConfig.output.chunkFilename.includes("[contenthash") &&
!webpackConfig.output.chunkFilename.includes("[chunkhash")
) {
// The plugin requires the chunkFilename to include [contenthash] or [chunkhash]. Thats because
// the plugin renames every icon chunk to "icon". If chunkFilename doesnt include the `[contenthash]` or `[chunkhash]`
// placeholder, wed end up with multiple chunks named "icon". This might result in overwriting
// the icons or (in development) even hanging the build process completely.
throw new Error(
"IconChunkNamingPlugin: the output.chunkFilename config must include [contenthash] " +
"or [chunkhash] to give every chunk file a unique name",
);
}
compiler.hooks.thisCompilation.tap(
"IconChunkNamingPlugin",
(compilation) => {
compilation.hooks.afterOptimizeChunks.tap(
"IconChunkNamingPlugin",
(chunks) => {
const { chunkGraph } = compilation;
// Walk over all chunks webpack emits
for (const chunk of chunks) {
// Get all modules in the current chunk
const chunkModules = chunkGraph.getChunkModules(chunk);
// Only if the chunk has exactly one module...
const hasOnlyOneModule = chunkModules.length === 1;
if (!hasOnlyOneModule) continue;
// ...and that module is either a SVG icon or a Remix icon...
const modulePath = chunkModules[0].resource;
const isSvgIcon =
modulePath.endsWith(".svg.js") || modulePath.endsWith(".svg");
const isRemixIcon = modulePath.match(
/node_modules[\\\/]remixicon-react[\\\/]/,
);
if (!isSvgIcon && !isRemixIcon) continue;
// ...then rename the chunk to "icon"
chunk.name = "icon";
}
},
);
},
);
}
}
module.exports = IconChunkNamingPlugin;