Chris Carson
Chris Carson

Reputation: 1845

What's the correct way to code split (lazy-load) an external library into a SvelteKit project

tldr;

I'm getting the following warning when building a SvelteKit project with @sveltejs/adapter-static, lazy-loading Firebase JS SDK 9.0.0-beta.2:

[vite-plugin-svelte] The following packages did not export their package.json file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file. -firebase

Everything seems to work in real life (i.e. on the client with initially static routes that later make calls to the Firebase API.) Do I need to stress about this warning? Note -- I don't think I'm ever "polluting" the static routes with direct Firebase imports, but I may be doing it all wrong. Please see below for my methodology.

More Info

I'm lazily importing Firebase 9 (beta) into a SvelteKit project. I expose async getters for the various Firebase things like this...

import type { FirebaseApp } from 'firebase/app';
import type { Auth } from 'firebase/auth';
// etc...

// basic firebase options plus some emulator config...
import { getEnv } from './env';

let _app: FirebaseApp | null = null;
let _auth: Auth | null = null;
// etc...

export const firebaseApp = async () => {
  if (!_app) {
    const { loadApp } = await import('./load/load-app');
    _app = loadApp(getEnv());
  }
  return _app;

}

export const firebaseAuth = async (): Promise<Auth> => {
  if (!_auth) {
    const app = await firebaseApp();
    const { loadAuth } = await import('./load/load-auth');
    _auth = loadAuth(app, getEnv());
  }
  return _auth;
}

The actual firebase imports are in the load/load-**.ts files...

//load-app.ts
import { FirebaseApp, initializeApp } from 'firebase/app';
import type { FirebaseEnvironment } from '../api';

export const loadApp = (env: FirebaseEnvironment): FirebaseApp => {
  const  app = initializeApp(env.options);
  return app;
};
// load-auth.ts
import type { FirebaseApp } from 'firebase/app';
import { getAuth, useAuthEmulator, Auth } from 'firebase/auth';
import type { FirebaseEnvironment } from '../api';


export const loadAuth  = (app: FirebaseApp, env: FirebaseEnvironment): Auth => {
  const auth = getAuth(app);
  if (
    env.emulators &&
    env.emulators.auth
  ) {
    useAuthEmulator(auth, env.emulators.auth.url, {
      disableWarnings: true
    });
  }
  return auth;
}

This works as expected -- i.e. Vite and SvelteKit seem to chunk everything up nicely, and I can do stuff like this in my components....

<script>
// SignInForm.svelte
  // the lazy getter from above...
  import { firebaseAuth } from '$lib/firebase';
  import {
    browserLocalPersistence,
    browserSessionPersistence,
    setPersistence,
    signInWithEmailAndPassword
  } from '@firebase/auth';
  const signIn = async () => {
   try {
      const auth = await firebaseAuth();
      const cred = await signInWithEmailAndPassword(auth, ...);
      // etc...
    } catch (error) {
      // handle
    }
  };

</script>

Again, all this seems to work, except for the warning on build. I just need somebody more familiar with Vite and SvelteKit to let me know if it's the "right way" (Or not.) Thanks in advance!

Upvotes: 1

Views: 1065

Answers (1)

Luke
Luke

Reputation: 614

The warning basically says that if the firebase package exports any svelte components (which it doesn't), the svelte compiler won't pick it up and won't be able to optimize it. I have seen the warning too and I don't think there is anything to worry about.

Upvotes: 2

Related Questions