@@ -2,24 +2,23 @@ mod parser;
22pub ( crate ) mod utils;
33mod walk_data;
44
5- use std:: sync:: Arc ;
5+ use std:: sync:: { Arc , LazyLock } ;
66
77use parser:: DefineParserPlugin ;
88use rspack_core:: {
9- Compilation , CompilationParams , CompilerCompilation , ModuleType , NormalModuleFactoryParser ,
10- ParserAndGenerator , ParserOptions , Plugin ,
9+ Compilation , CompilationId , CompilationParams , CompilerCompilation , ModuleType ,
10+ NormalModuleFactoryParser , ParserAndGenerator , ParserOptions , Plugin ,
1111} ;
1212use rspack_error:: { Diagnostic , Error , Result } ;
1313use rspack_hook:: { plugin, plugin_hook} ;
14- use rustc_hash :: FxHashMap ;
14+ use rspack_util :: fx_hash :: { FxDashMap , FxHashMap } ;
1515use serde_json:: Value ;
1616
17- use self :: walk_data:: WalkData ;
17+ use self :: { utils :: code_to_string , walk_data:: WalkData } ;
1818use crate :: parser_and_generator:: JavaScriptParserAndGenerator ;
1919
2020pub ( crate ) const VALUE_DEP_PREFIX : & str = "rspack/DefinePlugin " ;
2121pub ( crate ) const IMPORT_META_ENV_VALUE_DEP_KEY : & str = "rspack/DefinePlugin import.meta.env.*" ;
22- const IMPORT_META_ENV_PREFIX : & str = "import.meta.env." ;
2322
2423#[ derive( Debug ) ]
2524struct ConflictingValuesError ( String , String , String ) ;
@@ -35,54 +34,82 @@ impl ConflictingValuesError {
3534}
3635
3736pub type DefineValue = FxHashMap < String , Value > ;
37+ pub ( crate ) type ImportMetaEnvDefinitions = FxHashMap < String , Value > ;
38+
39+ #[ derive( Debug , Default ) ]
40+ struct ImportMetaEnvDefinitionsState {
41+ definitions : ImportMetaEnvDefinitions ,
42+ serialized : Option < String > ,
43+ }
44+
45+ static IMPORT_META_ENV_DEFINITIONS_MAP : LazyLock <
46+ FxDashMap < CompilationId , ImportMetaEnvDefinitionsState > ,
47+ > = LazyLock :: new ( Default :: default) ;
3848
3949#[ plugin]
4050#[ derive( Debug ) ]
4151pub struct DefinePlugin {
4252 walk_data : Arc < WalkData > ,
43- definitions : Arc < DefineValue > ,
4453}
4554
4655impl DefinePlugin {
4756 pub fn new ( definitions : DefineValue ) -> Self {
48- Self :: new_inner ( Arc :: new ( WalkData :: new ( & definitions) ) , Arc :: new ( definitions ) )
57+ Self :: new_inner ( Arc :: new ( WalkData :: new ( & definitions) ) )
4958 }
5059}
5160
52- fn import_meta_env_value ( definitions : & DefineValue ) -> String {
61+ pub ( crate ) fn serialize_import_meta_env_definitions (
62+ definitions : & ImportMetaEnvDefinitions ,
63+ ) -> String {
5364 let mut pairs = definitions
5465 . iter ( )
55- . filter_map ( |( key, value) | {
56- key
57- . strip_prefix ( IMPORT_META_ENV_PREFIX )
58- . map ( |env_key| ( env_key, value. to_string ( ) ) )
59- } )
66+ . map ( |( key, value) | ( key. as_str ( ) , code_to_string ( value, None , None ) ) )
6067 . collect :: < Vec < _ > > ( ) ;
6168 pairs. sort_unstable_by ( |a, b| a. 0 . cmp ( b. 0 ) ) ;
62- pairs
69+ let content = pairs
6370 . into_iter ( )
64- . map ( |( key, value) | format ! ( "{key }:{value}" ) )
71+ . map ( |( key, value) | format ! ( "{}:{value}" , rspack_util :: json_stringify_str ( key ) ) )
6572 . collect :: < Vec < _ > > ( )
66- . join ( "," )
73+ . join ( "," ) ;
74+ format ! ( "{{{content}}}" )
75+ }
76+
77+ pub ( crate ) fn remove_import_meta_env_definitions ( compilation_id : CompilationId ) {
78+ IMPORT_META_ENV_DEFINITIONS_MAP . remove ( & compilation_id) ;
79+ }
80+
81+ pub ( crate ) fn import_meta_env_definitions_string ( compilation_id : CompilationId ) -> String {
82+ IMPORT_META_ENV_DEFINITIONS_MAP
83+ . get ( & compilation_id)
84+ . map ( |state| {
85+ state
86+ . serialized
87+ . clone ( )
88+ . unwrap_or_else ( || serialize_import_meta_env_definitions ( & state. definitions ) )
89+ } )
90+ . unwrap_or_else ( || "{}" . to_string ( ) )
91+ }
92+
93+ pub ( crate ) fn has_import_meta_env_definition ( compilation_id : CompilationId , name : & str ) -> bool {
94+ IMPORT_META_ENV_DEFINITIONS_MAP
95+ . get ( & compilation_id)
96+ . is_some_and ( |state| state. definitions . contains_key ( name) )
6797}
6898
6999#[ plugin_hook( CompilerCompilation for DefinePlugin , tracing=false ) ]
70- async fn compilation (
100+ async fn collect_import_meta_env_definitions (
71101 & self ,
72102 compilation : & mut Compilation ,
73103 _params : & mut CompilationParams ,
74104) -> Result < ( ) > {
75105 compilation. extend_diagnostics ( self . walk_data . diagnostics . clone ( ) ) ;
76- compilation. define_plugin_definitions . extend (
77- self
78- . definitions
79- . iter ( )
80- . map ( |( key, value) | ( key. clone ( ) , value. clone ( ) ) ) ,
81- ) ;
82- compilation. value_cache_versions . insert (
83- IMPORT_META_ENV_VALUE_DEP_KEY . to_string ( ) ,
84- import_meta_env_value ( & compilation. define_plugin_definitions ) ,
85- ) ;
106+ let mut definitions = IMPORT_META_ENV_DEFINITIONS_MAP
107+ . entry ( compilation. id ( ) )
108+ . or_default ( ) ;
109+ for ( key, value) in & self . walk_data . import_meta_env_definitions {
110+ definitions. definitions . insert ( key. clone ( ) , value. clone ( ) ) ;
111+ definitions. serialized = None ;
112+ }
86113 for ( key, value) in self . walk_data . tiling_definitions . iter ( ) {
87114 let cache_key = format ! ( "{VALUE_DEP_PREFIX}{key}" ) ;
88115 if let Some ( prev) = compilation. value_cache_versions . get ( & cache_key)
@@ -101,6 +128,30 @@ async fn compilation(
101128 Ok ( ( ) )
102129}
103130
131+ #[ plugin_hook( CompilerCompilation for DefinePlugin , stage = i32 :: MAX , tracing=false ) ]
132+ async fn finalize_import_meta_env_definitions (
133+ & self ,
134+ compilation : & mut Compilation ,
135+ _params : & mut CompilationParams ,
136+ ) -> Result < ( ) > {
137+ let mut state = IMPORT_META_ENV_DEFINITIONS_MAP
138+ . entry ( compilation. id ( ) )
139+ . or_default ( ) ;
140+ let serialized = match & state. serialized {
141+ Some ( serialized) => serialized. clone ( ) ,
142+ None => {
143+ let serialized = serialize_import_meta_env_definitions ( & state. definitions ) ;
144+ state. serialized = Some ( serialized. clone ( ) ) ;
145+ serialized
146+ }
147+ } ;
148+ compilation
149+ . value_cache_versions
150+ . insert ( IMPORT_META_ENV_VALUE_DEP_KEY . to_string ( ) , serialized) ;
151+
152+ Ok ( ( ) )
153+ }
154+
104155#[ plugin_hook( NormalModuleFactoryParser for DefinePlugin , tracing=false ) ]
105156async fn nmf_parser (
106157 & self ,
@@ -121,8 +172,19 @@ impl Plugin for DefinePlugin {
121172 "rspack.DefinePlugin"
122173 }
123174
175+ fn clear_cache ( & self , id : CompilationId ) {
176+ remove_import_meta_env_definitions ( id) ;
177+ }
178+
124179 fn apply ( & self , ctx : & mut rspack_core:: ApplyContext < ' _ > ) -> Result < ( ) > {
125- ctx. compiler_hooks . compilation . tap ( compilation:: new ( self ) ) ;
180+ ctx
181+ . compiler_hooks
182+ . compilation
183+ . tap ( collect_import_meta_env_definitions:: new ( self ) ) ;
184+ ctx
185+ . compiler_hooks
186+ . compilation
187+ . tap ( finalize_import_meta_env_definitions:: new ( self ) ) ;
126188 ctx
127189 . normal_module_factory_hooks
128190 . parser
0 commit comments