rspack_plugin_remove_empty_chunks/
lib.rs

1// Port of https://github.com/webpack/webpack/blob/4b4ca3bb53f36a5b8fc6bc1bd976ed7af161bd80/lib/optimize/RemoveEmptyChunksPlugin.js
2
3use rspack_collections::DatabaseItem;
4use rspack_core::{Compilation, CompilationOptimizeChunks, Logger, Plugin, incremental::Mutation};
5use rspack_error::Result;
6use rspack_hook::{plugin, plugin_hook};
7
8#[plugin]
9#[derive(Debug, Default)]
10pub struct RemoveEmptyChunksPlugin;
11
12impl RemoveEmptyChunksPlugin {
13  fn remove_empty_chunks(&self, compilation: &mut Compilation) {
14    let logger = compilation.get_logger(self.name());
15    let start = logger.time("remove empty chunks");
16
17    let chunk_graph = &mut compilation.chunk_graph;
18    let empty_chunks = compilation
19      .chunk_by_ukey
20      .values()
21      .filter(|chunk| {
22        chunk_graph.get_number_of_chunk_modules(&chunk.ukey()) == 0
23          && !chunk.has_runtime(&compilation.chunk_group_by_ukey)
24          && chunk_graph.get_number_of_entry_modules(&chunk.ukey()) == 0
25          && chunk
26            .get_entry_options(&compilation.chunk_group_by_ukey)
27            .is_none()
28      })
29      .map(|chunk| chunk.ukey())
30      .collect::<Vec<_>>();
31
32    empty_chunks.iter().for_each(|chunk_ukey| {
33      if let Some(mut chunk) = compilation.chunk_by_ukey.remove(chunk_ukey) {
34        chunk_graph.disconnect_chunk(&mut chunk, &mut compilation.chunk_group_by_ukey);
35        if let Some(mutations) = compilation.incremental.mutations_write() {
36          mutations.add(Mutation::ChunkRemove { chunk: *chunk_ukey });
37        }
38      }
39    });
40
41    logger.time_end(start);
42  }
43}
44
45#[plugin_hook(CompilationOptimizeChunks for RemoveEmptyChunksPlugin, stage = Compilation::OPTIMIZE_CHUNKS_STAGE_ADVANCED)]
46async fn optimize_chunks(&self, compilation: &mut Compilation) -> Result<Option<bool>> {
47  self.remove_empty_chunks(compilation);
48  Ok(None)
49}
50
51impl Plugin for RemoveEmptyChunksPlugin {
52  fn name(&self) -> &'static str {
53    "rspack.RemoveEmptyChunksPlugin"
54  }
55
56  fn apply(&self, ctx: &mut rspack_core::ApplyContext) -> Result<()> {
57    ctx
58      .compilation_hooks
59      .optimize_chunks
60      .tap(optimize_chunks::new(self));
61    Ok(())
62  }
63}