Index Of /
Sapper and Firebase
May 30, 2019
SSR on the Firebase Hosting
To deploy this blog to the Firebase Hosting I found a great article from @eckhardtdreyer:
How to host a Sapper.js SSR app on Firebase.
Just follow the instructions and you'll have a working svelte/sapper and server-rendered website in a few minutes.
Importing Firebase
The only problem I've got was Firebase library itself. When imported it for the first time:
import firebase from "firebase/app";
...
in the terminal the following message appeared:
[2019-05-30T15:25:08.981Z] @firebase/app:
Warning: This is a browser-targeted Firebase bundle but it appears it is being
run in a Node environment. If running in a Node environment, make sure you
are using the bundle specified by the "main" field in package.json.
...
Have to tell you right away, that using `rollup-plugin-node-resolve` to switch to `main` leads to enormous pile of errors for a lot of packages. And I didn't realize how to solve it.
Server vs. Client
Client only
The first solution that came to my mind was to use Firebase client only. But that was not the case. Why use SSR for the blog if posts are loaded on the client after the initial rendering?
Full Firebase SDK
Second solution was to import the whole Firebase SDK:
import firebase from "firebase";
In this case almost everything is working smooth, but the size of the main chunk served to the users went up to 256 KB. And I wanted the size of the app to be as small as possible.
require() for the server
The best solution I found so far is to modify the firebase init script: import the client version and then check if it's a server (no window
object) load the full Firebase API using CommonJS' require()
. Since bundle size on the server is not so critical and require
is synchronous, everything works as expected:
import firebase from "firebase/app";
import "firebase/firestore";
const firebaseConfig = {
// firebase config object
}
function initFirebase(config) {
if (typeof window === "object") {
return firebase.initializeApp(config);
} else {
const fb = require("firebase");
return fb.initializeApp(config);
}
}
const app = initFirebase(firebaseConfig);
// returning firestore handle
export const firestore = app.firestore();
Final deployment
If you have troubles when deploying cloud functions, you should add firebase
as a dependency to the functions directory and deploy it from there:
cd ./functions
npm install firebase --save
npm run deploy
And here we are. Everything is working as expected and the size of the chunk with firebase went down to 112 KB from 256 KB (gzipped)!
Still thinking about getting rid of the firestore and use realtime database like REST API, but for now that's enough
Some frontender thoughts
Twitter,
GitHub,
LinkedIn