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

Parse entry point of index.html and rewrite JS for serverless injection #58

Closed
nothingismagick opened this issue Nov 20, 2019 · 4 comments

Comments

@nothingismagick
Copy link
Sponsor Member

Is your feature request related to a problem? Please describe.
The problem is that different frameworks use different strategies for JS injection in the root app. In the serverless distribution type, we need to do some slight transformation to the JS in order to properly inject it.

Describe the solution you'd like
At build time (not dev because that is really served via webpack) we need to parse the source of the index.html for JS and transform the JS for injection. On a sidenote, this is also where we can inject the CSP meta value.

Describe alternatives you've considered
There are a couple of alternatives:

  1. Write a type of app extension for every framework. This might be a stopgap solution if we can't get DOM / AST parsing to work the way we need it to. It would probably entail handcrafting the tauri entry index.html file, and it strikes me as the most brittle and error-prone.
  2. Whitelist types of frameworks - which defeats the notion of being agnostic in serverless, which is really the claim to fame.

Additional context
In an earlier iteration I hand-crafted the entry file and totally ignored the index.html file that was shipping. Here is the example:

#[cfg(feature = "serverless")]
    {
      fn inline_style(s: &str) -> String {
        format!(r#"<style type="text/css">{}</style>"#, s)
      }

      fn inline_script(s: &str) -> String {
        format!(r#"<script type="text/javascript">{}</script>"#, s)
      }
      let html = format!(r#"<!DOCTYPE html><html><head><meta http-equiv="Content-Security-Policy" content="default-src data: filesystem: 'unsafe-eval' 'unsafe-inline'">{styles}</head><body><div id="q-app"></div>{scripts}</body></html>"#,
    styles = inline_style(include_str!("../target/compiled-web/css/app.css")),
    scripts = inline_script(include_str!("../target/compiled-web/js/app.js")),
  );
      content = tauri_ui::Content::Html(html);
    }
let webview = tauri_ui::builder()
  .title("Tauri POC")
  .size(800, 600)
  .resizable(true)
  .debug(debug)
  .content(content)
@nothingismagick
Copy link
Sponsor Member Author

nothingismagick commented Nov 20, 2019

As part of the build step, I sort of feel like the best approach will be to use node to parse the HTML using JSDOM something like this:

    const filePath = path.resolve(__dirname, `${theIndex.html}`)
    const readInterface = readline.createInterface({
      input: fs.createReadStream(`${filePath}`),
      terminal: false
    })
    readInterface.forEach((line) => {
      const { document } = (new JSDOM(line)).window
      let el = document.querySelector('script')
      ...
    }).catch(e => {
        console.log(e)
    }).finally(() => {
      // magick
    })

But obviously readLIne won't work all the time, so its just a preliminary sketch.

@nothingismagick
Copy link
Sponsor Member Author

nothingismagick commented Nov 20, 2019

Well, maybe the approach we can use to make the monolith here is to mung the index.html, looking for JS files and just directly inlining them. Whether or not we'd need to actually destructure dynamicImports is something to look at too.

@lucasfernog
Copy link
Member

We are making some progress on the feature/iframe branch, it might be the best solution.

@nothingismagick
Copy link
Sponsor Member Author

@lucasfernog - I think that the merge of features/no-server resolves this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants