-
Notifications
You must be signed in to change notification settings - Fork 0
Env as HTML Data #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Env as HTML Data #53
Conversation
…s function renaming to clarify control flow.
…(top-level index.html)
|
Would it not be much simpler (no re-rendering of the HTML document etc) to generate a |
|
@dzuelke HTML This body data attribute injection is a technique that we've been working with in Heroku Front-end engineering, and have found our current proof-of-concept used for vibes.heroku.com is performing beautifully. Problems with writing a JS file at runtime:
HTML Data attributes avoids these issues using a web-native interface which is agnostic to any JS module type or framework. |
| .or(Some(PathBuf::from(DEFAULT_DOC_ROOT))) | ||
| .expect("should always default to some value"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .or(Some(PathBuf::from(DEFAULT_DOC_ROOT))) | |
| .expect("should always default to some value"); | |
| .unwrap_or(PathBuf::from(DEFAULT_DOC_ROOT)); |
| .or(Some(DEFAULT_DOC_INDEX.to_owned())) | ||
| .expect("should always default to some value"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .or(Some(DEFAULT_DOC_INDEX.to_owned())) | |
| .expect("should always default to some value"); | |
| .unwrap_or(DEFAULT_DOC_INDEX.to_string()); |
| .or(Some(true)) | ||
| .expect("should always default to some boolean") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .or(Some(true)) | |
| .expect("should always default to some boolean") | |
| .unwrap_or(true) |
| Ok(true) => { | ||
| eprintln!("Runtime configuration written into {file_path}"); | ||
| } | ||
| _ => (), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silence for this branch?
| pub fn env_as_html_data<S: BuildHasher>( | ||
| data: &HashMap<String, String, S>, | ||
| file_path: &PathBuf, | ||
| ) -> Result<bool, Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'm having trouble following what this bool represents while reading through the code. Personally, I find enums or newtypes are a cheap way to clarify intent vs. boolean flags when it comes to both argument and return values. E.g.;
pub(crate) struct EnvInjected(bool);
// or
pub(crate) enum EnvInjected { Yes, No }
pub fn env_as_html_data<S: BuildHasher>(
data: &HashMap<String, String, S>,
file_path: &PathBuf,
) -> Result<EnvInjected, Error> { ... }| pub(crate) fn parse_html_and_inject_data<S: BuildHasher>( | ||
| data: &HashMap<String, String, S>, | ||
| html_bytes: &[u8], | ||
| ) -> Result<(bool, String), Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment as above. Given how this value is propagating, maybe an enum makes more sense because it could simplify the false path which doesn't do anything with the html doc returned but is kind of forced to return it due to the use of the tuple (bool, String). E.g.;
pub(crate) enum EnvInjected {
Yes(String),
No
}| fn match_html_body_and_inject_data<S: BuildHasher>( | ||
| data: &HashMap<String, String, S>, | ||
| node: &Handle, | ||
| ) -> Result<(bool, bool), Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this boolean tuple is the most confusing 😅
Looking at the signature of the function, I have no clue what boolean 1 represents nor boolean 2 without reading the implementation and how the return values are used. I imagine this same will be true for anyone returning to this code in a week or two.
It also makes it hard to spot during review if someone changes this code in the future and accidentally confuses boolean 2 with boolean 1 in the return value.
| "ENV_AS_HTML_DATA_TARGET_FILES", | ||
| default_doc_path, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The environment variable (and usage in the env-as-html-data binary) implies that multiple files can be processed but only one is set here? How does this work when there are multiple HTML files in the static site? Is the user expected to manually configure each? Can they use a glob pattern?
| std::process::exit(1); | ||
| }).map(|v| v.split(',').collect()).expect("should exit failure when none"); | ||
|
|
||
| for file_path in file_paths { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may also be a good idea to only process files found within the app's workspace directory.
A new approach to keeping config vars fresh at runtime 🍃
See rendered README doc:
Heroku Cloud Native Static Web Server Buildpack: Runtime App Configuration.
This will be a major version bump to
v2.0.0, because all Release Phase integration is being dropped. This major version should not require any migration/upgrading docs, because this CNB project is still warned as experimental on the front-page README.