Skip to content

Commit

Permalink
feat: add optimization.moduleIds: 'natural' (#6685)
Browse files Browse the repository at this point in the history
* feat: add `optimization.moduleIds: 'natural'`

Also, set default value to `'natural'` when `mode === 'none'`.

* fix clippy

* test: update css-extract snapshot

* docs: update optimization.moduleIds

* revert defaults change

* test: add a config case for `moduleIds: 'natural'`

* update css-extract snapshot
  • Loading branch information
colinaaa authored May 31, 2024
1 parent 06990bb commit 825883b
Show file tree
Hide file tree
Showing 20 changed files with 144 additions and 13 deletions.
1 change: 1 addition & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export enum BuiltinPluginName {
ConsumeSharedPlugin = 'ConsumeSharedPlugin',
ModuleFederationRuntimePlugin = 'ModuleFederationRuntimePlugin',
NamedModuleIdsPlugin = 'NamedModuleIdsPlugin',
NaturalModuleIdsPlugin = 'NaturalModuleIdsPlugin',
DeterministicModuleIdsPlugin = 'DeterministicModuleIdsPlugin',
NamedChunkIdsPlugin = 'NamedChunkIdsPlugin',
DeterministicChunkIdsPlugin = 'DeterministicChunkIdsPlugin',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use rspack_core::{BoxPlugin, Define, DefinePlugin, Plugin, PluginExt, Provide, P
use rspack_error::Result;
use rspack_ids::{
DeterministicChunkIdsPlugin, DeterministicModuleIdsPlugin, NamedChunkIdsPlugin,
NamedModuleIdsPlugin,
NamedModuleIdsPlugin, NaturalModuleIdsPlugin,
};
use rspack_napi::NapiResultExt;
use rspack_plugin_asset::AssetPlugin;
Expand Down Expand Up @@ -126,6 +126,7 @@ pub enum BuiltinPluginName {
ConsumeSharedPlugin,
ModuleFederationRuntimePlugin,
NamedModuleIdsPlugin,
NaturalModuleIdsPlugin,
DeterministicModuleIdsPlugin,
NamedChunkIdsPlugin,
DeterministicChunkIdsPlugin,
Expand Down Expand Up @@ -323,6 +324,9 @@ impl BuiltinPlugin {
BuiltinPluginName::NamedModuleIdsPlugin => {
plugins.push(NamedModuleIdsPlugin::default().boxed())
}
BuiltinPluginName::NaturalModuleIdsPlugin => {
plugins.push(NaturalModuleIdsPlugin::default().boxed())
}
BuiltinPluginName::DeterministicModuleIdsPlugin => {
plugins.push(DeterministicModuleIdsPlugin::default().boxed())
}
Expand Down
16 changes: 16 additions & 0 deletions crates/rspack_core/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::{cmp::Ordering, fmt::Display};

use itertools::Itertools;
use rspack_identifier::Identifier;
use rspack_util::comparators::compare_ids;
use rspack_util::comparators::compare_numbers;
use rustc_hash::FxHashMap as HashMap;

use crate::{
Expand Down Expand Up @@ -143,6 +145,20 @@ pub fn compare_chunk_group(
}
}

pub fn compare_modules_by_pre_order_index_or_identifier(
module_graph: &ModuleGraph,
a: &Identifier,
b: &Identifier,
) -> std::cmp::Ordering {
if let Some(a) = module_graph.get_pre_order_index(a)
&& let Some(b) = module_graph.get_pre_order_index(b)
{
compare_numbers(a, b)
} else {
compare_ids(a, b)
}
}

pub fn compare_modules_by_identifier(a: &BoxModule, b: &BoxModule) -> std::cmp::Ordering {
compare_ids(&a.identifier(), &b.identifier())
}
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 @@ -8,3 +8,5 @@ mod named_chunk_ids_plugin;
pub use named_chunk_ids_plugin::*;
mod deterministic_chunk_ids_plugin;
pub use deterministic_chunk_ids_plugin::DeterministicChunkIdsPlugin;
mod natural_module_ids_plugin;
pub use natural_module_ids_plugin::NaturalModuleIdsPlugin;
53 changes: 53 additions & 0 deletions crates/rspack_ids/src/natural_module_ids_plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use rspack_core::{
compare_modules_by_pre_order_index_or_identifier, ApplyContext, CompilationModuleIds,
CompilerOptions, Plugin, PluginContext,
};
use rspack_error::Result;
use rspack_hook::{plugin, plugin_hook};

use crate::id_helpers::{assign_ascending_module_ids, get_used_module_ids_and_modules};

#[plugin]
#[derive(Debug, Default)]
pub struct NaturalModuleIdsPlugin;

#[plugin_hook(CompilationModuleIds for NaturalModuleIdsPlugin)]
fn module_ids(&self, compilation: &mut rspack_core::Compilation) -> Result<()> {
let (used_ids, mut modules_in_natural_order) = get_used_module_ids_and_modules(compilation, None);

let mut chunk_graph = std::mem::take(&mut compilation.chunk_graph);
let module_graph = compilation.get_module_graph();

modules_in_natural_order
.sort_unstable_by(|a, b| compare_modules_by_pre_order_index_or_identifier(&module_graph, a, b));

let modules_in_natural_order = modules_in_natural_order
.into_iter()
.filter_map(|i| module_graph.module_by_identifier(&i))
.collect::<Vec<_>>();

assign_ascending_module_ids(&used_ids, modules_in_natural_order, &mut chunk_graph);

compilation.chunk_graph = chunk_graph;

Ok(())
}

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

fn apply(
&self,
ctx: PluginContext<&mut ApplyContext>,
_options: &mut CompilerOptions,
) -> Result<()> {
ctx
.context
.compilation_hooks
.module_ids
.tap(module_ids::new(self));
Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @type {import("@rspack/core").Configuration} */
module.exports = {
mode: "none",
optimization: {
moduleIds: 'named'
},
module: {
rules: [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const a = 42;

import b from "./b.js";

it("should load c.js", () => {
expect(b).toBe("foo");

const d = require("./d.js");

expect(d.default).toEqual({});
});

export { b }

export const c = require("./c.js");
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = "foo";
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function c() {
return "bar"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { a, b } from "./a.js";

it('should load a.js', () => {
expect(a).toBe(42)

expect(b).toBe("foo")
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import("@rspack/core").Configuration} */
module.exports = {
optimization: {
moduleIds: "natural"
},
};
16 changes: 8 additions & 8 deletions packages/rspack/etc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6000,7 +6000,7 @@ export type Optimization = z.infer<typeof optimization>;

// @public (undocumented)
const optimization: z.ZodObject<{
moduleIds: z.ZodOptional<z.ZodEnum<["named", "deterministic"]>>;
moduleIds: z.ZodOptional<z.ZodEnum<["named", "natural", "deterministic"]>>;
chunkIds: z.ZodOptional<z.ZodEnum<["named", "deterministic"]>>;
minimize: z.ZodOptional<z.ZodBoolean>;
minimizer: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"...">, z.ZodUnion<[z.ZodType<RspackPluginInstance, z.ZodTypeDef, RspackPluginInstance>, z.ZodType<RspackPluginFunction, z.ZodTypeDef, RspackPluginFunction>, z.ZodUnion<[z.ZodLiteral<false>, z.ZodLiteral<0>, z.ZodLiteral<"">, z.ZodNull, z.ZodUndefined]>]>]>, "many">>;
Expand Down Expand Up @@ -6199,7 +6199,7 @@ const optimization: z.ZodObject<{
mangleExports: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["size", "deterministic"]>, z.ZodBoolean]>>;
nodeEnv: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodLiteral<false>]>>;
}, "strict", z.ZodTypeAny, {
moduleIds?: "named" | "deterministic" | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "deterministic" | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | RspackPluginInstance | "..." | RspackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -6260,7 +6260,7 @@ const optimization: z.ZodObject<{
mangleExports?: boolean | "deterministic" | "size" | undefined;
nodeEnv?: string | false | undefined;
}, {
moduleIds?: "named" | "deterministic" | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "deterministic" | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | RspackPluginInstance | "..." | RspackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -9372,7 +9372,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", "deterministic"]>>;
moduleIds: z.ZodOptional<z.ZodEnum<["named", "natural", "deterministic"]>>;
chunkIds: z.ZodOptional<z.ZodEnum<["named", "deterministic"]>>;
minimize: z.ZodOptional<z.ZodBoolean>;
minimizer: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"...">, z.ZodUnion<[z.ZodType<RspackPluginInstance, z.ZodTypeDef, RspackPluginInstance>, z.ZodType<RspackPluginFunction, z.ZodTypeDef, RspackPluginFunction>, z.ZodUnion<[z.ZodLiteral<false>, z.ZodLiteral<0>, z.ZodLiteral<"">, z.ZodNull, z.ZodUndefined]>]>]>, "many">>;
Expand Down Expand Up @@ -9571,7 +9571,7 @@ export const rspackOptions: z.ZodObject<{
mangleExports: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["size", "deterministic"]>, z.ZodBoolean]>>;
nodeEnv: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodLiteral<false>]>>;
}, "strict", z.ZodTypeAny, {
moduleIds?: "named" | "deterministic" | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "deterministic" | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | RspackPluginInstance | "..." | RspackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -9632,7 +9632,7 @@ export const rspackOptions: z.ZodObject<{
mangleExports?: boolean | "deterministic" | "size" | undefined;
nodeEnv?: string | false | undefined;
}, {
moduleIds?: "named" | "deterministic" | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "deterministic" | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | RspackPluginInstance | "..." | RspackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -10735,7 +10735,7 @@ export const rspackOptions: z.ZodObject<{
} | undefined;
snapshot?: {} | undefined;
optimization?: {
moduleIds?: "named" | "deterministic" | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "deterministic" | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | RspackPluginInstance | "..." | RspackPluginFunction | null | undefined)[] | undefined;
Expand Down Expand Up @@ -11184,7 +11184,7 @@ export const rspackOptions: z.ZodObject<{
} | undefined;
snapshot?: {} | undefined;
optimization?: {
moduleIds?: "named" | "deterministic" | undefined;
moduleIds?: "named" | "natural" | "deterministic" | undefined;
chunkIds?: "named" | "deterministic" | undefined;
minimize?: boolean | undefined;
minimizer?: (false | "" | 0 | RspackPluginInstance | "..." | RspackPluginFunction | null | undefined)[] | undefined;
Expand Down
9 changes: 9 additions & 0 deletions packages/rspack/src/builtin-plugin/NaturalModuleIdsPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BuiltinPluginName } from "@rspack/binding";

import { create } from "./base";

export const NaturalModuleIdsPlugin = create(
BuiltinPluginName.NaturalModuleIdsPlugin,
() => {},
"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 @@ -43,6 +43,7 @@ export * from "./ModuleChunkFormatPlugin";
export * from "./ModuleConcatenationPlugin";
export * from "./NamedChunkIdsPlugin";
export * from "./NamedModuleIdsPlugin";
export * from "./NaturalModuleIdsPlugin";
export * from "./NodeTargetPlugin";
export * from "./ProgressPlugin";
export * from "./ProvidePlugin";
Expand Down
4 changes: 3 additions & 1 deletion packages/rspack/src/config/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -893,8 +893,10 @@ const applyOptimizationDefaults = (
D(optimization, "removeAvailableModules", true);
D(optimization, "removeEmptyChunks", true);
D(optimization, "mergeDuplicateChunks", true);
F(optimization, "moduleIds", (): "named" | "deterministic" => {
F(optimization, "moduleIds", (): "natural" | "named" | "deterministic" => {
if (production) return "deterministic";
if (development) return "named";
// TODO([email protected]): change to `"natural"`
return "named";
});
F(optimization, "chunkIds", (): "named" | "deterministic" => {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack/src/config/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,7 @@ export type OptimizationSplitChunksOptions = z.infer<
>;

const optimization = z.strictObject({
moduleIds: z.enum(["named", "deterministic"]).optional(),
moduleIds: z.enum(["named", "natural", "deterministic"]).optional(),
chunkIds: z.enum(["named", "deterministic"]).optional(),
minimize: z.boolean().optional(),
minimizer: z.literal("...").or(plugin).array().optional(),
Expand Down
5 changes: 5 additions & 0 deletions packages/rspack/src/rspackOptionsApply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
ModuleConcatenationPlugin,
NamedChunkIdsPlugin,
NamedModuleIdsPlugin,
NaturalModuleIdsPlugin,
NodeTargetPlugin,
RealContentHashPlugin,
RemoveEmptyChunksPlugin,
Expand Down Expand Up @@ -308,6 +309,10 @@ export class RspackOptionsApply {
new NamedModuleIdsPlugin().apply(compiler);
break;
}
case "natural": {
new NaturalModuleIdsPlugin().apply(compiler);
break;
}
case "deterministic": {
new DeterministicModuleIdsPlugin().apply(compiler);
break;
Expand Down
3 changes: 2 additions & 1 deletion website/docs/en/config/optimization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ Rspack will select appropriate optimization configuration based on the [`mode`](

## optimization.moduleIds

<PropertyType type="'named' | 'deterministic'" />
<PropertyType type="'natural' | 'named' | 'deterministic'" />

| option | description |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `natural` | Use numeric ids in order of usage. |
| `named` | Use meaningful, easy-to-debug content as id. This option is enabled by default in development mode. |
| `deterministic` | Use the hashed module identifier as the id to benefit from long-term caching. This option is enabled by default in production mode. |

Expand Down
3 changes: 2 additions & 1 deletion website/docs/zh/config/optimization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import WebpackLicense from '@components/webpack-license';

## optimization.moduleIds

<PropertyType.CN type="'named' | 'deterministic'" />
<PropertyType.CN type="'natural' | 'named' | 'deterministic'" />

| 选项 | 描述 |
| --------------- | --------------------------------------------------------------------------------------- |
| `natural` | 根据模块加载的顺序使用自增数字作为模块 id。 |
| `named` | 使用有意义、方便调试的内容当作模块 id。此选项会在开发环境下默认开启。 |
| `deterministic` | 使用对模块标识符哈希后的数字当作模块 id,有益于长期缓存。此选项会在生产环境下默认开启。 |

Expand Down

2 comments on commit 825883b

@rspack-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Benchmark detail: Open

Name Base (2024-05-31 93a5923) Current Change
10000_development-mode + exec 2.61 s ± 25 ms 2.63 s ± 24 ms +0.82 %
10000_development-mode_hmr + exec 751 ms ± 7.8 ms 735 ms ± 7.6 ms -2.15 %
10000_production-mode + exec 2.56 s ± 31 ms 2.62 s ± 24 ms +2.11 %
arco-pro_development-mode + exec 2.41 s ± 66 ms 2.5 s ± 66 ms +3.87 %
arco-pro_development-mode_hmr + exec 482 ms ± 3.3 ms 489 ms ± 3 ms +1.37 %
arco-pro_production-mode + exec 3.99 s ± 72 ms 4.19 s ± 75 ms +4.93 %
threejs_development-mode_10x + exec 2.14 s ± 16 ms 2.13 s ± 19 ms -0.26 %
threejs_development-mode_10x_hmr + exec 957 ms ± 15 ms 942 ms ± 13 ms -1.52 %
threejs_production-mode_10x + exec 5.47 s ± 27 ms 5.46 s ± 29 ms -0.22 %

@rspack-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Ran ecosystem CI: Open

suite result
modernjs ✅ success
_selftest ✅ success
nx ✅ success
rspress ❌ failure
rsbuild ❌ failure
compat ✅ success
examples ✅ success

Please sign in to comment.