use super::config_parser;
use super::{Plugin, PluginResult};
const ENABLERS: &[&str] = &["rolldown"];
const CONFIG_PATTERNS: &[&str] = &["rolldown.config.{js,cjs,mjs,ts,mts,cts}"];
const ALWAYS_USED: &[&str] = &["rolldown.config.{js,cjs,mjs,ts,mts,cts}"];
const TOOLING_DEPENDENCIES: &[&str] = &["rolldown", "@rolldown/pluginutils"];
define_plugin! {
struct RolldownPlugin => "rolldown",
enablers: ENABLERS,
config_patterns: CONFIG_PATTERNS,
always_used: ALWAYS_USED,
tooling_dependencies: TOOLING_DEPENDENCIES,
resolve_config(config_path, source, _root) {
let mut result = PluginResult::default();
let imports = config_parser::extract_imports(source, config_path);
for imp in &imports {
let dep = crate::resolve::extract_package_name(imp);
result.referenced_dependencies.push(dep);
}
let inputs = config_parser::extract_config_string_or_array(source, config_path, &["input"]);
result.extend_entry_patterns(inputs);
let external =
config_parser::extract_config_shallow_strings(source, config_path, "external");
for ext in &external {
result
.referenced_dependencies
.push(crate::resolve::extract_package_name(ext));
}
result
}
}
#[cfg(test)]
mod tests {
use std::path::Path;
use super::*;
#[test]
fn resolve_config_input_string() {
let source = r#"export default { input: "./src/index.js" };"#;
let plugin = RolldownPlugin;
let result = plugin.resolve_config(
Path::new("rolldown.config.js"),
source,
Path::new("/project"),
);
assert_eq!(result.entry_patterns, vec!["./src/index.js"]);
}
#[test]
fn resolve_config_input_array() {
let source = r#"
export default {
input: ["./src/index.js", "./src/cli.js"]
};
"#;
let plugin = RolldownPlugin;
let result = plugin.resolve_config(
Path::new("rolldown.config.ts"),
source,
Path::new("/project"),
);
assert_eq!(
result.entry_patterns,
vec!["./src/index.js", "./src/cli.js"]
);
}
#[test]
fn resolve_config_input_object() {
let source = r#"
export default {
input: {
main: "./src/main.js",
utils: "./src/utils.js"
}
};
"#;
let plugin = RolldownPlugin;
let result = plugin.resolve_config(
Path::new("rolldown.config.mjs"),
source,
Path::new("/project"),
);
assert_eq!(
result.entry_patterns,
vec!["./src/main.js", "./src/utils.js"]
);
}
#[test]
fn resolve_config_external() {
let source = r#"
export default {
input: "./src/index.js",
external: ["react", "react-dom", "@scope/lib"]
};
"#;
let plugin = RolldownPlugin;
let result = plugin.resolve_config(
Path::new("rolldown.config.js"),
source,
Path::new("/project"),
);
let deps = &result.referenced_dependencies;
assert!(deps.contains(&"react".to_string()));
assert!(deps.contains(&"react-dom".to_string()));
assert!(deps.contains(&"@scope/lib".to_string()));
}
#[test]
fn resolve_config_imports() {
let source = r#"
import { defineConfig } from 'rolldown';
import pluginA from '@rolldown/pluginutils';
export default defineConfig({
input: "./src/main.ts"
});
"#;
let plugin = RolldownPlugin;
let result = plugin.resolve_config(
Path::new("rolldown.config.ts"),
source,
Path::new("/project"),
);
let deps = &result.referenced_dependencies;
assert!(deps.contains(&"rolldown".to_string()));
assert!(deps.contains(&"@rolldown/pluginutils".to_string()));
assert_eq!(result.entry_patterns, vec!["./src/main.ts"]);
}
#[test]
fn resolve_config_empty() {
let source = r"export default {};";
let plugin = RolldownPlugin;
let result = plugin.resolve_config(
Path::new("rolldown.config.js"),
source,
Path::new("/project"),
);
assert!(result.entry_patterns.is_empty());
assert!(result.referenced_dependencies.is_empty());
}
#[test]
fn resolve_config_no_input() {
let source = r#"
export default {
output: { dir: "dist" }
};
"#;
let plugin = RolldownPlugin;
let result = plugin.resolve_config(
Path::new("rolldown.config.js"),
source,
Path::new("/project"),
);
assert!(result.entry_patterns.is_empty());
}
}