Skip to content

Commit

Permalink
feat: support more features of DefinePlugin (#7108)
Browse files Browse the repository at this point in the history
* feat: init

* doc
  • Loading branch information
h-a-n-a authored Jul 10, 2024
1 parent 5dc33d7 commit 584cd90
Show file tree
Hide file tree
Showing 22 changed files with 1,394 additions and 390 deletions.
234 changes: 0 additions & 234 deletions crates/rspack_plugin_javascript/src/parser_plugin/define_plugin.rs

This file was deleted.

124 changes: 124 additions & 0 deletions crates/rspack_plugin_javascript/src/parser_plugin/define_plugin/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
mod parser;

use std::{borrow::Cow, collections::HashMap};

use itertools::Itertools;
use parser::{walk_definitions, DefineParserPlugin};
use rspack_core::{
ApplyContext, Compilation, CompilationParams, CompilerCompilation, CompilerOptions, ModuleType,
NormalModuleFactoryParser, ParserAndGenerator, ParserOptions, Plugin, PluginContext,
};
use rspack_error::{
miette::{self, Diagnostic},
thiserror::{self, Error},
DiagnosticExt, Result,
};
use rspack_hook::{plugin, plugin_hook};
use serde_json::Value;

use crate::parser_and_generator::JavaScriptParserAndGenerator;

type DefineValue = HashMap<String, Value>;

const VALUE_DEP_PREFIX: &str = "webpack/DefinePlugin ";

#[plugin]
#[derive(Debug)]
pub struct DefinePlugin {
definitions: DefineValue,
}

impl DefinePlugin {
pub fn new(definitions: DefineValue) -> Self {
Self::new_inner(definitions)
}
}

#[derive(Debug, Error, Diagnostic)]
#[error("DefinePlugin:\nConflicting values for '{0}' ({1} !== {2})")]
#[diagnostic(severity(Warning))]
struct ConflictingValuesError(String, String, String);

#[plugin_hook(CompilerCompilation for DefinePlugin)]
async fn compilation(
&self,
compilation: &mut Compilation,
_params: &mut CompilationParams,
) -> Result<()> {
fn walk_definitions<'d, 's>(
definitions: impl Iterator<Item = (&'d String, &'d Value)>,
compilation: &mut Compilation,
prefix: Cow<'s, str>,
) {
definitions.for_each(|(key, value)| {
let name = format!("{VALUE_DEP_PREFIX}{prefix}{key}");
let value_str = value.to_string();
if let Some(prev) = compilation.value_cache_versions.get(&name)
&& !prev.eq(&value_str)
{
compilation.push_diagnostic(
ConflictingValuesError(format!("{prefix}{key}"), prev.clone(), value_str)
.boxed()
.into(),
);
} else {
compilation.value_cache_versions.insert(name, value_str);
}
if let Some(value) = value.as_object() {
walk_definitions(
value.iter(),
compilation,
Cow::Owned(format!("{prefix}{key}.")),
)
} else if let Some(value) = value.as_array() {
let indexes = (0..value.len())
.map(|index| format!("{}", index))
.collect_vec();
let iter = indexes.iter().zip(value.iter());
walk_definitions(iter, compilation, Cow::Owned(format!("{prefix}{key}.")))
}
});
}
walk_definitions(self.definitions.iter(), compilation, "".into());
Ok(())
}

#[plugin_hook(NormalModuleFactoryParser for DefinePlugin)]
fn nmf_parser(
&self,
module_type: &ModuleType,
parser: &mut dyn ParserAndGenerator,
_parser_options: Option<&ParserOptions>,
) -> Result<()> {
if module_type.is_js_like()
&& let Some(parser) = parser.downcast_mut::<JavaScriptParserAndGenerator>()
{
let walk_data = walk_definitions(&self.definitions);
parser.add_parser_plugin(Box::new(DefineParserPlugin { walk_data }));
}
Ok(())
}

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

fn apply(
&self,
ctx: PluginContext<&mut ApplyContext>,
_options: &mut CompilerOptions,
) -> Result<()> {
ctx
.context
.compiler_hooks
.compilation
.tap(compilation::new(self));
ctx
.context
.normal_module_factory_hooks
.parser
.tap(nmf_parser::new(self));
Ok(())
}
}
Loading

2 comments on commit 584cd90

@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 ❌ failure
_selftest ✅ success
nx ❌ failure
rspress ✅ success
rsbuild ❌ failure
examples ✅ success

@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-07-10 7d3eabb) Current Change
10000_development-mode + exec 2.19 s ± 24 ms 2.23 s ± 27 ms +1.84 %
10000_development-mode_hmr + exec 692 ms ± 5.3 ms 694 ms ± 4.8 ms +0.31 %
10000_production-mode + exec 2.84 s ± 18 ms 2.81 s ± 27 ms -0.79 %
arco-pro_development-mode + exec 1.9 s ± 85 ms 1.9 s ± 43 ms -0.14 %
arco-pro_development-mode_hmr + exec 434 ms ± 2.3 ms 435 ms ± 2.3 ms +0.15 %
arco-pro_production-mode + exec 3.41 s ± 86 ms 3.43 s ± 83 ms +0.58 %
threejs_development-mode_10x + exec 1.59 s ± 10 ms 1.59 s ± 18 ms +0.17 %
threejs_development-mode_10x_hmr + exec 799 ms ± 11 ms 799 ms ± 5.8 ms +0.09 %
threejs_production-mode_10x + exec 5.61 s ± 40 ms 5.55 s ± 22 ms -0.97 %

Please sign in to comment.