Skip to content

Commit

Permalink
feat: add new optimization.avoidEntryIife config (#8814)
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework authored Dec 25, 2024
1 parent 56a99b2 commit 27dca00
Show file tree
Hide file tree
Showing 63 changed files with 450 additions and 151 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 @@ -1746,6 +1746,7 @@ export interface RawOptimizationOptions {
innerGraph: boolean
mangleExports: boolean | string
concatenateModules: boolean
avoidEntryIife: boolean
}

export interface RawOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct RawOptimizationOptions {
#[napi(ts_type = "boolean | string")]
pub mangle_exports: WithBool<String>,
pub concatenate_modules: bool,
pub avoid_entry_iife: bool,
}

macro_rules! impl_from_with_bool {
Expand Down Expand Up @@ -48,6 +49,7 @@ impl TryFrom<RawOptimizationOptions> for Optimization {
inner_graph: value.inner_graph,
mangle_exports: value.mangle_exports.into(),
concatenate_modules: value.concatenate_modules,
avoid_entry_iife: value.avoid_entry_iife,
})
}
}
1 change: 1 addition & 0 deletions crates/rspack_core/src/options/optimizations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ pub struct Optimization {
pub inner_graph: bool,
pub mangle_exports: MangleExportsOption,
pub concatenate_modules: bool,
pub avoid_entry_iife: bool,
}

pub static DEFAULT_DELIMITER: &str = "~";
62 changes: 45 additions & 17 deletions crates/rspack_plugin_javascript/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,13 +637,18 @@ impl JsPlugin {
)));
}

let renamed_inline_modules = self.rename_inline_modules(
&all_modules,
inlined_modules,
compilation,
chunk_ukey,
all_strict,
)?;
let renamed_inline_modules = if compilation.options.optimization.avoid_entry_iife {
self.get_renamed_inline_module(
&all_modules,
inlined_modules,
compilation,
chunk_ukey,
all_strict,
has_chunk_modules_result,
)?
} else {
None
};

