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

[Proposal] Html as entry point #419

Closed
zmitry opened this issue Sep 30, 2020 · 4 comments
Closed

[Proposal] Html as entry point #419

zmitry opened this issue Sep 30, 2020 · 4 comments

Comments

@zmitry
Copy link

zmitry commented Sep 30, 2020

I wanted to setup my story book to work with with esbuild. I was using regular cra with a few plugins before, now I switched to esbuild. I managed to migrate almost everything, I had issue with prismjs because it uses globals, some issues with emotion because it required custom jsx pragma.
So far my biggest concerns are watch mode and lack of html support.
As for html, for regular spa application workflow you usually have some public file with html which has some defintions for style and scripts import. Here is the example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="Content-Security-Policy" content="%%CSP_POLICY%%" />
    <meta name="referrer" content="no-referrer" />
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no, maximum-scale=1, minimal-ui"
    />
    <meta name="theme-color" content="#000000" />
    <meta name="mobile-web-app-capable" content="yes" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <link rel="apple-touch-icon" sizes="180x180" href="%PUBLIC_URL%/apple-touch-icon.png" />
    <link rel="icon" type="image/png" sizes="32x32" href="%PUBLIC_URL%/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/favicon-16x16.png" />
    <link rel="mask-icon" href="%PUBLIC_URL%/safari-pinned-tab.svg" color="#5bbad5" />
    <title>App</title>
  </head>

  <body>
    <noscript> You need to enable JavaScript to run this app. </noscript>
    <div id="root"></div>
  </body>
</html>

Right now to ge app working you have to do some workarounds where you copy index.html to build folder manually and hardcode index.js and index.css, also you would need to copy all the icons, fonts, styles and other dependencies.
I think we should integrate html as first class citizen for entry points. I'd consider implementing limited subset of html with only support for head and script imports and no actual body parsing.

@zmitry
Copy link
Author

zmitry commented Sep 30, 2020

It would be nice to have ability to prototype such loader using only plugins api but the problem with plugins api is that it's not clear how to add some code into processing pipeline.

@zmitry
Copy link
Author

zmitry commented Oct 3, 2020

@evanw do you think this aligns with your vision of the project. I think I can implement something like this, I could use https://godoc.org/golang.org/x/net/html as parser/tokenizer and then it will only require to find import tokens. Let me know what do you think about this.

@evanw
Copy link
Owner

evanw commented Oct 3, 2020

Yes I would like to try supporting this eventually. This issue is actually a duplicate of a much older issue about this #31, so I'm going to close this one as a duplicate of that.

Right now I'm focused on fixing code splitting, improving CSS support, and getting plugins out the door, so I wasn't planning on also taking on HTML at the same time. That seems like kind of too many balls in the air at once to me given how major a feature HTML support is. Believe me I want HTML support too but it's sort of a maximally complex file format given how it can nest other file formats inside of itself.

That's very interesting that there's a HTML5 tokenizer built into the Go standard library. I wasn't aware of that. That definitely warrants an exploration, although if something about it doesn't quite work out it's possible that it makes more sense to still rewrite it in-house given that it would be a core competency of esbuild.

It would be nice to have ability to prototype such loader using only plugins api but the problem with plugins api is that it's not clear how to add some code into processing pipeline.

I think exploring what it would take for a HTML plugin would be very valuable. There are likely other situations where the same APIs would be useful, so this is bringing up a deficiency in the plugin API. Right now you can add additional code into the processing pipeline by importing it (e.g. with import()) from plugin-generated code, but then you have to have JavaScript code to do the importing which isn't desirable in this case. What API would you need to be able to do this? Just addEntryPoint or something else too?

@evanw evanw closed this as completed Oct 3, 2020
@zmitry
Copy link
Author

zmitry commented Oct 4, 2020

From plugin developer perspective I'd need api which will allow me retrieve the value of the current chunk.
So for instance I parse the script tag which is ./src/index.js I need somehow receive path of this chunk in production build. Ideally I'd like to have also some meta like what async chunks this bundle includes so I could add some files as preload.

	plugin.AddLoader(
		api.LoaderOptions{Filter: `\.svg`, Namespace: "svg"},
		func(args api.LoaderArgs) (res api.LoaderResult, err error) {
                  imports:= parseFileImports(args.Path);
                  // here I expect parsed files with paths to output.  Or contents if it's single output.  
                  // the problem with this api that it's going to block processing pipeline  because parse file expects to get result for parserd files, so I think it's up to you to decide on this api. 
                  res:=plugin.ParseFiles(imports)
           
                 return serializeHtml(res.Path, args.Path, imports)

})

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