Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support size option for optimization.chunkIds config #8642

Merged
merged 1 commit into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ export declare enum BuiltinPluginName {
NaturalChunkIdsPlugin = 'NaturalChunkIdsPlugin',
NamedChunkIdsPlugin = 'NamedChunkIdsPlugin',
DeterministicChunkIdsPlugin = 'DeterministicChunkIdsPlugin',
OccurrenceChunkIdsPlugin = 'OccurrenceChunkIdsPlugin',
RealContentHashPlugin = 'RealContentHashPlugin',
RemoveEmptyChunksPlugin = 'RemoveEmptyChunksPlugin',
EnsureChunkConditionsPlugin = 'EnsureChunkConditionsPlugin',
Expand Down Expand Up @@ -1728,6 +1729,10 @@ export interface RawNonStandard {
deepSelectorCombinator: boolean
}

export interface RawOccurrenceChunkIdsPluginOptions {
prioritiseInitial?: boolean
}

export interface RawOptimizationOptions {
removeAvailableModules: boolean
sideEffects: string
Expand Down
11 changes: 10 additions & 1 deletion crates/rspack_binding_options/src/options/raw_builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod raw_copy;
mod raw_css_extract;
mod raw_dll;
mod raw_html;
mod raw_ids;
mod raw_ignore;
mod raw_lazy_compilation;
mod raw_lightning_css_minimizer;
Expand All @@ -17,13 +18,14 @@ mod raw_swc_js_minimizer;
use napi::{bindgen_prelude::FromNapiValue, Env, JsUnknown};
use napi_derive::napi;
use raw_dll::{RawDllReferenceAgencyPluginOptions, RawFlagAllModulesAsUsedPluginOptions};
use raw_ids::RawOccurrenceChunkIdsPluginOptions;
use raw_lightning_css_minimizer::RawLightningCssMinimizerRspackPluginOptions;
use rspack_binding_values::entry::JsEntryPluginOptions;
use rspack_core::{BoxPlugin, Plugin, PluginExt};
use rspack_error::Result;
use rspack_ids::{
DeterministicChunkIdsPlugin, DeterministicModuleIdsPlugin, NamedChunkIdsPlugin,
NamedModuleIdsPlugin, NaturalChunkIdsPlugin, NaturalModuleIdsPlugin,
NamedModuleIdsPlugin, NaturalChunkIdsPlugin, NaturalModuleIdsPlugin, OccurrenceChunkIdsPlugin,
};
use rspack_napi::NapiResultExt;
use rspack_plugin_asset::AssetPlugin;
Expand Down Expand Up @@ -149,6 +151,7 @@ pub enum BuiltinPluginName {
NaturalChunkIdsPlugin,
NamedChunkIdsPlugin,
DeterministicChunkIdsPlugin,
OccurrenceChunkIdsPlugin,
RealContentHashPlugin,
RemoveEmptyChunksPlugin,
EnsureChunkConditionsPlugin,
Expand Down Expand Up @@ -370,6 +373,12 @@ impl BuiltinPlugin {
BuiltinPluginName::DeterministicChunkIdsPlugin => {
plugins.push(DeterministicChunkIdsPlugin::default().boxed())
}
BuiltinPluginName::OccurrenceChunkIdsPlugin => plugins.push(
OccurrenceChunkIdsPlugin::new(
downcast_into::<RawOccurrenceChunkIdsPluginOptions>(self.options)?.into(),
)
.boxed(),
),
BuiltinPluginName::RealContentHashPlugin => {
plugins.push(RealContentHashPlugin::default().boxed())
}
Expand Down
16 changes: 16 additions & 0 deletions crates/rspack_binding_options/src/options/raw_builtins/raw_ids.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use napi_derive::napi;
use rspack_ids::OccurrenceChunkIdsPluginOptions;

#[derive(Debug)]
#[napi(object, object_to_js = false)]
pub struct RawOccurrenceChunkIdsPluginOptions {
pub prioritise_initial: Option<bool>,
}

impl From<RawOccurrenceChunkIdsPluginOptions> for OccurrenceChunkIdsPluginOptions {
fn from(value: RawOccurrenceChunkIdsPluginOptions) -> Self {
Self {
prioritise_initial: value.prioritise_initial.unwrap_or_default(),
}
}
}
4 changes: 4 additions & 0 deletions crates/rspack_core/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ impl Chunk {
self.groups.remove(chunk_group)
}

pub fn get_number_of_groups(&self) -> usize {
self.groups.len()
}

pub fn runtime(&self) -> &RuntimeSpec {
&self.runtime
}
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_ids/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ mod natural_module_ids_plugin;
pub use natural_module_ids_plugin::NaturalModuleIdsPlugin;
mod natural_chunk_ids_plugin;
pub use natural_chunk_ids_plugin::NaturalChunkIdsPlugin;
mod occurrence_chunk_ids_plugin;
pub use occurrence_chunk_ids_plugin::*;
94 changes: 94 additions & 0 deletions crates/rspack_ids/src/occurrence_chunk_ids_plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::collections::HashMap;

use itertools::Itertools;
use rspack_collections::DatabaseItem;
use rspack_core::{
ApplyContext, Chunk, CompilationChunkIds, CompilerOptions, Plugin, PluginContext,
};
use rspack_error::Result;
use rspack_hook::{plugin, plugin_hook};

use crate::id_helpers::{assign_ascending_chunk_ids, compare_chunks_natural};

pub struct OccurrenceChunkIdsPluginOptions {
pub prioritise_initial: bool,
}

#[plugin]
#[derive(Debug, Default)]
pub struct OccurrenceChunkIdsPlugin {
prioritise_initial: bool,
}

impl OccurrenceChunkIdsPlugin {
pub fn new(option: OccurrenceChunkIdsPluginOptions) -> Self {
Self::new_inner(option.prioritise_initial)
}
}

#[plugin_hook(CompilationChunkIds for OccurrenceChunkIdsPlugin)]
fn chunk_ids(&self, compilation: &mut rspack_core::Compilation) -> Result<()> {
let chunk_graph = &compilation.chunk_graph;
let module_graph = &compilation.get_module_graph();
let chunk_group_by_ukey = &compilation.chunk_group_by_ukey;
let mut occurs_in_initial_chunks_map = HashMap::new();

for chunk in compilation.chunk_by_ukey.values() {
let mut occurs = 0;
for chunk_group_ukey in chunk.groups() {
if let Some(chunk_group) = chunk_group_by_ukey.get(chunk_group_ukey) {
for parent_ukey in &chunk_group.parents {
if let Some(parent) = chunk_group_by_ukey.get(parent_ukey) {
if parent.is_initial() {
occurs += 1;
}
}
}
}
}
occurs_in_initial_chunks_map.insert(chunk.ukey(), occurs);
}

let chunks = compilation
.chunk_by_ukey
.values()
.map(|chunk| chunk as &Chunk)
.sorted_unstable_by(|a, b| {
if self.prioritise_initial {
let a_entry_occurs = occurs_in_initial_chunks_map.get(&a.ukey()).unwrap_or(&0);
let b_entry_occurs = occurs_in_initial_chunks_map.get(&b.ukey()).unwrap_or(&0);
if a_entry_occurs != b_entry_occurs {
return b_entry_occurs.cmp(a_entry_occurs);
}
}

let a_occurs = a.get_number_of_groups();
let b_occurs = b.get_number_of_groups();
if a_occurs != b_occurs {
return b_occurs.cmp(&a_occurs);
}

compare_chunks_natural(chunk_graph, module_graph, &compilation.module_ids, a, b)
})
.map(|chunk| chunk.ukey())
.collect::<Vec<_>>();

assign_ascending_chunk_ids(&chunks, compilation);

Ok(())
}

impl Plugin for OccurrenceChunkIdsPlugin {
fn name(&self) -> &'static str {
"rspack.OccurrenceChunkIdsPlugin"
}

fn apply(&self, ctx: PluginContext<&mut ApplyContext>, _options: &CompilerOptions) -> Result<()> {
ctx
.context
.compilation_hooks
.chunk_ids
.tap(chunk_ids::new(self));
Ok(())
}
}
12 changes: 6 additions & 6 deletions packages/rspack/etc/core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4028,7 +4028,7 @@ type Open = (file: PathLike, flags: undefined | string | number, callback: (arg0
// @public (undocumented)
export type Optimization = {
moduleIds?: "named" | "natural" | "deterministic";
chunkIds?: "natural" | "named" | "deterministic";
chunkIds?: "natural" | "named" | "deterministic" | "size" | "total-size";
minimize?: boolean;
minimizer?: Array<"..." | Plugin_2>;
mergeDuplicateChunks?: boolean;
Expand Down Expand Up @@ -6851,7 +6851,7 @@ export const rspackOptions: z.ZodObject<{
snapshot: z.ZodOptional<z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>>;
optimization: z.ZodOptional<z.ZodObject<{
moduleIds: z.ZodOptional<z.ZodEnum<["named", "natural", "deterministic"]>>;
chunkIds: z.ZodOptional<z.ZodEnum<["natural", "named", "deterministic"]>>;
chunkIds: z.ZodOptional<z.ZodEnum<["natural", "named", "deterministic", "size", "total-size"]>>;
minimize: z.ZodOptional<z.ZodBoolean>;
minimizer: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"...">, z.ZodUnion<[z.ZodType<t.RspackPluginInstance | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction, z.ZodTypeDef, t.RspackPluginInstance | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction>, z.ZodUnion<[z.ZodLiteral<false>, z.ZodLiteral<0>, z.ZodLiteral<"">, z.ZodNull, z.ZodUndefined]>]>]>, "many">>;
mergeDuplicateChunks: z.ZodOptional<z.ZodBoolean>;
Expand Down Expand Up @@ -7115,7 +7115,7 @@ export const rspackOptions: z.ZodObject<{
usedExports?: boolean | "global" | undefined;
providedExports?: boolean | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "size" | "named" | "natural" | "deterministic" | "total-size" | undefined;
removeAvailableModules?: boolean | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | t.RspackPluginInstance | "..." | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -7181,7 +7181,7 @@ export const rspackOptions: z.ZodObject<{
usedExports?: boolean | "global" | undefined;
providedExports?: boolean | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "size" | "named" | "natural" | "deterministic" | "total-size" | undefined;
removeAvailableModules?: boolean | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | t.RspackPluginInstance | "..." | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -8701,7 +8701,7 @@ export const rspackOptions: z.ZodObject<{
usedExports?: boolean | "global" | undefined;
providedExports?: boolean | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "size" | "named" | "natural" | "deterministic" | "total-size" | undefined;
removeAvailableModules?: boolean | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | t.RspackPluginInstance | "..." | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -9301,7 +9301,7 @@ export const rspackOptions: z.ZodObject<{
usedExports?: boolean | "global" | undefined;
providedExports?: boolean | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "size" | "named" | "natural" | "deterministic" | "total-size" | undefined;
removeAvailableModules?: boolean | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | t.RspackPluginInstance | "..." | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction | null | undefined)[] | undefined;
Expand Down
12 changes: 12 additions & 0 deletions packages/rspack/src/builtin-plugin/OccurrenceChunkIdsPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {
BuiltinPluginName,
type RawOccurrenceChunkIdsPluginOptions
} from "@rspack/binding";

import { create } from "./base";

export const OccurrenceChunkIdsPlugin = create(
BuiltinPluginName.OccurrenceChunkIdsPlugin,
(options?: RawOccurrenceChunkIdsPluginOptions) => ({ ...options }),
"compilation"
);
1 change: 1 addition & 0 deletions packages/rspack/src/builtin-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export * from "./NamedModuleIdsPlugin";
export * from "./NaturalChunkIdsPlugin";
export * from "./NaturalModuleIdsPlugin";
export * from "./NodeTargetPlugin";
export * from "./OccurrenceChunkIdsPlugin";
export * from "./ProgressPlugin";
export * from "./ProvidePlugin";
export * from "./RealContentHashPlugin";
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2208,7 +2208,7 @@ export type Optimization = {
/**
* Which algorithm to use when choosing chunk ids.
*/
chunkIds?: "natural" | "named" | "deterministic";
chunkIds?: "natural" | "named" | "deterministic" | "size" | "total-size";

/**
* Whether to minimize the bundle.
Expand Down
4 changes: 3 additions & 1 deletion packages/rspack/src/config/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,9 @@ const optimizationSplitChunksOptions = z.strictObject({

const optimization = z.strictObject({
moduleIds: z.enum(["named", "natural", "deterministic"]).optional(),
chunkIds: z.enum(["natural", "named", "deterministic"]).optional(),
chunkIds: z
.enum(["natural", "named", "deterministic", "size", "total-size"])
.optional(),
minimize: z.boolean().optional(),
minimizer: z.literal("...").or(plugin).array().optional(),
mergeDuplicateChunks: z.boolean().optional(),
Expand Down
13 changes: 13 additions & 0 deletions packages/rspack/src/rspackOptionsApply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import {
NaturalModuleIdsPlugin,
NoEmitOnErrorsPlugin,
NodeTargetPlugin,
OccurrenceChunkIdsPlugin,
RealContentHashPlugin,
RemoveEmptyChunksPlugin,
RuntimeChunkPlugin,
Expand Down Expand Up @@ -336,6 +337,18 @@ export class RspackOptionsApply {
new DeterministicChunkIdsPlugin().apply(compiler);
break;
}
case "size": {
new OccurrenceChunkIdsPlugin({
prioritiseInitial: true
}).apply(compiler);
break;
}
case "total-size": {
new OccurrenceChunkIdsPlugin({
prioritiseInitial: false
}).apply(compiler);
break;
}
default:
throw new Error(`chunkIds: ${chunkIds} is not implemented`);
}
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion website/components/PluginSupportStatusTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ const pluginSupportStatusList: PluginSupportStatus[] = [
},
{
name: 'OccurrenceChunkIdsPlugin',
status: SupportStatus.NotSupported,
status: SupportStatus.FullySupported,
},
{
name: 'OccurrenceModuleIdsPlugin',
Expand Down
3 changes: 3 additions & 0 deletions website/docs/en/config/optimization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ The following string values are supported:

| option | description |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `'natural'` | Use numeric ids in order of usage. |
| `'named'` | Readable ids for better debugging. |
| `'deterministic'` | Short numeric ids which will not be changing between compilation. Good for long term caching. By default a minimum length of 3 digits is used. |
| `'size'` | Use numeric ids to make the initial download package smaller. |
| `'total-size'` | Use numeric ids to make the overall download package smaller. |

```js title=rspack.config.js
module.exports = {
Expand Down
3 changes: 3 additions & 0 deletions website/docs/zh/config/optimization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ module.exports = {

| 选项 | 描述 |
| ----------------- | ---------------------------------------------------------------------------------------- |
| `'natural'` | 根据 Chunk 加载的顺序使用自增数字作为 Chunk id。 |
| `'named'` | 使用有意义、方便调试的内容当作 Chunk id。 |
| `'deterministic'` | 简短的数字 id,在多次编译的场景下,会尽量保持其稳定性。适合长期缓存。默认使用 3 位数字。 |
| `'size'` | 使用让初始下载包大小更小的数字 id。 |
| `'total-size'` | 使用让总下载包大小更小的数字 id。 |

```js title=rspack.config.js
module.exports = {
Expand Down
Loading