gr2m / milestones

A GitHub backed Milestone thingy
http://gr2m.github.io/milestones/
69 stars 14 forks source link

Plugins #89

Closed gr2m closed 7 years ago

gr2m commented 8 years ago

The code for the new Hoodie has been released, but plugins are not part of it. It’s time to re-enable them again.

Our thoughts so far

For an example, look at https://github.com/hoodiehq/hoodie-account. It’s a core hoodie module and will get loaded differently than user plugins, but it follows the same structure.

This is up for grabs :) Let us know if you have any questions :)

jameswestnz commented 8 years ago

@gr2m how do we feel about using browserify on each server start to compile the client.js file? Browserfy is only a dev dependency at present, and theres likely reasons not to use in production. But it seems like it'd be an efficient solution...

gr2m commented 8 years ago

@jameswestnz yes I agree, once we have plugins we should make it a normal dependency. We will have to compile hoodie/client.js unless options.client is set to false or something like that. (this option does not exist yet :) )

jameswestnz commented 8 years ago

@gr2m sweet.

One possibility is that we first sort the server portion of plugin loading (loading hoodie-plugin-[plugin-name-here]/server after the core plugins), then create a plugin called hoodie-plugin-bundle-client...

In hoodie-plugin-bundle-client/server/index.js (which would be loaded when hoodie is bootstrapped), we can then locate all registered plugins and compile the associated client/index.js files along with the hoodie client.

This concept makes the "bundle-client" feature optional, and could even be limited to a devDependency so that the heavy lifting is only done while in a development environment.

We could then still have a options.client variable so the user can stop this compilation when required.

Not sure if this is overkill, considering it could be just as easy to modify the current bundle-client.js - but I've assumed that not all apps moving forward will have a need for the client compilation (essentially a situation using hoodie as a server only, and external clients would be using hoodie-client).

Thoughts?

gr2m commented 8 years ago

+1 on loading server components first.

For the client, I’d keep the code in https://github.com/hoodiehq/hoodie/blob/master/server/bundle-client.js for now. We can split up later as we see fit. Right now we load the dist/hoodie.js file which I think we can’t do anymore, we have to proper browserify anything for deduping dependencies. Say a plugin could also use PouchDB as dependency for what ever reasons, if the versions would be in the same range as hoodie-client’s, it would not bundle it in twice.

We also need to tell hoodie somehow which plugins to load. I suggest we add a "hoodie" property to the app’s package.json which can either be an object with key/values or a string with a path to a config path?

So an example hoodie app’s package.json could look like this?

{
  "name": "my-hoodie-app",
  "hoodie": {
    "account": {},
    "store": {},
    "client": {
      "url": "http://my-hoodie-app.com"
    },
    "foobar": {
      "someOption": "value"
    }
  },
  "scripts": {
    "start": "hoodie"
  },
  "dependencies": {
    "hoodie": "^21.0.0",
    "hoodie-plugin-foobar": "^1.2.3"
  }
}

Where "account", "store" and "client" would be options for the core modules. This is where we could set "client" to false. And for example "account" would set options for hoodie-account-server’s hapi plugin.

And if "hoodie": { "foobar" is not set, the plugin will not be loaded

Makes sense?

gr2m commented 7 years ago

@jameswestnz I created an example plugin to discuss how things could work based on our discussions so far: https://github.com/hoodiehq/hoodie-plugin-example/pull/1

Let’s use that for discussions on APIs and imlementation. +@inator

inator commented 7 years ago

@gr2m - Just a quick suggestion on your comment above:

We also need to tell hoodie somehow which plugins to load. I suggest we add a "hoodie" property to the app’s package.json which can either be an object with key/values or a string with a path to a config path?

Perhaps the app package dependencies property can be iterated over to look for "hoodie-plugin" attributes instead to load the plugins? Just a thought.

gr2m commented 7 years ago

we won’t enforce the hoodie-plugin- prefix, and we want to make it explicit this time which plugin is enabled and which is not.

We already support a "hoodie" property in the package.json, I think we should add a plugins key which is an array of the enabled plugins. And if the plugin requires own configuration, we should add it to the root, so we have sth like this

{
  "name": "my-app",
  ...
  "hoodie": {
    "plugins": ["email"],
    "email": {
      "service": "mandrill"
    }
  }
}

The reason for that is that apps can be plugins themselves. There are cases where you want to run a plugin in a separate process, for example. And ideally we can configure things always at the same place, no matter if loaded as plugin or as app itself.

I know that has a risk of namespace conflicts in the configuration, but I’d suggest it’s a problem when it’s a problem. Until then we should keep it simple.

inator commented 7 years ago

Makes sense, thanks @gr2m!

gr2m commented 7 years ago

shipped in https://github.com/hoodiehq/hoodie/releases/tag/v28.2.0 🎉