Skip to content

Commit

Permalink
feat: full support dynamic entry
Browse files Browse the repository at this point in the history
  • Loading branch information
wre232114 committed Jan 13, 2025
1 parent b2545b8 commit 43bfce4
Show file tree
Hide file tree
Showing 43 changed files with 1,017 additions and 551 deletions.
13 changes: 12 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion crates/compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ farmfe_plugin_json = { path = "../plugin_json", version = "0.0.13" }
farmfe_plugin_polyfill = { path = "../plugin_polyfill", version = "0.0.13" }
farmfe_plugin_progress = { path = "../plugin_progress", version = "0.0.13" }
farmfe_plugin_define = { path = "../plugin_define", version = "0.0.13" }
farmfe_plugin_bundle = { path = "../plugin_bundle", version = "0.0.7" }
# farmfe_plugin_bundle = { path = "../plugin_bundle", version = "0.0.7" }
farmfe_plugin_library = { path = "../plugin_library", version = "0.0.1" }
farmfe_testing = { path = "../macro_testing", version = "0.0.2" }

[features]
Expand Down
38 changes: 21 additions & 17 deletions crates/compiler/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,20 +480,30 @@ impl Compiler {
resolve_module_id_result,
}) => {
farm_profile_scope!(format!("new module {:?}", module.id));

if resolve_module_id_result.resolve_result.external {
// insert external module to the graph
let module_id = module.id.clone();
Self::add_module(module, &resolve_param.kind, &context);
Self::add_module(module, &context);
Self::add_edge(&resolve_param, module_id, order, &context);
return;
}

// mark entry module first after resolving
if let ResolveKind::Entry(ref name) = resolve_param.kind {
context
.module_graph
.write()
.entries
.insert(module.id.clone(), name.to_string());
module.is_entry = true;
} else if let ResolveKind::DynamicEntry { .. } = resolve_param.kind {
context
.module_graph
.write()
.dynamic_entries
.insert(module.id.clone(), resolve_param.source.clone());
module.is_dynamic_entry = true;
}

match Self::build_module(
Expand Down Expand Up @@ -525,7 +535,7 @@ impl Compiler {
fn handle_dependencies(params: HandleDependenciesParams) {
let HandleDependenciesParams {
module,
resolve_param,
mut resolve_param,
order,
deps,
thread_pool,
Expand All @@ -534,9 +544,16 @@ impl Compiler {
} = params;

let module_id = module.id.clone();
// dynamic entry modules may reset importer module, reset importer here
if let ResolveKind::DynamicEntry { no_importer, .. } = &resolve_param.kind {
if *no_importer {
resolve_param.importer = None
}
}

let immutable = module.immutable;
// add module to the graph
Self::add_module(module, &resolve_param.kind, &context);
Self::add_module(module, &context);
// add edge to the graph
Self::add_edge(&resolve_param, module_id.clone(), order, &context);

Expand Down Expand Up @@ -580,22 +597,9 @@ impl Compiler {
}

/// add a module to the module graph, if the module already exists, update it
pub(crate) fn add_module(mut module: Module, kind: &ResolveKind, context: &CompilationContext) {
pub(crate) fn add_module(module: Module, context: &CompilationContext) {
let mut module_graph = context.module_graph.write();

// mark entry module
if let ResolveKind::Entry(name) = kind {
module.is_entry = true;
module_graph
.entries
.insert(module.id.clone(), name.to_string());
} else if let ResolveKind::DynamicEntry { name, .. } = kind {
module.is_dynamic_entry = true;
module_graph
.dynamic_entries
.insert(module.id.clone(), name.to_string());
}

// check if the module already exists
if module_graph.has_module(&module.id) {
module_graph.replace_module(module);
Expand Down
60 changes: 59 additions & 1 deletion crates/compiler/src/generate/finalize_resources.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
use std::sync::Arc;

use farmfe_core::{
config::Mode, context::CompilationContext, plugin::PluginFinalizeResourcesHookParams,
config::Mode,
context::CompilationContext,
plugin::{PluginFinalizeResourcesHookParams, PluginHandleEntryResourceHookParams},
resource::{Resource, ResourceType},
HashMap,
};

pub fn finalize_resources(context: &Arc<CompilationContext>) -> farmfe_core::error::Result<()> {
{
let mut resources_map = context.resources_map.lock();

handle_entry_resource(&mut resources_map, context)?;

let mut param = PluginFinalizeResourcesHookParams {
resources_map: &mut resources_map,
config: &context.config,
Expand Down Expand Up @@ -45,3 +51,55 @@ pub fn finalize_resources(context: &Arc<CompilationContext>) -> farmfe_core::err

Ok(())
}

fn handle_entry_resource(
resources_map: &mut HashMap<String, Resource>,
context: &Arc<CompilationContext>,
) -> farmfe_core::error::Result<()> {
let module_graph = context.module_graph.read();
let module_group_graph = context.module_group_graph.read();
let resource_pot_map = context.resource_pot_map.read();

for (entry_module_id, _) in &module_graph.entries {
let module = module_graph.module(entry_module_id).unwrap();

for resource_pot in &module.resource_pots {
let resource_pot = resource_pot_map.resource_pot(resource_pot).unwrap();

let mut params = PluginHandleEntryResourceHookParams {
resource: Resource::default(),
resource_source_map: None,
module_graph: &module_graph,
module_group_graph: &module_group_graph,
entry_module_id,
};

for resource_name in resource_pot.resources() {
// get resource from resources_map
let resource = resources_map.get_mut(resource_name).unwrap();
let resource = std::mem::replace(resource, Resource::default());

if let ResourceType::Js = &resource.resource_type {
params.resource = resource;
} else if let ResourceType::SourceMap(_) = &resource.resource_type {
params.resource_source_map = Some(resource);
}
}

context
.plugin_driver
.handle_entry_resource(&mut params, context)?;

// write entry resource back to resources_map
let resource = resources_map.get_mut(&params.resource.name).unwrap();
*resource = params.resource;

if let Some(resource) = params.resource_source_map {
let resource = resources_map.get_mut(&resource.name).unwrap();
*resource = resource.clone();
}
}
}

Ok(())
}
7 changes: 6 additions & 1 deletion crates/compiler/src/generate/partial_bundling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub fn fill_necessary_fields_for_resource_pot(

if module_graph.entries.contains_key(module_id) {
if entry_module.is_some() {
panic!("a resource pot can only have one entry module, but both {:?} and {:?} are entry modules", entry_module.unwrap(), module_id);
panic!("a resource pot({}) can only have one entry module, but both {:?} and {:?} are entry modules", resource_pot.id, entry_module.unwrap(), module_id);
}
entry_module = Some(module_id.clone());
}
Expand Down Expand Up @@ -192,6 +192,11 @@ fn generate_enforce_resource_pots(

// generate enforce resource pots first
for g in module_group_graph.module_groups() {
// skip dynamic entry module group
if matches!(g.module_group_type, ModuleGroupType::DynamicEntry) {
continue;
}

for module_id in g.modules() {
// ignore external module
if module_graph.module(module_id).unwrap().external {
Expand Down
7 changes: 6 additions & 1 deletion crates/compiler/src/generate/render_resource_pots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub fn render_resource_pots_and_generate_resources(

let resources = Mutex::new(vec![]);
let entries = context.module_graph.read().entries.clone();
let dynamic_entries = context.module_graph.read().dynamic_entries.clone();

let mut resource_pots_need_render = vec![];

Expand Down Expand Up @@ -88,7 +89,11 @@ pub fn render_resource_pots_and_generate_resources(
if r.should_transform_output_filename {
let content_with_extra_content_hash = &[&r.bytes, augment_resource_hash_bytes].concat();
if let Some(name) = resource_pot.entry_module.as_ref() {
let entry_name = entries.get(name).unwrap();
let entry_name = entries
.get(name)
.or_else(|| dynamic_entries.get(name))
.unwrap();

r.name = transform_output_entry_filename(
context.config.output.entry_filename.clone(),
resource_pot.id.to_string().as_str(),
Expand Down
2 changes: 1 addition & 1 deletion crates/compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Compiler {
/// The params are [farmfe_core::config::Config] and dynamic load rust plugins and js plugins [farmfe_core::plugin::Plugin]
pub fn new(config: Config, mut plugin_adapters: Vec<Arc<dyn Plugin>>) -> Result<Self> {
let render_plugin: Arc<dyn Plugin> = if config.output.target_env.is_library() {
Arc::new(farmfe_plugin_bundle::FarmPluginBundle::new()) as _
Arc::new(farmfe_plugin_library::FarmPluginLibrary::new(&config)) as _
} else {
Arc::new(farmfe_plugin_runtime::FarmPluginRuntime::new(&config)) as _
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ fn test_patch_module_graph_add_remove_dynamic_entry() {
kind: ResolveKind::DynamicEntry {
name: "AD".to_string(),
output_filename: None,
no_importer: false,
},
..Default::default()
}]),
Expand All @@ -454,6 +455,7 @@ fn test_patch_module_graph_add_remove_dynamic_entry() {
kind: ResolveKind::DynamicEntry {
name: "BH".to_string(),
output_filename: None,
no_importer: false,
},
..Default::default()
}]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ fn test_patch_module_group_graph_dynamic_entry_complex() {
kind: ResolveKind::DynamicEntry {
name: "AD".to_string(),
output_filename: None,
no_importer: false,
},
..Default::default()
}]),
Expand All @@ -43,6 +44,7 @@ fn test_patch_module_group_graph_dynamic_entry_complex() {
kind: ResolveKind::DynamicEntry {
name: "EI".to_string(),
output_filename: None,
no_importer: false,
},
..Default::default()
}]),
Expand Down Expand Up @@ -170,6 +172,7 @@ fn test_patch_module_group_graph_dynamic_entry_update_dynamic_entry() {
kind: ResolveKind::DynamicEntry {
name: "AD".to_string(),
output_filename: None,
no_importer: false,
},
..Default::default()
}]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,20 @@ fn get_affected_modules(
context: &Arc<CompilationContext>,
) -> Vec<ModuleId> {
let module_group_graph = context.module_group_graph.read();
// let mut enforce_resource_pots = HashSet::new();

module_groups
.iter()
.fold(HashSet::default(), |mut acc, module_group_id| {
let module_group = module_group_graph.module_group(module_group_id).unwrap();
acc.extend(module_group.modules().clone());

// ignore dynamic entry module group
if !matches!(
module_group.module_group_type,
ModuleGroupType::DynamicEntry
) {
acc.extend(module_group.modules().clone());
}

acc
})
.into_iter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ fn test_generate_and_diff_resource_pots() {
kind: ResolveKind::DynamicEntry {
name: "EI".to_string(),
output_filename: None,
no_importer: false,
},
..Default::default()
}]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ fn test_handle_dynamic_entry_resource_pots() {
kind: farmfe_core::plugin::ResolveKind::DynamicEntry {
name: "BH".to_string(),
output_filename: None,
no_importer: false,
},
..Default::default()
}]),
Expand Down
1 change: 0 additions & 1 deletion crates/compiler/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ pub fn generate_runtime(crate_path: PathBuf) -> Box<RuntimeConfig> {
.join("fixtures")
.join("_internal")
.join("runtime")
.join("index.js")
.to_string_lossy()
.to_string();

Expand Down
1 change: 0 additions & 1 deletion crates/compiler/tests/fixtures/_internal/runtime/index.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('module_system.ts');
4 changes: 4 additions & 0 deletions crates/core/src/module/meta_data/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,8 @@ impl ModuleSystem {
ModuleSystem::Custom(_) => module_system,
}
}

pub fn contains_commonjs(&self) -> bool {
matches!(self, ModuleSystem::CommonJs | ModuleSystem::Hybrid)
}
}
5 changes: 5 additions & 0 deletions crates/core/src/module/meta_data/script/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,16 @@ impl SwcId {
#[cache_item]
#[serde(rename_all = "camelCase")]
pub enum ImportSpecifierInfo {
/// import * as foo from 'foo';
Namespace(SwcId),
/// import { foo, bar as zoo } from 'foo';
Named {
/// foo or zoo in `import { foo, bar as zoo } from 'foo';`
local: SwcId,
/// bar in `import { foo, bar as zoo } from 'foo';`
imported: Option<SwcId>,
},
/// import foo from 'foo';
Default(SwcId),
}

Expand Down
3 changes: 3 additions & 0 deletions crates/core/src/plugin/hooks/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub enum ResolveKind {
name: String,
/// the same as config.output.filename, default to config.output.filename
output_filename: Option<String>,
/// disable importer of the dynamic entry. for example if b.ts is a dynamic entry return by a.ts, then a.ts is the importer of b.ts by default,
/// if you want a isolate dynamic entry, you can set this field to true
no_importer: bool,
},
/// static import, e.g. `import a from './a'`
#[default]
Expand Down
3 changes: 2 additions & 1 deletion crates/core/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,8 @@ pub struct PluginFinalizeResourcesHookParams<'a> {
}

pub struct PluginHandleEntryResourceHookParams<'a> {
pub resource: &'a mut Resource,
pub resource: Resource,
pub resource_source_map: Option<Resource>,
pub module_graph: &'a ModuleGraph,
pub module_group_graph: &'a ModuleGroupGraph,
pub entry_module_id: &'a ModuleId,
Expand Down
1 change: 0 additions & 1 deletion crates/core/src/resource/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use heck::AsLowerCamelCase;

use farmfe_macro_cache_item::cache_item;
use resource_pot::ResourcePotType;

use crate::module::ModuleId;

Expand Down
Loading

0 comments on commit 43bfce4

Please sign in to comment.