Skip to content
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

Option to inline CSS and Javascript #28

Open
kellpossible opened this issue Aug 30, 2020 · 14 comments
Open

Option to inline CSS and Javascript #28

kellpossible opened this issue Aug 30, 2020 · 14 comments
Labels
assets Build pipelines for specific asset types enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed ready Ready to be implemented

Comments

@kellpossible
Copy link

When working on web-view based desktop application, you don't have access automatically to a server to serve your application front-end files, and it's a lot simpler just to pass in the entire front-end inlined as a single HTML file. It would be nice if Trunk had support for this.

@MartinKavik
Copy link
Contributor

Inlined CSS is also useful to mitigate flashing of unstyled elements during the page loading.

@thedodd
Copy link
Member

thedodd commented Aug 30, 2020

Yes, that is a great idea. I've been mulling over a possible design where we could add something like data-trunk="inline" on linked resources in the source HTML, and then trunk would see these data attrs and would modify its behavior for the specific pipeline based on the value of the attribute.

First of all, what do you all think of that as a general solution to these sorts of problems?

Secondly, before moving forward on an implementation, I would like to brain storm what other attributes/values we might want to include in the design to ensure that we land on a generalizable and mostly future-proof solution.

@thedodd thedodd added assets Build pipelines for specific asset types core enhancement New feature or request labels Aug 30, 2020
@MartinKavik
Copy link
Contributor

First of all, what do you all think of that as a general solution to these sorts of problems?

A template engine is one solution. Sooner or later you want to load different assets on prod and stage and dev, show different titles, use different API keys, set different base path, etc. For instance, I chose Handlebars for Seed Webpack quickstart - https://github.com/seed-rs/seed-quickstart-webpack/blob/master/static/index.hbs

Another solution for some cases would be a config file in combination with a simpler template "engine". Something like Trunk.prod.toml with:

optimize = "size"
inline = [ "\\.css$", "\\.js$", "\\.svg$" ]
#...

Another option is custom HTML preprocessors / hooks written in Rust or Duckscript. Something like Rust's build.rs.

Just some first ideas for brainstorming.

@thedodd thedodd added discussion This item needs some discussion needs design This item needs design work and removed assets Build pipelines for specific asset types core enhancement New feature or request labels Sep 4, 2020
@thedodd
Copy link
Member

thedodd commented Sep 4, 2020

Looks like this project made a little headway on processing CSS (imports &c) and then minifying that content: https://github.com/8176135/inline-assets-rs grand total of like 200 LOC. Could serve as a nice point of reference.

As far as the JS minification & inlining ... this might be part of a larger discussion over in #32. We'll see.

For inlining SVGs, by my analysis, this would be most useful/beneficial as part of the trunk::include! macros being planned over in #9. We could inline the SVG directly in the Rust->WASM binary so that it can be used directly in the DOM generated by the Rust app. Inlining the SVG in the HTML may not be that useful otherwise.

Good discussion, let's keep this going. We'll arrive at something actionable soon.

@kellpossible
Copy link
Author

kellpossible commented Sep 4, 2020

One solution for embedding SVGs/Images to use in the dom is to use something like rust_embed for image assets, and then base64 encode the image to place into the DOM, it's pretty easy, and when using yew one can create a custom image component to make it even simpler.

@thedodd
Copy link
Member

thedodd commented Sep 8, 2020

@kellpossible that's an excellent idea. We will probably use rust_embed as the backend for the trunk::include! macro being planned over in #9. The macro could receive an option to control inlining, something like: trunk::include!("path/to/resource.svg", inline). Still in the works though.

@thedodd
Copy link
Member

thedodd commented Sep 16, 2020

@kellpossible && @MartinKavik just out of curiosity, do you think that wasm-bindgen's inline snippets would be a good immediate-term solution? The long-term trunk::include! macro is still needed, for sure.

@kellpossible
Copy link
Author

@thedodd do inline snippets still produce separate javascript files when built?

@thedodd
Copy link
Member

thedodd commented Sep 16, 2020

@kellpossible you can do both:

  • as a separate JS file: #[wasm_bindgen(module = "/js/foo.js")]
  • as inlined JS: #[wasm_bindgen(inline_js = "export function add(a, b) { return a + b; }")]

Both of the above are just taken from the wasm-bindgen snippets page in their docs. As of Trunk 0.4.0 (just recently released), both options are supported.

@thedodd
Copy link
Member

thedodd commented Oct 6, 2020

Just as a quick follow-up, once #73 lands, we will be able to add a simple data attr to linked css or JS files to control this behavior. Something like: <link data-trunk rel="js" href="path/to/code.js" data-inline />, and same for rel="css".

@thedodd thedodd added this to the 0.7.x | TBD milestone Oct 6, 2020
@thedodd thedodd added assets Build pipelines for specific asset types enhancement New feature or request help wanted Extra attention is needed ready Ready to be implemented good first issue Good for newcomers and removed discussion This item needs some discussion needs design This item needs design work labels Oct 6, 2020
@kellpossible
Copy link
Author

kellpossible commented Nov 23, 2020

@kellpossible you can do both:

  • as a separate JS file: #[wasm_bindgen(module = "/js/foo.js")]
  • as inlined JS: #[wasm_bindgen(inline_js = "export function add(a, b) { return a + b; }")]

Both of the above are just taken from the wasm-bindgen snippets page in their docs. As of Trunk 0.4.0 (just recently released), both options are supported.

but don't both those examples still produce separate javascript files when they get built? I could be wrong, but I feel like the inlined js snippet gets put in a seperate js file by wasm-bindgen that gets imported as a module by the wasm loader script, rather than being inlined in the loader script? I'll need to go back and look at it again properly sometime.

@DzenanJupic
Copy link
Contributor

Is there currently a possibility to inline HTML or raw text? I have my header and footer in separate files so that I can use them via include_str!() in Rust. It would be nice to be able to inline them into index.html to prevent flashing when the WASM app loads.

@thedodd
Copy link
Member

thedodd commented Dec 3, 2020

@DzenanJupic currently no. That should be a fairly simple "pipeline" type to add. With the current version of Trunk, we could just add a new link type, something like:

<link data-trunk rel="inline" href="path/to/content"/>

Trunk could then copy the exact contents of the file at href, and include it in the finalized HTML. Super easy to implemented.

@DzenanJupic would you be interested in hacking on a feature like this. It is simple enough, and isolated from the larger JS & CSS plans mentioned earlier in this thread. As such, if you are interested, you could knock out a PR and get it merged pretty quickly.

@thedodd thedodd removed this from the 0.7.x | TBD milestone Feb 1, 2021
@thedodd
Copy link
Member

thedodd commented Feb 1, 2021

Just dropping a note here for reference, we should create a new issue which describes all of the remaining work to be done based on our discussion here. I'm about to merge @DzenanJupic's #98 PR which addresses some of these items. After the new issue is open, I'll close this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assets Build pipelines for specific asset types enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed ready Ready to be implemented
Projects
None yet
Development

No branches or pull requests

4 participants