How to make minimongo.js works in browser?

2020-07-17 15:07发布

问题:

The github presentation of minimongo states it as

Client-side mongo database with server sync over http

There is a also a minimongo-standalone providing a minimongo.min.js which states :

You could also just download the minimongo.min.js, place it on your server, and reference it in your source.

For browsers

<script src="/js/minimongo.min.js"></script>

I previously used d3.js which is packaged in a way so the .js file works both in web-browsers as a lib and on nodes as a npm packages.

So I tried locally with my newly downloaded minimongo.js to build a classic webpage with indexeddb in Chrome as I would do with D3.js. It gives something like that (jsfiddle) :

<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>MiniMongo</title>
    <script src="https://rawgit.com/rurri/minimongo-standalone/master/minimongo.min.js"></script>
    <!-- https://github.com/rurri/minimongo-standalone/blob/master/minimongo.min.js -->
  </head>
  <body></body>
  <script>
    // Require minimongo
    var minimongo = require("minimongo");
    var LocalDb = minimongo.MemoryDb;
    // Create local db (in memory database with no backing)
    db = new LocalDb();
    // Add a collection to the database
    db.addCollection("animals");
    doc = { species: "dog", name: "Bingo" };
    // Always use upsert for both inserts and modifies
    db.animals.upsert(doc, function() {
      // Query dog (with no query options beyond a selector)
      db.animals.findOne({
        species: "dog"
      }, {}, function(res) {
        console.log("Dog's name is: " + res.name);
      });
    });

  </script>
</html>

It returns the errors :

Uncaught ReferenceError: _ is not defined
    at minimongo.min.js:1
    at minimongo.min.js:3
Uncaught ReferenceError: require is not defined
    at (index):5911
Uncaught ReferenceError: _ is not defined
    at (index):91
    at window.onload ((index):5889)

What am I missing or misunderstanding ? How to make it work if possible ?

回答1:

A few things

1. Dependencies

If you read the README.MD of minimongo-standalone, it says

Requirements

underscore, async

So you will need to include both those libraries on your page before the minimongo script tag.

<head>
  <script src="https://link/to/underscore.js"></script>
  <script src="https://link/to/async.js"></script>
  <script src="https://rawgit.com/rurri/minimongo-standalone/master/minimongo.min.js"></script>

It's important to mention that you need to get the browser versions of these libraries. It seems that async don't use a Universal Module Definition (UMD) and so provide separate files for different targets.


2. Require

The function require doesn't exist unless you are using browserify or another commonJS module loading framework.

I haven't checked async or underscore, but most libraries will fallback to ordinary globals in the browser if a module system isn't present.

After including the three script tags you should be able to access minimongo-standalone's exported symbols globally


3. minimongo-standalone has a very different API to minimongo

A frustrating point; minimongo-standalone implements the Meteor wrappers around minimongo, and then renames them again. Meaning that any minimongo or Meteor code is not directly transferable.

The good part is that the API is a great deal simpler. The equivalent code for your example would be

// Create collection
var animals = new LocalCollection('animals');
// Insert/update a document

var doc = { species: "dog", name: "Bingo" };
animals.upsert('dog', doc);

// Fetch document and log
var myDog = animals.findOne({ species: "dog" });
console.log("Dog's name is: " + myDog.name);


回答2:

@Fred_Stark : you are encouraged to integrate this into your answer.

Short: works but super heavy (800kb!). https://jsfiddle.net/7fehe9ey/9/ . Use something else!

Initial code

/* **************************************************************** */
/* THIS WILL GO TO BUNDLE ***************************************** */
// Require minimongo
var minimongo = require('minimongo');
var LocalDb = minimongo.MemoryDb;
// Create local db (in memory database with no backing)
db = new LocalDb();

/* **************************************************************** */
/* THIS WILL GO TO INDEX.HTML ************************************* */
// Add a collection to the database
db.addCollection("animals");
doc = { species: "dog", name: "Bingo" };
// Always use upsert for both inserts and modifies
db.animals.upsert(doc, function() {
  // Query dog (with no query options beyond a selector)
  db.animals.findOne({
    species: "dog"
  }, {}, function(res) {
    console.log("Dog's name is: " + res.name);
  });
});

Bundles up

npm install minimongo underscore async
npm install -g browserify
echo "var minimongo=require('minimongo');var LocalDb=minimongo.MemoryDb;db=new LocalDb();" > ./app.js
browserify ./app.js -o ./bundle.js

It results in a 800Kb ./bundle.js file which works as a black box in jsfiddle jsfiddle.net/7fehe9ey/8

HTML-JS

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>MiniMongo</title>
    <!-- ======================================================= -->
    <!-- ======================================================= -->
    <script src="./js/bundle.js"></script><!--================== -->
    <!-- ======================================================= -->
    <!-- ======================================================= -->
  </head>
  <body>
</body>
    <script>
    // Require minimongo
    // var minimongo = require('minimongo');
    // var LocalDb = minimongo.MemoryDb;
    // Create local db (in memory database with no backing)
    // db = new LocalDb();
    // Add a collection to the database
    db.addCollection("animals");
    doc = { species: "Cat", name: "Cingo" };
    // Always use upsert for both inserts and modifies
    db.animals.upsert(doc, function() {
      // Query dog (with no query options beyond a selector)
      db.animals.findOne({
        species: "Cat"
      }, {}, function(res) {
        console.log("Cat's name is: " + res.name);
      });
    });

    </script>
</html>

Returns

Console returns :

Cat's name is: Cingo