Skip to main content

cli/lib/compiler/defaults/
webpack_defaults.rs

1//! Upstream source: `../nest-cli/lib/compiler/defaults/webpack-defaults.ts`.
2
3use std::path::{Path, PathBuf};
4
5use crate::configuration::DEFAULT_TSCONFIG_FILENAME;
6
7use super::super::helpers::append_extension::append_ts_extension;
8use super::super::plugins::plugins_loader::MultiNestCompilerPlugins;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct WebpackDefaults {
12    pub entry: PathBuf,
13    pub devtool: Option<String>,
14    pub target: String,
15    pub output_filename: PathBuf,
16    pub ignore_warnings_except: String,
17    pub externals: Vec<String>,
18    pub externals_presets_node: bool,
19    pub module_rules: Vec<WebpackModuleRule>,
20    pub resolve_extensions: Vec<String>,
21    pub resolve_plugins: Vec<WebpackResolvePlugin>,
22    pub mode: String,
23    pub optimization_node_env: bool,
24    pub node_filename: bool,
25    pub node_dirname: bool,
26    pub plugins: Vec<WebpackPluginPlan>,
27}
28
29#[derive(Clone, Debug, PartialEq, Eq)]
30pub struct WebpackModuleRule {
31    pub test: String,
32    pub loader: String,
33    pub transpile_only: bool,
34    pub config_file: PathBuf,
35    pub custom_transformers: bool,
36    pub exclude: String,
37}
38
39#[derive(Clone, Debug, PartialEq, Eq)]
40pub enum WebpackResolvePlugin {
41    TsconfigPaths { config_file: PathBuf },
42}
43
44#[derive(Clone, Debug, PartialEq, Eq)]
45pub enum WebpackPluginPlan {
46    IgnoreLazyImports { imports: Vec<String> },
47    ForkTsChecker { config_file: PathBuf },
48}
49
50pub fn webpack_defaults_factory(
51    source_root: impl AsRef<Path>,
52    relative_source_root: impl AsRef<Path>,
53    entry_filename: &str,
54    is_debug_enabled: bool,
55    ts_config_file: Option<impl AsRef<Path>>,
56    plugins: &MultiNestCompilerPlugins,
57) -> WebpackDefaults {
58    let ts_config_file = ts_config_file
59        .map(|path| path.as_ref().to_path_buf())
60        .unwrap_or_else(|| PathBuf::from(DEFAULT_TSCONFIG_FILENAME));
61    let is_plugin_registered = plugins.is_any_plugin_registered();
62    let mut plugin_plans = vec![WebpackPluginPlan::IgnoreLazyImports {
63        imports: vec![
64            "@nestjs/microservices".to_string(),
65            "@nestjs/microservices/microservices-module".to_string(),
66            "@nestjs/websockets/socket-module".to_string(),
67            "class-validator".to_string(),
68            "class-transformer".to_string(),
69            "class-transformer/storage".to_string(),
70        ],
71    }];
72
73    if !is_plugin_registered {
74        plugin_plans.push(WebpackPluginPlan::ForkTsChecker {
75            config_file: ts_config_file.clone(),
76        });
77    }
78
79    WebpackDefaults {
80        entry: PathBuf::from(append_ts_extension(
81            &source_root.as_ref().join(entry_filename).to_string_lossy(),
82        )),
83        devtool: is_debug_enabled.then(|| "inline-source-map".to_string()),
84        target: "node".to_string(),
85        output_filename: relative_source_root
86            .as_ref()
87            .join(format!("{entry_filename}.js")),
88        ignore_warnings_except: "CriticalDependenciesWarning".to_string(),
89        externals: vec!["webpack-node-externals".to_string()],
90        externals_presets_node: true,
91        module_rules: vec![WebpackModuleRule {
92            test: ".tsx?$".to_string(),
93            loader: "ts-loader".to_string(),
94            transpile_only: !is_plugin_registered,
95            config_file: ts_config_file.clone(),
96            custom_transformers: is_plugin_registered,
97            exclude: "node_modules".to_string(),
98        }],
99        resolve_extensions: vec![".tsx".to_string(), ".ts".to_string(), ".js".to_string()],
100        resolve_plugins: vec![WebpackResolvePlugin::TsconfigPaths {
101            config_file: ts_config_file,
102        }],
103        mode: "none".to_string(),
104        optimization_node_env: false,
105        node_filename: false,
106        node_dirname: false,
107        plugins: plugin_plans,
108    }
109}