for (m_identifier, _) in inlined_modules {
let m = module_graph
Expand All @@ -655,10 +660,12 @@ impl JsPlugin {
continue;
};

if renamed_inline_modules.contains_key(m_identifier) {
if let Some(source) = renamed_inline_modules.get(m_identifier) {
rendered_module = source.clone();
};
if let Some(renamed_inline_modules) = &renamed_inline_modules {
if renamed_inline_modules.contains_key(m_identifier) {
if let Some(source) = renamed_inline_modules.get(m_identifier) {
rendered_module = source.clone();
};
}
}

chunk_init_fragments.extend(fragments);
Expand All @@ -673,9 +680,11 @@ impl JsPlugin {
let webpack_exports_argument = matches!(exports_argument, ExportsArgument::WebpackExports);
let webpack_exports = exports && webpack_exports_argument;
let iife: Option<Cow<str>> = if inner_strict {
Some("it need to be in strict mode.".into())
Some("it needs to be in strict mode.".into())
} else if inlined_modules.len() > 1 {
Some("it need to be isolated against other entry modules.".into())
Some("it needs to be isolated against other entry modules.".into())
} else if has_chunk_modules_result && renamed_inline_modules.is_none() {
Some("it needs to be isolated against other modules in the chunk.".into())
} else if exports && !webpack_exports {
Some(format!("it uses a non-standard name for the exports ({exports_argument}).").into())
} else {
Expand All @@ -687,7 +696,7 @@ impl JsPlugin {
let footer;
if let Some(iife) = iife {
startup_sources.add(RawStringSource::from(format!(
"// This entry need to be wrapped in an IIFE because {iife}\n"
"// This entry needs to be wrapped in an IIFE because {iife}\n"
)));
if supports_arrow_function {
startup_sources.add(RawStringSource::from_static("(() => {\n"));
Expand Down Expand Up @@ -784,14 +793,33 @@ impl JsPlugin {
})
}

pub fn rename_inline_modules(
pub fn get_renamed_inline_module(
&self,
all_modules: &[&BoxModule],
inlined_modules: &IdentifierLinkedMap<ChunkGroupUkey>,
compilation: &Compilation,
chunk_ukey: &ChunkUkey,
all_strict: bool,
) -> Result<IdentifierMap<Arc<dyn Source>>> {
has_chunk_modules_result: bool,
) -> Result<Option<IdentifierMap<Arc<dyn Source>>>> {
let inner_strict = !all_strict
&& all_modules.iter().all(|m| {
let build_info = m
.build_info()
.expect("should have build_info in rename_inline_modules");
build_info.strict
});
let is_multiple_entries = inlined_modules.len() > 1;
let single_entry_with_modules = inlined_modules.len() == 1 && has_chunk_modules_result;

// TODO:
// This step is before the IIFE reason calculation. Ideally, it should only be executed when this function can optimize the
// IIFE reason. Otherwise, it should directly return false. There are four reasons now, we have skipped two already, the left
// one is 'it uses a non-standard name for the exports'.
if is_multiple_entries || inner_strict || !single_entry_with_modules {
return Ok(None);
}

let mut inlined_modules_to_info: IdentifierMap<InlinedModuleInfo> = IdentifierMap::default();
let mut non_inlined_module_through_idents: Vec<ConcatenatedModuleIdent> = Vec::new();
let mut all_used_names = HashSet::from_iter(RESERVED_NAMES.iter().map(|item| Atom::new(*item)));
Expand Down Expand Up @@ -1076,7 +1104,7 @@ impl JsPlugin {
renamed_inline_modules.insert(*module_id, Arc::clone(&source));
}

Ok(renamed_inline_modules)
Ok(Some(renamed_inline_modules))
}

pub async fn render_chunk(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ Object {
global: warn,
},
optimization: Object {
avoidEntryIife: false,
chunkIds: natural,
concatenateModules: false,
emitOnErrors: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ Rspack x.x.x compiled successfully in X s
`;
exports[`statsOutput statsOutput/css-concat should print correct stats for 1`] = `
asset main.js 3.65 KiB [emitted] (name: main)
asset main.js 3.78 KiB [emitted] (name: main)
asset main.css 24 bytes [emitted] (name: main)
Entrypoint main 3.67 KiB = main.js 3.65 KiB main.css 24 bytes
Entrypoint main 3.8 KiB = main.js 3.78 KiB main.css 24 bytes
runtime modules 2.26 KiB 6 modules
cacheable modules 62 bytes (javascript) 23 bytes (css)
./index.js 20 bytes [built] [code generated]
Expand Down Expand Up @@ -142,14 +142,14 @@ Rspack compiled with 1 error
exports[`statsOutput statsOutput/limit-chunk-count-plugin should print correct stats for 1`] = `
1 chunks:
asset bundle1.js 3.54 KiB [emitted] (name: main)
asset bundle1.js 3.66 KiB [emitted] (name: main)
chunk (runtime: main) bundle1.js (main) 219 bytes (javascript) 1.84 KiB (runtime) <{909}> >{909}< [entry] [rendered]
dependent modules 96 bytes [dependent] 4 modules
./index.js 123 bytes [built] [code generated]
1 chunks (Rspack x.x.x) compiled successfully in X s
2 chunks:
asset bundle2.js 10.5 KiB [emitted] (name: main)
asset bundle2.js 10.6 KiB [emitted] (name: main)
asset 76.bundle2.js 497 bytes [emitted] (name: c)
chunk (runtime: main) 76.bundle2.js (c) 74 bytes <{76}> <{909}> >{76}< [rendered]
dependent modules 44 bytes [dependent] 2 modules
Expand All @@ -160,7 +160,7 @@ exports[`statsOutput statsOutput/limit-chunk-count-plugin should print correct s
2 chunks (Rspack x.x.x) compiled successfully in X s
3 chunks:
asset bundle3.js 10.5 KiB [emitted] (name: main)
asset bundle3.js 10.6 KiB [emitted] (name: main)
asset 76.bundle3.js 387 bytes [emitted] (name: c)
asset 345.bundle3.js 186 bytes [emitted]
chunk (runtime: main) 345.bundle3.js 44 bytes <{76}> [rendered]
Expand All @@ -174,7 +174,7 @@ exports[`statsOutput statsOutput/limit-chunk-count-plugin should print correct s
3 chunks (Rspack x.x.x) compiled successfully in X s
4 chunks:
asset bundle4.js 10.5 KiB [emitted] (name: main)
asset bundle4.js 10.6 KiB [emitted] (name: main)
asset 76.bundle4.js 387 bytes [emitted] (name: c)
asset 697.bundle4.js 130 bytes [emitted]
asset 753.bundle4.js 130 bytes [emitted]
Expand Down Expand Up @@ -327,11 +327,11 @@ cacheable modules 293 KiB
./e.js 22 bytes [built] [code generated]
ERROR in × asset size limit: The following asset(s) exceed the recommended size limit (244.141 KiB). This can impact web performance.Assets:
│ main.js (303.692 KiB)
│ main.js (303.818 KiB)
ERROR in × entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244.141 KiB). This can impact web performance.Entrypoints:
│ main (303.692 KiB)
│ main (303.818 KiB)
│ main.js
Expand Down Expand Up @@ -411,7 +411,7 @@ webpack/runtime/make_namespace_object 280 bytes [code generated]
`;
exports[`statsOutput statsOutput/runtime-specific-exports should print correct stats for 1`] = `
asset main.js 1.67 KiB [emitted] (name: main)
asset main.js 1.8 KiB [emitted] (name: main)
./example.js 70 bytes [built] [code generated]
[no exports]
[no exports used]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ module.exports = {
type: "modern-module",
}
},
optimization: {
avoidEntryIife: true,
},
experiments: {
outputModule: true
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@ module.exports = [
experiments: {
outputModule: true
},
optimization: {
avoidEntryIife: true,
},
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = (env, { testPath }) => [
},
optimization: {
concatenateModules: true,
avoidEntryIife: true,
},
experiments: {
outputModule: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module.exports = [{
},
optimization: {
concatenateModules: true,
avoidEntryIife: true,
minimize: false
},
}, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
},
externals: "external-module",
optimization: {
avoidEntryIife: true,
concatenateModules: true,
minimize: false
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module.exports = {
},
optimization: {
concatenateModules: true,
avoidEntryIife: true,
minimize: false
},
plugins: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ module.exports = {
library: {
type: 'modern-module'
}
}
}
},
optimization: {
avoidEntryIife: true,
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ __webpack_require__.o = function (obj, prop) {

})();
/************************************************************************/
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
// This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
(() => {
"use strict";
/* ESM import */var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("../../normalModuleFactory​#afterResolve/duplicate/a.js");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ __webpack_require__.o = function (obj, prop) {

})();
/************************************************************************/
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
// This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
(() => {
"use strict";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ __webpack_require__.o = function (obj, prop) {

})();
/************************************************************************/
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
// This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
(() => {
"use strict";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ __webpack_require__.o = function (obj, prop) {

})();
/************************************************************************/
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
// This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
(() => {
"use strict";

Expand Down
6 changes: 6 additions & 0 deletions packages/rspack/etc/core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4132,6 +4132,7 @@ export type Optimization = {
mangleExports?: "size" | "deterministic" | boolean;
nodeEnv?: string | false;
emitOnErrors?: boolean;
avoidEntryIife?: boolean;
};

// @public
Expand Down Expand Up @@ -7178,6 +7179,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>]>>;
emitOnErrors: z.ZodOptional<z.ZodBoolean>;
avoidEntryIife: z.ZodOptional<z.ZodBoolean>;
}, "strict", z.ZodTypeAny, {
usedExports?: boolean | "global" | undefined;
providedExports?: boolean | undefined;
Expand Down Expand Up @@ -7244,6 +7246,7 @@ export const rspackOptions: z.ZodObject<{
mangleExports?: boolean | "deterministic" | "size" | undefined;
nodeEnv?: string | false | undefined;
emitOnErrors?: boolean | undefined;
avoidEntryIife?: boolean | undefined;
}, {
usedExports?: boolean | "global" | undefined;
providedExports?: boolean | undefined;
Expand Down Expand Up @@ -7310,6 +7313,7 @@ export const rspackOptions: z.ZodObject<{
mangleExports?: boolean | "deterministic" | "size" | undefined;
nodeEnv?: string | false | undefined;
emitOnErrors?: boolean | undefined;
avoidEntryIife?: boolean | undefined;
}>>;
resolve: z.ZodOptional<z.ZodType<t.ResolveOptions, z.ZodTypeDef, t.ResolveOptions>>;
resolveLoader: z.ZodOptional<z.ZodType<t.ResolveOptions, z.ZodTypeDef, t.ResolveOptions>>;
Expand Down Expand Up @@ -8933,6 +8937,7 @@ export const rspackOptions: z.ZodObject<{
mangleExports?: boolean | "deterministic" | "size" | undefined;
nodeEnv?: string | false | undefined;
emitOnErrors?: boolean | undefined;
avoidEntryIife?: boolean | undefined;
} | undefined;
plugins?: (false | "" | 0 | t.RspackPluginInstance | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction | null | undefined)[] | undefined;
watch?: boolean | undefined;
Expand Down Expand Up @@ -9535,6 +9540,7 @@ export const rspackOptions: z.ZodObject<{
mangleExports?: boolean | "deterministic" | "size" | undefined;
nodeEnv?: string | false | undefined;
emitOnErrors?: boolean | undefined;
avoidEntryIife?: boolean | undefined;
} | undefined;
plugins?: (false | "" | 0 | t.RspackPluginInstance | t.WebpackPluginInstance | t.RspackPluginFunction | t.WebpackPluginFunction | null | undefined)[] | undefined;
watch?: boolean | undefined;
Expand Down
2 changes: 2 additions & 0 deletions packages/rspack/src/config/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,8 @@ const applyOptimizationDefaults = (
D(optimization, "emitOnErrors", !production);
D(optimization, "runtimeChunk", false);
D(optimization, "realContentHash", production);
// IGNORE(optimization.avoidEntryIife): to update the default value of webpack and bump webpack version in Rspack.
D(optimization, "avoidEntryIife", false);
D(optimization, "minimize", production);
D(optimization, "concatenateModules", production);
// IGNORE(optimization.minimizer): Rspack use `SwcJsMinimizerRspackPlugin` and `LightningCssMinimizerRspackPlugin` by default
Expand Down
5 changes: 5 additions & 0 deletions packages/rspack/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,11 @@ export type Optimization = {
* The value is `true` in development mode.
* */
emitOnErrors?: boolean;

/**
* Avoid wrapping the entry module in an IIFE.
*/
avoidEntryIife?: boolean;
};
//#endregion

Expand Down
3 changes: 2 additions & 1 deletion packages/rspack/src/config/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,8 @@ const optimization = z.strictObject({
usedExports: z.enum(["global"]).or(z.boolean()).optional(),
mangleExports: z.enum(["size", "deterministic"]).or(z.boolean()).optional(),
nodeEnv: z.union([z.string(), z.literal(false)]).optional(),
emitOnErrors: z.boolean().optional()
emitOnErrors: z.boolean().optional(),
avoidEntryIife: z.boolean().optional()
}) satisfies z.ZodType<t.Optimization>;
//#endregion

Expand Down
Loading

0 comments on commit 27dca00

Please sign in to comment.