This post is now irrelevant, as the Ionic team replaced Webpack with Browserfy in their Beta 4 release. However, if you’re customizing to use Webpack, feel free to read on.

In this post I’ll walk through how I got PouchDB working as part of the Webpack compilation process in an Ionic 2 project. There are other ways to add PouchDB, which I’ll go into first. But every time I looked at my code it just felt dirty – like I wasn’t using the tools that were specifically intended to be part of the build workflow. So I ultimately opted for including Pouch in Webpack. After showing how to do it the olden way, I’ll go into how it’s done in Webpack.

The Olden Way: Adding a Script Tag

The easiest way to add PouchDB is the old fashioned way. You add a <script> tag to your code. Assuming you have PouchDB installed via Bower or NPM, you’d just link to the appropriate file in the dist/ folder. Just a heads up, that’s going to get ugly fast.

By default, Ionic 2 is going to compile your entire application into an app.bundle.js file, which will load into an index.html that lives outside of your application files. This essentially means that you don’t have access to the index.html from within your application files, and instead have to edit it inside the compiled porject. That’s a bummer. Ideally you should leave www/index.html alone and only deal with the working files that are part of your application.

<!DOCTYPE html>
<html lang="en">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">

  <link ios-href="build/css/app.ios.css" rel="stylesheet">
  <link md-href="build/css/app.md.css" rel="stylesheet">

  <!-- this Ionic's root component and where the app will load -->

    <!-- PouchDB, as promised... -->
  <script src="./build/js/pouchdb.5.2.1.min.js"></script>
  <script src="cordova.js"></script>
    <!-- and there's the build run by Webpack... -->
  <script src="build/js/app.bundle.js"></script>

Even more of a bummer, if you’re not adding PouchDB as part of your application, then you’ll have to manually add it as a file living in the compiled project’s www/js/ folder. And that’s where things really start to feel really dirty, as you have a nicely bundled JS file with literally everything in your app, except for PouchDB.

"You know, if you'd done that to somebody else, they might devote their existence to exacting revenge." “You know, if you’d done that to somebody else, they might devote their existence to exacting revenge.”

Another down side is that your application is not aware of PouchDB, and so you won’t be able to reference it as part of your module loading. It would look something like this:

import {Injectable} from 'angular2/core';

export function DataFactory() {
    // create local DB instances
    return new PouchDB('fresh_pouch'); // psh, where did THAT come from?

Notice you’re not importing anything. The reason is that the script is already loaded into the DOM, so it’s operating at the window scope before your DataFactory is loaded.

For me, that didn’t exactly feel like the right way to do things. First of all, because I’m running TypeScript which is super strict, my IDE always highlighted any reference to PouchDB in red, as it wasn’t defined in any of the classes I was writing. I’m sure that could have been fixed by adding it as a library in my IDE settings, but it was motivation for figuring out a better load process instead.

Second, I want clarity in my code. If I’m going to reference a module, I want that module to be an obvious dependency of the code I’m writing. When I look at someone else’s code, and it’s like untangling a ball of yarn trying to track down their dependencies, I get frustrated. So I tend to avoid that when I can.

Adding PouchDB to Webpack

Let’s just get this out of the way – I’m no expert at Webpack. I’ve loaded enough modules in my day to understand how module loading and exporting works, and fortunately that was plenty for getting PouchDB into Ionic applications. If you have a better way, feel free to comment and I’ll try it out!

Also, I’d like to throw credit to Matt Kunze for his example in a typical JS setting, which allowed me to facepalm my way through an import problem I was seeing in TypeScript.

Resolving files in the Webpack config

If you open webpack.config.js, you’ll see that there is an array of entry points that correspond to modules that need to be loaded. The path.normalize() method resolves strings passed in as arguments as paths within the node_modules/ folder. So we’ll add our path to PouchDB here:

// ...
module.exports = {
  entry: [
    path.normalize('pouchdb/dist/pouchdb') // BOO-YA-HA-HA!!!
    // ...

At the bottom of this file you’ll notice that the resolve property lists extensions that include .ts and .js, so we don’t need to add file extensions. If you have PouchDB installed via bower, your entry point might look something like this:


At this point, if you were to run compilation with ionic serve, you’ll find PouchDB tucked nice and neatly away in your app.bundle.js.

Importing PouchDB into your Angular components

Now that it’s part of the bundle, we can simply run an import statement to pull in the PouchDB module. And here’s the catch that had me facepalming once I figured it out from the help mentioned above – most of the examples we see in an Angular application use destructured imports:

import {Injectable} from 'angular2/core';

The curly braces correspond to an exported property on the core class being assigned as a local variable. PouchDB doesn’t exist in class nor object form, and therefore doesn’t have properties for us to assigned via destrcuturing while still maintaining its integrity. Instead, it is the exported module. So instead of using destructured imports, we’ll simply call the entire module.

import * as PouchDB from 'pouchdb';

Big ups to khamaileon for suggesting import * as, as an alternative to using require. Using require worked, but personally I’d prefer that my imports all follow the same syntactical pattern.

Ultimately, this is what my DataFactory class looks like:

import {Injectable} from 'angular2/core';
import * as PouchDB from 'pouchdb';

export function DataFactory() {
    // create local DB instances
    return new PouchDB('fresh_pouch');

And that’s it! From here on out you can use this newly created local database as grounds for a nice data service that will load up all of your data locally, and eventually sync to a distant, server-side CouchDB installation.

2 responses to “Add PouchDB to an Ionic 2 app via Webpack”

  1. khamaileon says:

    Have you tried this ?
    import * as PouchDB from ‘pouchdb’;

    • admin says:

      I hadn’t, but I did just now and it works. Very studly suggestion. About to head to work, but tonight I’ll update and give props. Thanks!

Leave a Reply