From d993c4def65b0bf900a6b8b8f0d0dee44ba8e0c8 Mon Sep 17 00:00:00 2001 From: Jonathan Rudenberg Date: Sun, 5 Feb 2023 16:35:48 -0500 Subject: [PATCH] feat(bindings/cli): Add `--config` (#6835) --- bindings/swc_cli/src/commands/compile.rs | 39 +++++++++++++++++++++--- crates/swc/src/config/mod.rs | 4 +-- crates/swc/src/plugin.rs | 2 +- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/bindings/swc_cli/src/commands/compile.rs b/bindings/swc_cli/src/commands/compile.rs index 59090afe6d13..b53d45009011 100644 --- a/bindings/swc_cli/src/commands/compile.rs +++ b/bindings/swc_cli/src/commands/compile.rs @@ -1,7 +1,7 @@ use std::{ fs::{self, File}, io::{self, Read, Write}, - path::{Path, PathBuf}, + path::{Component, Path, PathBuf}, sync::Arc, }; @@ -13,7 +13,7 @@ use rayon::prelude::*; use relative_path::RelativePath; use swc_core::{ base::{ - config::{ConfigFile, Options, SourceMapsConfig}, + config::{Config, ConfigFile, Options, PluginConfig, SourceMapsConfig}, try_with_handler, Compiler, HandlerOpts, TransformOutput, }, common::{ @@ -28,9 +28,12 @@ use crate::util::trace::init_trace; /// Configuration option for transform files. #[derive(Parser)] pub struct CompileOptions { - /// Override a config from .swcrc file. - #[clap(long)] - config: Option>, + /// Experimental: provide additional configuration to override the .swcrc. + /// Can be used to provide experimental plugin configuration, + /// including plugin imports that are explicitly relative, starting with `.` + /// or `..` + #[clap(long, value_parser = parse_config)] + config: Option, /// Path to a .swcrc file to use #[clap(long)] @@ -107,6 +110,10 @@ pub struct CompileOptions { *no_swcrc: bool, */ } +fn parse_config(s: &str) -> Result { + serde_json::from_str(s) +} + static COMPILER: Lazy> = Lazy::new(|| { let cm = Arc::new(SourceMap::new(FilePathMapping::empty())); @@ -277,10 +284,32 @@ impl CompileOptions { }); let mut options = Options { + config: self.config.to_owned().unwrap_or_default(), config_file, ..Options::default() }; + options.config.jsc.experimental.plugins = + options.config.jsc.experimental.plugins.map(|plugins| { + plugins + .into_iter() + .map(|p| { + // if the path starts with . or .., then turn it into an absolute path using + // the current working directory as the base + let path = Path::new(&p.0); + PluginConfig( + match path.components().next() { + Some(Component::CurDir) | Some(Component::ParentDir) => { + path.absolutize().unwrap().display().to_string() + } + _ => p.0, + }, + p.1, + ) + }) + .collect() + }); + if let Some(file_path) = *file_path { options.filename = file_path.to_str().unwrap_or_default().to_owned(); } diff --git a/crates/swc/src/config/mod.rs b/crates/swc/src/config/mod.rs index 731f92282643..78ee3fda6bcf 100644 --- a/crates/swc/src/config/mod.rs +++ b/crates/swc/src/config/mod.rs @@ -70,9 +70,9 @@ use swc_ecma_transforms_compat::es2015::regenerator; use swc_ecma_transforms_optimization::{inline_globals2, GlobalExprMap}; use swc_ecma_visit::{Fold, VisitMutWith}; +pub use crate::plugin::PluginConfig; use crate::{ - builder::PassBuilder, dropped_comments_preserver::dropped_comments_preserver, - plugin::PluginConfig, SwcImportResolver, + builder::PassBuilder, dropped_comments_preserver::dropped_comments_preserver, SwcImportResolver, }; #[cfg(test)] diff --git a/crates/swc/src/plugin.rs b/crates/swc/src/plugin.rs index 8b00faae3f0d..0e90f81f49a4 100644 --- a/crates/swc/src/plugin.rs +++ b/crates/swc/src/plugin.rs @@ -25,7 +25,7 @@ use swc_ecma_visit::{noop_fold_type, Fold}; /// plugin's entrypoint function. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(deny_unknown_fields, rename_all = "camelCase")] -pub struct PluginConfig(String, serde_json::Value); +pub struct PluginConfig(pub String, pub serde_json::Value); #[cfg(any(feature = "plugin", feature = "plugin-bytecheck"))] pub fn plugins(