-
Notifications
You must be signed in to change notification settings - Fork 5
Conversation
For the record, I don't see anything inherently wrong with having some things in meta and some as global. The separation was really clear before: 1) cache, storage, and other things that are internal to the plugin server in meta, 2) all exported libraries (bigquery, fetch, etc) in globals. |
From my side, I just can't practically use injected globals with .ts plugins, which is frustrating. This is why I push for something like this. |
I still don't fully get that. It should be enough to add into declare const posthog: {
capture: (event: string, properties?: Record<string, any>) => void
} ... and then in whatever source file that imports this package (or any other package where these types are in the file that's defined by the The problem is obviously that this package is imported not just by plugins, but also by posthog itself... and we probably don't want to add all plugin server globals in the frontend there. So some side-package (separate scaffold just for plugins) is probably needed. |
Yep. But… we'd need another package and we do actually want to share the definitions that are in plugin scaffold between the server and plugins to ensure we keep them in sync. This requires nothing additional. Just everything conveniently in meta as well as globally for backwards compatibility. |
We can always make a new package, To make the experience seamless for users, this package would be included in the {
"compilerOptions": {
"target": "ES2018",
"lib": ["ESNext"],
"module": "ES2015",
"moduleResolution": "Node",
"strict": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noUnusedParameters": true,
"noEmit": true,
"resolveJsonModule": true
},
"exclude": ["**.test.ts"],
"include": ["**.ts", "./node_modules/@posthog/plugin-globals/src/globals.d.ts"]
} Still no? 😅 |
I've published this package that adds supports for plugin globals and is quite easy to install: https://github.com/PostHog/plugin-globals |
From a technical standpoint that is cool and does the job, but from an ergonomics point of view I really don't want to have to install an additional package and configure tsconfig for it (and as a PostHogger, I don't want to have to maintain it in addition to |
We can always use github actions to keep various packages in sync and thus have just one package ;). I guess we need tiebreakers. @macobo ? The question is basically: function runEveryMinute() {
posthog.capture('hello')
} vs import { Plugin } from '@posthog/posthog-scaffold'
const plugin: Plugin = {
runEveryMinute(meta) {
meta.posthog.capture('hello')
}
}
module.exports = plugin I'm still arguing that the former is a much nicer and more approachable API than the latter, even though the latter is more explicit... and what's more, I'm arguing that making it more approachable matters for the adoption of plugins and for the dev experience of people writing plugins (types are not everything). Hence I still wouldn't put all external libraries into |
Hm, that's not exactly the gist of the discussion (the
|
This discussion is running off the rails if the arguments are in the format of "no because we need to maintain two packages". Again, in my book this is a discussion between optics and practicality on one side and purity on the other. In my experience purity usually loses in the real world. |
But two packages are, in very practical terms: 1. more maintenance for us 2. more work to get going as a plugin server developer, especially if the new package also requires tsconfig setup. |
To keep things simple, I'd actually just integrate this package into |
More practically, This solves all problems I see in the thread (you'll get globals in plugins without adding any extra lines anywhere) and is not that hard for people who code posthog to get their heads around. We could even just |
There's one alternative approach we can take as well. Since we're using babel to transpile all plugin code, we could use actual So to And finally, I still like the logic that external libraries come to you externally and globally, not via any of the built in plugin objects. We are writing our own JS runtime here, so we can be really flexible with the syntax we offer our users. |
I'm probably not the best person to judge in on this (least amount of plugins created). Instead, I'd ask:
However let's stir the pot a bit. Let me try to summarize the argument(s):
My vote on the current state is:
Why? Because my argument is:
However, as soon as your functions/scripts start relying on magical globals it becomes non-interoperable with the rest of the world. There were a few other ideas floated around like using babel to do some import-level schenanigans. Mocking |
Thanks @macobo for weighing in! This actually made me really like the approach of importing from There's one thing that's slightly annoying with both previously discussed approaches (globals and meta), and that's that they make it a lot more complicated to write tests, for the plugin itself. Imagine you have an If we instead re-package each plugin into something like Packaging things like this also gives us much greater control over versioning. In case the Re-exporting the package as It would also make package.json saner for the plugin server, as we could directly see which packages are there since they're extensions for plugins, and which are there since the plugin server itself needs them. WDYT? |
So just weighing in here given @macobo's tag. For me, I've now accepted a bit of the "magic" of plugins, where some stuff is just available to me. It also helps because I do have some insight into how it works in the background, so it isn't entirely magic. Hence, I like that I can use However, this is a bit confusing for users. I built a plugin with a user on a call and there was definitely confusion as to why some stuff he needed the meta for (metaphor?) whereas other things just existed. Hence, my 2c (purely from a "plugin developer experience" light):
|
@yakkomajuri do you think ES imports could work and be easy to explain to users? Do any of these options make sense? // importing from our own stdlib
import { posthog } from '@posthog/plugin-library'
function runEveryMinute() {
posthog.capture('haha')
} // importing from a whitelisted "@posthog-plugins" package
import { bigquery } from '@posthog-plugins/google'
// importing natively, but again from a whitelisted source (e.g. @google-cloud/bigtable throws an error)
import { bigquery } from '@google-cloud/bigquery'
function processEvent(event) {
bigquery.run('insert into events ?', event)
} |
Yeah @mariusandra those make sense to me too - feels even less magic than meta |
Ok, so I made a PR to add After that, you can do: import { BigQuery } from '@google-cloud/bigquery'
import fetch from 'node-fetch' ... and it'll just work. Thus I propose:
|
Now that #284 is merged, this can be closed I think. |
Changes
Stemming from #247 (comment), this is a way to make extensions more usable.
Currently some of them are part of plugin meta, while others are globals. And the latter half is not usable in TypeScript plugins: it requires plugin developers to write their own definition of the extension and to convince TypeScript that the global will surely be injected at runtime. With the meta object on the other hand it's just a matter of using
PluginMeta
from the plugin scaffold and everything works.This PR injects everything into both globals and meta, with a unified
createExtensions
inextensions/index
, which allows the plugin server (VM generation in particular) to be agnostic of particular extensions.Checklist