Skip to content

Commit

Permalink
feat: switch to oxc-resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
xusd320 committed Feb 27, 2024
1 parent 55a3222 commit e6d0e0f
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 268 deletions.
231 changes: 106 additions & 125 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ md5 = "0.7.0"
mdxjs = "0.1.14"
merge-source-map = "1.2.0"
mime_guess = "2.0.4"
nodejs-resolver = "0.0.88"
notify = { version = "6.1.1", default-features = false, features = ["macos_kqueue"] }
notify-debouncer-full = { version = "0.3.1", default-features = false }
path-clean = "1.0.1"
Expand Down
4 changes: 2 additions & 2 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ pub use swc_core::ecma::{
pub use {
anyhow, base64, cached, clap, colored, config, convert_case, fs_extra, futures, glob, hyper,
hyper_staticfile, hyper_tungstenite, indexmap, lazy_static, md5, mdxjs, merge_source_map,
mime_guess, nodejs_resolver, notify, notify_debouncer_full, path_clean, pathdiff, petgraph,
rayon, regex, sailfish, serde, serde_json, serde_xml_rs, serde_yaml, svgr_rs, swc_emotion,
mime_guess, notify, notify_debouncer_full, path_clean, pathdiff, petgraph, rayon, regex,
sailfish, serde, serde_json, serde_xml_rs, serde_yaml, svgr_rs, swc_emotion,
swc_error_reporters, swc_node_comments, thiserror, tokio, tokio_tungstenite, toml, tracing,
tracing_subscriber, tungstenite, twox_hash,
};
Expand Down
15 changes: 8 additions & 7 deletions crates/mako/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ path = "src/main.rs"
test = false

[dependencies]
cached = { workspace = true }
glob-match = "0.2.1"
mako_core = { path = "../core" }
miette = { version = "5.10.0", features = ["fancy"] }
serde = { workspace = true }
serde_json = { workspace = true }
swc_core = { workspace = true, features = ["swc_ecma_quote_macros"] }
cached = { workspace = true }
glob-match = "0.2.1"
mako_core = { path = "../core" }
miette = { version = "5.10.0", features = ["fancy"] }
oxc_resolver = "1.5.4"
serde = { workspace = true }
serde_json = { workspace = true }
swc_core = { workspace = true, features = ["swc_ecma_quote_macros"] }

[target.'cfg(not(target_os = "linux"))'.dependencies]
mimalloc-rust = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/mako/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ module.exports = new Promise((resolve, reject) => {{
let has_side_effects = if let Some(ResolverResource::Resolved(ResolvedResource(x))) =
task.parent_resource.clone()
{
if let Some(d) = &x.description {
if let Some(d) = &x.package_json() {
has_side_effects(d)
} else {
true
Expand Down
18 changes: 8 additions & 10 deletions crates/mako/src/optimize_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::collections::HashMap;
use std::string::String;

use mako_core::indexmap::{IndexMap, IndexSet};
use mako_core::nodejs_resolver::Resource;
use mako_core::regex::Regex;
use mako_core::tracing::debug;

Expand Down Expand Up @@ -300,19 +299,18 @@ impl Compiler {
Some(ModuleInfo {
resolved_resource:
Some(ResolverResource::Resolved(ResolvedResource(
Resource {
description: Some(module_desc),
..
},
resolution,
))),
..
}),
..
}) => module_desc.data().raw().get("name"),
_ => None,
}
.map(|n| n.as_str().unwrap())
.unwrap_or("unknown");
}) => resolution.package_json().map_or("unknown", |json| {
json.raw_json()
.get("name")
.map_or("unknown", |n| n.as_str().unwrap())
}),
_ => "unknown",
};

let module_size = module_graph.get_module(mtc.0).unwrap().get_module_size();

Expand Down
165 changes: 59 additions & 106 deletions crates/mako/src/resolve.rs → crates/mako/src/resolve/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use std::collections::{HashMap, HashSet};
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use std::vec;

use cached::proc_macro::cached;
use mako_core::anyhow::{anyhow, Result};
use mako_core::convert_case::{Case, Casing};
use mako_core::nodejs_resolver::{AliasMap, Options, ResolveResult, Resolver, Resource};
use mako_core::regex::{Captures, Regex};
use mako_core::thiserror::Error;
use mako_core::tracing::debug;
use oxc_resolver::{Alias, AliasValue, ResolveError as OxcResolveError, ResolveOptions, Resolver};

mod resource;
pub(crate) use resource::{ExternalResource, ResolvedResource, ResolverResource};

use crate::compiler::Context;
use crate::config::{
Expand All @@ -20,9 +23,10 @@ use crate::module::{Dependency, ResolveType};
use crate::task::parse_path;

#[derive(Debug, Error)]
enum ResolveError {
#[error("Resolve {path:?} failed from {from:?}")]
ResolveError { path: String, from: String },
#[error("Resolve {path:?} failed from {from:?}")]
struct ResolveError {
path: String,
from: String,
}

#[derive(Debug, PartialEq, Eq, Hash)]
Expand All @@ -35,53 +39,6 @@ pub enum ResolverType {

pub type Resolvers = HashMap<ResolverType, Resolver>;

#[derive(Debug, Clone)]
pub struct ExternalResource {
pub source: String,
pub external: String,
pub script: Option<String>,
}

#[derive(Debug, Clone)]
pub struct ResolvedResource(pub Resource);

#[derive(Debug, Clone)]
pub enum ResolverResource {
External(ExternalResource),
Resolved(ResolvedResource),
Ignored,
}

impl ResolverResource {
pub fn get_resolved_path(&self) -> String {
match self {
ResolverResource::External(ExternalResource { source, .. }) => source.to_string(),
ResolverResource::Resolved(ResolvedResource(resource)) => {
let mut path = resource.path.to_string_lossy().to_string();
if resource.query.is_some() {
path = format!("{}{}", path, resource.query.as_ref().unwrap());
}
path
}
ResolverResource::Ignored => "".to_string(),
}
}
pub fn get_external(&self) -> Option<String> {
match self {
ResolverResource::External(ExternalResource { external, .. }) => Some(external.clone()),
ResolverResource::Resolved(_) => None,
ResolverResource::Ignored => None,
}
}
pub fn get_script(&self) -> Option<String> {
match self {
ResolverResource::External(ExternalResource { script, .. }) => script.clone(),
ResolverResource::Resolved(_) => None,
ResolverResource::Ignored => None,
}
}
}

pub fn resolve(
path: &str,
dep: &Dependency,
Expand Down Expand Up @@ -252,42 +209,38 @@ fn do_resolve(
let parent = path.parent().unwrap();
debug!("parent: {:?}, source: {:?}", parent, source);
let result = resolver.resolve(parent, source);
if let Ok(result) = result {
match result {
ResolveResult::Resource(resource) => {
// TODO: 只在 watch 时且二次编译时才做这个检查
// TODO: 临时方案,需要改成删除文件时删 resolve cache 里的内容
// 比如把 util.ts 改名为 util.tsx,目前应该是还有问题的
if resource.path.exists() {
Ok(ResolverResource::Resolved(ResolvedResource(Resource {
query: resource.query.or_else(|| {
// 手动为 context resolve 补全 query,因为 nodejs_resolver 不会和 enhanced-resolve 一样保留 query
// TODO: 看看能否 PR 上游后移除该逻辑
source
.split('#')
.next()
.and_then(|head| head.split('?').nth(1))
.map(|query| format!("?{}", query))
}),
..resource
})))
} else {
Err(anyhow!(ResolveError::ResolveError {
path: source.to_string(),
from: path.to_string_lossy().to_string(),
}))
}
match result {
Ok(resolution) => {
// TODO: 只在 watch 时且二次编译时才做这个检查
// TODO: 临时方案,需要改成删除文件时删 resolve cache 里的内容
// 比如把 util.ts 改名为 util.tsx,目前应该是还有问题的
if resolution.path().exists() {
Ok(ResolverResource::Resolved(ResolvedResource(resolution)))
} else {
Err(anyhow!(ResolveError {
path: source.to_string(),
from: path.to_string_lossy().to_string(),
}))
}
ResolveResult::Ignored => {
}
Err(oxc_resolve_err) => match oxc_resolve_err {
OxcResolveError::Ignored(_) => {
debug!("resolve ignored: {:?}", source);
Ok(ResolverResource::Ignored)
}
}
} else {
Err(anyhow!(ResolveError::ResolveError {
path: source.to_string(),
from: path.to_string_lossy().to_string(),
}))
_ => {
eprintln!(
"failed to resolve {} from {} with oxc-resolver err: {:?}",
source,
path.to_string_lossy(),
oxc_resolve_err
);
Err(anyhow!(ResolveError {
path: source.to_string(),
from: path.to_string_lossy().to_string(),
}))
}
},
}
}
}
Expand Down Expand Up @@ -325,73 +278,73 @@ fn get_resolver(config: &Config, resolver_type: ResolverType) -> Resolver {
let extensions = get_module_extensions();

let options = match (resolver_type, is_browser) {
(ResolverType::Cjs, true) => Options {
(ResolverType::Cjs, true) => ResolveOptions {
alias,
extensions,
condition_names: HashSet::from([
condition_names: vec![
"require".to_string(),
"module".to_string(),
"webpack".to_string(),
"browser".to_string(),
]),
],
main_fields: vec![
"browser".to_string(),
"module".to_string(),
"main".to_string(),
],
browser_field: true,
alias_fields: vec![vec!["browser".to_string()]],
..Default::default()
},
(ResolverType::Esm, true) => Options {
(ResolverType::Esm, true) => ResolveOptions {
alias,
extensions,
condition_names: HashSet::from([
condition_names: vec![
"import".to_string(),
"module".to_string(),
"webpack".to_string(),
"browser".to_string(),
]),
],
main_fields: vec![
"browser".to_string(),
"module".to_string(),
"main".to_string(),
],
browser_field: true,
alias_fields: vec![vec!["browser".to_string()]],
..Default::default()
},
(ResolverType::Esm, false) => Options {
(ResolverType::Esm, false) => ResolveOptions {
alias,
extensions,
condition_names: HashSet::from([
condition_names: vec![
"import".to_string(),
"module".to_string(),
"webpack".to_string(),
]),
],
main_fields: vec!["module".to_string(), "main".to_string()],
..Default::default()
},
(ResolverType::Cjs, false) => Options {
(ResolverType::Cjs, false) => ResolveOptions {
alias,
extensions,
condition_names: HashSet::from([
condition_names: vec![
"require".to_string(),
"module".to_string(),
"webpack".to_string(),
]),
],
main_fields: vec!["module".to_string(), "main".to_string()],
..Default::default()
},
// css must be browser
(ResolverType::Css, _) => Options {
(ResolverType::Css, _) => ResolveOptions {
extensions: vec![".css".to_string(), ".less".to_string()],
alias,
main_fields: vec!["css".to_string(), "style".to_string(), "main".to_string()],
condition_names: HashSet::from(["style".to_string()]),
condition_names: vec!["style".to_string()],
prefer_relative: true,
browser_field: true,
alias_fields: vec![vec!["browser".to_string()]],
..Default::default()
},
(ResolverType::Ctxt, _) => Options {
(ResolverType::Ctxt, _) => ResolveOptions {
alias,
resolve_to_context: true,
..Default::default()
Expand All @@ -401,19 +354,19 @@ fn get_resolver(config: &Config, resolver_type: ResolverType) -> Resolver {
Resolver::new(options)
}

fn parse_alias(alias: HashMap<String, String>) -> Vec<(String, Vec<AliasMap>)> {
fn parse_alias(alias: HashMap<String, String>) -> Alias {
let mut result = vec![];
for (key, value) in alias {
let alias_map = vec![AliasMap::Target(value)];
result.push((key, alias_map));
let alias_vec = vec![AliasValue::Path(value)];
result.push((key, alias_vec));
}
result
}

pub fn clear_resolver_cache(resolvers: &Resolvers) {
resolvers
.iter()
.for_each(|(_, resolver)| resolver.clear_entries());
.for_each(|(_, resolver)| resolver.clear_cache());
}

#[cfg(test)]
Expand Down
Loading

0 comments on commit e6d0e0f

Please sign in to comment.