use std::path::{Path, PathBuf};
use crate::configuration::DEFAULT_TSCONFIG_FILENAME;
use super::super::helpers::append_extension::append_ts_extension;
use super::super::plugins::plugins_loader::MultiNestCompilerPlugins;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct WebpackDefaults {
pub entry: PathBuf,
pub devtool: Option<String>,
pub target: String,
pub output_filename: PathBuf,
pub ignore_warnings_except: String,
pub externals: Vec<String>,
pub externals_presets_node: bool,
pub module_rules: Vec<WebpackModuleRule>,
pub resolve_extensions: Vec<String>,
pub resolve_plugins: Vec<WebpackResolvePlugin>,
pub mode: String,
pub optimization_node_env: bool,
pub node_filename: bool,
pub node_dirname: bool,
pub plugins: Vec<WebpackPluginPlan>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct WebpackModuleRule {
pub test: String,
pub loader: String,
pub transpile_only: bool,
pub config_file: PathBuf,
pub custom_transformers: bool,
pub exclude: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum WebpackResolvePlugin {
TsconfigPaths { config_file: PathBuf },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum WebpackPluginPlan {
IgnoreLazyImports { imports: Vec<String> },
ForkTsChecker { config_file: PathBuf },
}
pub fn webpack_defaults_factory(
source_root: impl AsRef<Path>,
relative_source_root: impl AsRef<Path>,
entry_filename: &str,
is_debug_enabled: bool,
ts_config_file: Option<impl AsRef<Path>>,
plugins: &MultiNestCompilerPlugins,
) -> WebpackDefaults {
let ts_config_file = ts_config_file
.map(|path| path.as_ref().to_path_buf())
.unwrap_or_else(|| PathBuf::from(DEFAULT_TSCONFIG_FILENAME));
let is_plugin_registered = plugins.is_any_plugin_registered();
let mut plugin_plans = vec![WebpackPluginPlan::IgnoreLazyImports {
imports: vec![
"@nestjs/microservices".to_string(),
"@nestjs/microservices/microservices-module".to_string(),
"@nestjs/websockets/socket-module".to_string(),
"class-validator".to_string(),
"class-transformer".to_string(),
"class-transformer/storage".to_string(),
],
}];
if !is_plugin_registered {
plugin_plans.push(WebpackPluginPlan::ForkTsChecker {
config_file: ts_config_file.clone(),
});
}
WebpackDefaults {
entry: PathBuf::from(append_ts_extension(
&source_root.as_ref().join(entry_filename).to_string_lossy(),
)),
devtool: is_debug_enabled.then(|| "inline-source-map".to_string()),
target: "node".to_string(),
output_filename: relative_source_root
.as_ref()
.join(format!("{entry_filename}.js")),
ignore_warnings_except: "CriticalDependenciesWarning".to_string(),
externals: vec!["webpack-node-externals".to_string()],
externals_presets_node: true,
module_rules: vec![WebpackModuleRule {
test: ".tsx?$".to_string(),
loader: "ts-loader".to_string(),
transpile_only: !is_plugin_registered,
config_file: ts_config_file.clone(),
custom_transformers: is_plugin_registered,
exclude: "node_modules".to_string(),
}],
resolve_extensions: vec![".tsx".to_string(), ".ts".to_string(), ".js".to_string()],
resolve_plugins: vec![WebpackResolvePlugin::TsconfigPaths {
config_file: ts_config_file,
}],
mode: "none".to_string(),
optimization_node_env: false,
node_filename: false,
node_dirname: false,
plugins: plugin_plans,
}
}