architect-examples / arc-example-webpack

Example arc app to show how to use webpack in your arc project.
Apache License 2.0
1 stars 0 forks source link

Guidance on single page applications and static asset handling in arc #1

Open filmaj opened 5 years ago

filmaj commented 5 years ago

I'd like to figure out how to use arc together with e.g. react to build single page apps supported by FaaS.

I think this repo is what I'm looking for, though looks like it is brand new!

Talking about this in the past with @brianleroux, I think I recall him saying that he wasn't a fan of treating single page apps as a static asset bundle, though arc seems to support that. I am confused, though, as the static guide instructs to put static assets under src/shared, however, the README in that directory in the persisting-data example app cautions to not exceed 5MB. What do?

kristoferjoseph commented 5 years ago

@filmaj I hope this update to the repo helps you. Basically you should have your build script output to the public directory. If you have the @static section filled out with bucket names Architect will upload the contents of public to s3 when you deploy.

filmaj commented 5 years ago

This has been sitting at the bottom of my github inbox for a while, sorry for the delay in responding.

Your last update to this repo is great. Thank you.

One thing I'm trying to do is have the app root route return static index.html content. I know the arc static guide (near the bottom) provides an example where the root route's lambda pulls content from S3, and then serves that up. I'm trying different approaches, and one I've settled on now is that at client-assets-build-time, the generated SPA (react in my case but could be any) index.html's css (<link>) and js (<script>) tags are munged so that they point to the right static bucket URL (depending on env), then that munged index.html content is injected into the root http route's lambda code. It's hacky and dependent on build-time assembly but seems to work so far.

I have a gist of the relevant pieces over here in case that's interesting to you: https://gist.github.com/filmaj/ded05b6cb5026f0f655eee2495206caf, it basically builds the SPA assets and changes the URLs in them to match staging or prod, depending on what you have active via ARC_DEPLOY, then stuffs the generated index.html into the get-index lambda route.

I feel like this approach is a bit faster than querying S3 from inside the lambda every time the lambda is invoked, as the static guide on arc.codes does. It does rely on a specific build pipeline, though. However I feel like now I can lean on my frontend app authoring skills a lot more, and enhance with backend APIs as needed.

kristoferjoseph commented 5 years ago

@filmaj That works as well.

My favorite approach is:

Run whatever build step you want and have it put the output in the public directory.

Then when you run deploy your js, css, images etc put on S3 for you if you have set up the @static section in your .arc file.

Then have your get / lambda return html that uses the helper function arc.http.helpers.static to figure out the S3 paths for you.

For me, this is the best of all since you can do whatever you need at request time in your lambda; like query a db or internal API, then have your pre-compiled assets hosted on a CDN and have the helper worry about environment specific urls for you.

This example repo currently does the most simple thing and uploads it all; including the index.html to S3, which limits the dynamic abilities of the lambda.

kristoferjoseph commented 5 years ago

I get that you are working on applying your current workflow to serverless with Architect so please don't be annoyed by my recommendations.

With that said, I am currently working in a manner closer to this example: https://github.com/kristoferjoseph/arc-example-templates

and it is pretty fun, not to mention it doesn't require a build step other than ⌘R

filmaj commented 5 years ago

I like the approach you suggest conceptually re: using the static helper but it really grates me that that function reads the arc file on every lambda invocation. I can't get over that 🙈. That URL shouldn't change unless npx deploy is run again. So instead I handle that at build (pre-deploy) time, rather than at lambda-runtime.

Additionally the bundler I'm using (parcel) hashes the bundled css/js filename for cachebusting, purposes, something, from what I can tell, arc lambda handlers don't really handle right now.

filmaj commented 5 years ago

I'll keep an eye on the project you linked, thanks! I think we can close this down as I don't have much more actionable stuff to come out of this. Thanks for all your help and guidance!

kristoferjoseph commented 5 years ago

I hear you and had a similar issue with cache busting.

This was one reason we started moving to dynamic end points that either returned the cached version or compiled a new one at request time.

I will work with parcel to see if I can find a more compatible way to satisfy this requirement.

Let's leave this issue open for a bit so newcomers with similar questions can join the conversation and learn from your helpful feedback.

filmaj commented 5 years ago

I plan on expanding the gist I linked to to a full starter repo, with npm scripts for building, deploying and running locally. I'll see about opening that up this week. I have one final issue to hash out in there before it's good for use.