Skip to content

Commit

Permalink
fix: simplify loader config
Browse files Browse the repository at this point in the history
  • Loading branch information
ClarkXia committed Nov 28, 2023
1 parent 78e8b83 commit 5e5fc9c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 21 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/loader_compilation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ rspack_core = { path = "../.rspack_crates/rspack_core" }
rspack_error = { path = "../.rspack_crates/rspack_error" }
rspack_loader_runner = { path = "../.rspack_crates/rspack_loader_runner" }
rspack_plugin_javascript = { path = "../.rspack_crates/rspack_plugin_javascript" }
rspack_regex = { path = "../.rspack_crates/rspack_regex" }
regex = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = "1.0.100"
Expand Down
40 changes: 38 additions & 2 deletions crates/loader_compilation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,44 @@ use rspack_loader_runner::{Identifiable, Identifier, Loader, LoaderContext};
use rspack_error::{
internal_error, Result, Diagnostic,
};
use swc_core::{base::config::{InputSourceMap, Options, OutputCharset, Config, TransformConfig}, ecma::transforms::react::Runtime};
use swc_core::{
base::config::{InputSourceMap, Options, OutputCharset, Config, TransformConfig},
ecma::parser::{Syntax, TsConfig},
};

use swc_config::{config_types::MergingOption, merge::Merge};
use rspack_plugin_javascript::{
ast::{self, SourceMapConfig},
TransformOutput,
};
use serde::Deserialize;
use rspack_regex::RspackRegex;

mod compiler;
mod transform;

use transform::*;
use compiler::{SwcCompiler, IntoJsAst};

#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct CompileRules {
// Built-in rules to exclude files from compilation, such as react, react-dom, etc.
exclude: Option<Vec<String>>,
}

#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct LoaderOptions {
pub swc_options: Config,
pub transform_features: TransformFeatureOptions,
pub compile_rules: CompileRules,
}

pub struct CompilationOptions {
swc_options: Options,
transform_features: TransformFeatureOptions,
compile_rules: CompileRules,
}
pub struct CompilationLoader {
identifier: Identifier,
Expand All @@ -40,12 +55,14 @@ pub const COMPILATION_LOADER_IDENTIFIER: &str = "builtin:compilation-loader";
impl From<LoaderOptions> for CompilationOptions {
fn from(value: LoaderOptions) -> Self {
let transform_features = TransformFeatureOptions::default();
let compile_rules = CompileRules::default();
CompilationOptions {
swc_options: Options {
config: value.swc_options,
..Default::default()
},
transform_features,
compile_rules,
}
}
}
Expand Down Expand Up @@ -74,6 +91,17 @@ lazy_static! {
impl Loader<LoaderRunnerContext> for CompilationLoader {
async fn run(&self, loader_context: &mut LoaderContext<'_, LoaderRunnerContext>) -> Result<()> {
let resource_path = loader_context.resource_path.to_path_buf();

if self.loader_options.compile_rules.exclude.is_some() {
let exclude = self.loader_options.compile_rules.exclude.as_ref().unwrap();
for pattern in exclude {
let pattern = RspackRegex::new(pattern).unwrap();
if pattern.test(&resource_path.to_string_lossy()) {
return Ok(());
}
}
}

let Some(content) = std::mem::take(&mut loader_context.content) else {
return Err(internal_error!("No content found"));
};
Expand All @@ -84,7 +112,15 @@ impl Loader<LoaderRunnerContext> for CompilationLoader {
let mut transform = TransformConfig::default();
let default_development = matches!(loader_context.context.options.mode, Mode::Development);
transform.react.development = Some(default_development);
transform.react.runtime = Some(Runtime::Automatic);
swc_options
.config
.jsc
.transform
.merge(MergingOption::from(Some(transform)));
}

if resource_path.ends_with(".tsx") {
swc_options.config.jsc.syntax = Some(Syntax::Typescript(TsConfig { tsx: true, decorators: true, ..Default::default() }));
}

if let Some(pre_source_map) = std::mem::take(&mut loader_context.source_map) {
Expand Down
25 changes: 6 additions & 19 deletions crates/loader_compilation/src/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,11 @@ fn match_app_entry(resource_path: &Path) -> bool {
regex_for_app.is_match(resource_path_str)
}

#[derive(Default, Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct KeepExportOptions {
pub export_names: Vec<String>,
}

#[derive(Default, Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct RemoveExportOptions {
pub remove_names: Vec<String>,
}


#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct TransformFeatureOptions {
pub keep_export: Option<KeepExportOptions>,
pub remove_export: Option<RemoveExportOptions>,
pub keep_export: Option<Vec<String>>,
pub remove_export: Option<Vec<String>>,
}

pub(crate) fn transform<'a>(
Expand All @@ -106,8 +93,8 @@ pub(crate) fn transform<'a>(
feature_options: &TransformFeatureOptions,
) -> impl Fold + 'a {
chain!(
either!(feature_options.keep_export, |options: &KeepExportOptions| {
let mut exports_name = options.export_names.clone();
either!(feature_options.keep_export, |options: &Vec<String>| {
let mut exports_name = options.clone();
// Special case for app entry.
// When keep pageConfig, we should also keep the default export of app entry.
if match_app_entry(resource_path) && exports_name.contains(&String::from("pageConfig")) {
Expand All @@ -117,8 +104,8 @@ pub(crate) fn transform<'a>(
}, || {
match_app_entry(resource_path) || match_route_entry(resource_path, routes_config)
}),
either!(feature_options.remove_export, |options: &RemoveExportOptions| {
remove_export(options.remove_names.clone())
either!(feature_options.remove_export, |options: &Vec<String>| {
remove_export(options.clone())
}, || {
// Remove export only work for app entry and route entry.
match_app_entry(resource_path) || match_route_entry(resource_path, routes_config)
Expand Down

0 comments on commit 5e5fc9c

Please sign in to comment.