PouchDB and SvelteKit

Viewed 1132

I want to use PouchDB with SvelteKit. I have copied pouchdb-7.2.1.js to /src/libd in SvelteKit and renamed it to pouchdb.js. Pouchdb should run in the browser. Therefore I have used ssr=false to suppress server side rendering. I get the first error at the import statement. This is my first very short page (couchdb.svelte):

<script context="module">
    export const ssr = false;
</script>

<script>
    import PouchDB from '$lib/pouchdb.js'; 
</script>

I get an error 500

import not found: PouchDB

I have tried a lot of diffent version without any success. For example:

import PouchDB from 'pouchdb-browser';  (After npm i pouchdb-browser)
import PouchDB from 'pouchdb';          (After npm i pouchdb)

What is the correct way to use pouchdb?

3 Answers

Here is a work-around that uses PouchDB via a script tag:

index.svelte:

<script>
    import { onMount } from 'svelte'

    // Ensure execution only on the browser, after the pouchdb script has loaded.
    onMount(async function() {
        var db = new PouchDB('my_database');
        console.log({PouchDB})
        console.log({db})
    });
</script>


<svelte:head>
    <script src="//cdn.jsdelivr.net/npm/pouchdb@7.2.1/dist/pouchdb.min.js"></script>
</svelte:head>

When imported, PouchDB seems to expect a certain environment that Svelte/Vite/Rollup does not provide. (Svelte/Vite is happiest with proper ESM modules; PouchDB seems to be a "window.global" script that was converted to a JS module.)

There may be a way to modify the configuration to create the environment expected by PouchDB. I think you would have to modify the svelte.config.cjs file. (Specifically the vite section that determines the rollup configuration.)

You might find some hints in this related issue for PouchDB + Angular.

I would just use the <script> work-around above.

For future googlers trying to integrate pouchdb-browser and/or RxDB with sveltekit here are the changes to "fix" the enviornment for pouchdb in the browser when using vite.

  1. Add to your <head> section before %svelte.head%
<script>
    window.process = window.process || {env: {NODE_DEBUG:undefined, DEBUG:undefined}};
    window.global = window;
</script>
  1. In svelte.config.js add the optimizeDeps to config.kit.vite.optimizeDeps
optimizeDeps: {
    allowNodeBuiltins: ['pouchdb-browser', 'pouchdb-utils', 'base64id', 'mime-types']
}

Here is a commit that makes these changes to my app: https://github.com/TechplexEngineer/bionic-scouting/commit/d1c4a4dcdc7096ae40937501d97a7ef9ee10ab66

Thanks to: pouchdb/pouchdb#8266 (comment)

I have been battling this very same problem for a while. I decided to go a different route. This may not be right, but it is working.

I added two scripts to my app.html head:

<head>
    <meta charset="utf-8" />
    <meta name="description" content="" />
    <link rel="icon" href="%svelte.assets%/favicon.png" />
    <meta name="viewport" content="width=device-width, initial- 
    scale=1" />
    <!-- Call the Pouchdb import -->
    <script type="text/javascript" src="../src/lib/pouchdb.js">
    </script>
    <!-- create new databases for use in the app -->
    <script>
        const user = new PouchDB('user');
    </script>
    %svelte.head%
</head>

Then in any component that I want to use the database, I add an additional script tag to define the variable "user":

<script lang="ts" context="module">
    //Declare the database name so that it is recognized.
    declare const user;
</script>

<script lang="ts">
//Example use of database.
const addUser = () => {
    //Call the database by name established in app.html
    user.put({
        _id: 'someid',
        firstName: 'Jon',
        lastName: 'doe'
    });
};
</script>

That has been the easiest method for me to employ PouchDB with SvelteKit. Every other solution required significant modifications to configuration files, changes to environment variables, and unnecessary adaptations of code throughout the application. I hope this helps.

Related