vite_rust/
config.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use std::env;

use crate::utils::check_heart_beat;

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ViteMode {
    Development,
    Manifest,
}

impl ViteMode {
    pub(crate) async fn discover<'a>(use_hb: bool, use_dev_server: bool, host: &'a str) -> ViteMode {
        if !use_hb {
            return ViteMode::Development;
        }

        if !use_dev_server {
            return ViteMode::Manifest;
        }
        
        let is_production = env::vars().any(|(k, v)| {
            if ["RUST_ENV", "NODE_ENV", "APP_ENV"].contains(&k.as_str()) {
                return v.parse::<bool>().unwrap_or(false);
            }

            return false;
        });

        if is_production { return ViteMode::Manifest; }
        
        let dev_server_is_ok = check_heart_beat(host, None).await;

        match dev_server_is_ok {
            true => ViteMode::Development,
            false => ViteMode::Manifest,
        }
    }
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ViteConfig<'a> {
    /// The `path/to/manifest.json` file.
    /// Currently, Vite won't resolve relative paths, so please consider
    /// your current working directory as the root of it and start the path
    /// with a root node directory directly.
    /// 
    /// **Optionally and experimentally**, you can use the [`resolve_path`]
    /// method for the manifest file resolution. However, this method might
    /// come to fail at some point, and will also panic in the many situations
    /// described on its documentation.
    /// 
    /// # Example
    /// ```plaintext
    /// your_project/
    /// |-- public/
    /// |   |-- dist/
    /// |   |   |-- manifest.json
    /// |-- src/
    /// |   |-- main.rs // <-- you're here!
    /// ```
    /// 
    /// ```ignore
    /// 
    /// use vite_rust::{ViteConfig, utils::resolve_path};
    /// 
    /// let config = ViteConfig {
    ///     manifest_path: "public/dist/manifest.json",
    ///     // or
    ///     manifest_path: resolve_path(file!(), "../public/dist/manifest.json"),
    ///     // ...
    /// };
    /// ```
    pub manifest_path: &'a str,
    /// Defines which entrypoints Vite will use to generate the html `script`,
    /// `link` and `stylesheet` tags.
    /// 
    /// If `None` is provided, Vite will scan the manifest for files with
    /// `isEntry: true` property and consider them the entrypoints.
    pub entrypoints: Option<Vec<&'a str>>,
    /// If `None` is provided, Vite will discover which one to use considering:
    /// -   any of `RUST_ENV`, `NODE_ENV` or `APP_ENV` environment variables exists
    ///     and is set to `true`;
    /// -   Dev-server is running;
    /// -   Heart beat check is enabled.
    /// 
    /// By setting this option, the discovering phase will be skipped.
    /// Refer to the crate's `README.md` file to understand the way it decides which mode to pick.
    pub force_mode: Option<ViteMode>,
    /// Whether Vite should ping your vite dev-server to check if its running.
    /// If false, `ViteMode` will be set to `Development` if not forced by the configuration.
    pub use_heart_beat_check: bool,
    /// Whether dev server should be considered or not.
    /// 
    /// If false, `force_mode` should be either `Manifest` or `None`,
    /// otherwise, undefined behavior might occur.
    pub enable_dev_server: bool,
    /// The host in which your vite dev-server is running.
    /// Normally, it would be `"http://localhost:5173"`.
    /// 
    /// Please, do not forget the protocol (http, https)!
    pub server_host: Option<&'a str>,
}

impl<'a> ViteConfig<'a> {
    /// Create a `ViteConfig` instance.
    /// 
    /// You can create your config by directly instantiating the struct, or
    /// by using some default options and defining only the most critical fields:
    /// 
    /// # Example
    /// ```rust
    /// use vite_rust::ViteConfig;
    /// 
    /// let manual_config = ViteConfig {
    ///     manifest_path: "path/to/manifest.json",
    ///     entrypoints: None, // Vite can discover them by itself
    ///     force_mode: None, // Vite can discover it too
    ///     use_heart_beat_check: true,
    ///     enable_dev_server: true,
    ///     server_host: Some("http://localhost:5173")
    /// };
    /// 
    /// let with_defaults_config = ViteConfig::new_with_defaults("path/to/manifest.json");
    /// 
    /// assert_eq!(manual_config, with_defaults_config);
    /// ```
    pub fn new_with_defaults(manifest_path: &'a str) -> Self {
        ViteConfig {
            enable_dev_server: true,
            entrypoints: None,
            manifest_path,
            force_mode: None,
            server_host: Some("http://localhost:5173"),
            use_heart_beat_check: true,
        }
    }
}