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

feat(schematics): firebase function deployment for angular universal #2305

Merged
merged 8 commits into from
Mar 27, 2020

Conversation

mgechev
Copy link
Member

@mgechev mgechev commented Feb 1, 2020

Checklist

Description

This PR includes:

  1. Refactoring of the ng-add schematics. It decomposes the function to two separate ones responsible for static file deployments and SSR. Unfortunately, I wasn't able to get rid of the extra schematic from collection.json since currently our APIs do not allow manually persisting the Tree on the disk.
  2. Minor refactoring of the deploy builder to incorporate the functionality for server-side rendering enabled deployments.
  3. Refactoring of the tests to reflect the updated structure of ng-add and the deploy action.
  4. Implementation of deployment to Firebase functions.

This implementation supports Angular Universal version 9 and above. Originally I was thinking of checking the dependency versions manually with semver during ng deploy/ng add, but then decided that the peer dependency check that @angular/fire does might be sufficient.

Since the PR is relatively big, if you prefer I can decompose it into several smaller ones.

@jamesdaniels
Copy link
Member

I'm fine with it being one big commit. Don't see any obvious red flags, I'll give it a proper review and a test drive come Monday. Will let you know how that goes. Thanks!

@jamesdaniels
Copy link
Member

jamesdaniels commented Feb 5, 2020

Simple case seems to be working well. Going through the code.

What do you think of making the deploy process for Universal like this by default though:

  1. prerender
  2. dist/browser gets deployed to Firebase hosting
  3. dist/server gets deployed to Cloud Functions with the ** pass-through on hosting

That way all the static assets / prerenders are on the CDN w/o need for cold-start. We could also give the developer some options here:

? We detected an Angular Universal project. Would you like to prerender on deploy? Yes
? Deploy browser assets to Firebase Hosting? Yes
? Deploy server assets to Cloud Functions? Yes
UPDATE package.json (2302 bytes)
✔ Packages installed successfully.
✔ Preparing the list of your Firebase projects
? Please select a project: (Use arrow keys or type to search)
❯ Project A
  Project B
  Project C

@mgechev
Copy link
Member Author

mgechev commented Feb 5, 2020

Currently, the generated firebase.json would look like this:

{
    "target": "project",
    "public": "dist/browser",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "rewrites": [
      {
        "source": "**",
        "function": "ssr"
      }
    ]
  }
}

My understanding is that we deploy static assets to a CDN and we have the ** rewrite to a firebase function. I intentionally didn't do prerendering since I'm not sure if everyone would want to opt-into that.

@jamesdaniels
Copy link
Member

Ok, fair enough on the prerender; we can always see if that's requested later down the road.

** will cache it behind the CDN, due to the maxAge in server.ts, but only after the first time it's requested and the file hasn't been deployed to hosting. It's a reverse proxy (on cache miss) model. Deploying the static assets to hosting first would ensure that they're the freshest, even if they didn't change the filename (different eviction model), and won't be subject to coldstart...

That said, I missed that you were already deploying the browser bundle to hosting. So ignore that feedback 😃

"logs": "firebase functions:log"
},
"engines": {
"node": "8"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's beta, but what do you think of defaulting to Node 10? I think it would be a better experience out of box.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's warn/error if the engine version doesn't match their local development.

"node": "8"
},
"dependencies": {
"firebase-admin": "~7.0.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make these versions configurable, maybe look at their dev deps?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's assume latest if they don't have in their own package.json

"engines": {
"node": "8"
},
"dependencies": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way we could allow configuration of webpack externals here? E.g, libs that they don't want bundled but use in SSR

@jamesdaniels
Copy link
Member

Also general feedback, the deploy was less interactive than I would've liked. Can we pipe the output from the hosting / functions or put our own spinner / progress indicator?

Copy link
Member

@jamesdaniels jamesdaniels left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, comments are nits. Feel free to address before I cut rc.1 or we can take as action items.

@mgechev
Copy link
Member Author

mgechev commented Feb 11, 2020

Thanks for the review! I'll address some of the comments later this week. I'll probably not find the time for everything we discussed last week, but it shouldn't be a blocker for 6.0.0.

@mgechev
Copy link
Member Author

mgechev commented Feb 12, 2020

@jamesdaniels I did a few improvements:

  • Node.js version check - basically, we verify if the local node version satisfies ^10.0.0
  • Added --preview flag
  • Now we're using the versions from package.json as you suggested

This PR includes:

1. Refactoring of the `ng-add` schematics. It decomposes the function to two separate ones responsible for static file deployments and SSR. Unfortunately, I wasn't able to get rid of the extra schematic from `collection.json` since currently our APIs do not allow manually persisting the `Tree` on the disk.
2. Minor refactoring of the `deploy` builder to incorporate the functionality for server-side rendering enabled deployments.
3. Refactoring of the tests to reflect the updated structure of `ng-add` and the deploy action.
4. Implementation of deployment to Firebase functions.

This implementation supports Angular Universal version 9 and above. Originally I was thinking of checking the dependency versions manually with `semver` during `ng deploy`/`ng add`, but then decided that the peer dependency check that `@angular/fire` does might be sufficient.

Since the PR is relatively big, if you prefer I can decompose it into several smaller ones.
@michelepatrassi
Copy link

@mgechev @jamesdaniels hey thanks for the great work!

I run ng add @angular/fire for an angular universal project (here's the result commit michelepatrassi/ng-starter@370526c) and I cannot grasp two changes:

  • added devDependencies like inquirer, open, firebase-admin...why my main project would ever need them? Firebase functions are in a subfolder usually, and all dependencies are installed there
  • the externalDependencies meaning for my server app with all the firebase stuff

What are these changes solving? Does the second one maybe solves something like the externals filter done here https://gist.github.com/michelepatrassi/242f1f0a867af99918977ea64787fcee#file-webpack-server-config-js ?

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

Successfully merging this pull request may close these issues.

5 participants