-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add New Platform conventions doc #39542
Conversation
Pinging @elastic/kibana-platform |
Pinging @elastic/kibana-app-arch |
src/core/CONVENTIONS.md
Outdated
export class MyPlugin implements Plugin { | ||
public setup() { ... } | ||
public start() { ... } | ||
public stop() { ... } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there "fairly stable" types defined for the arguments passed to these lifecycle methods (are they called lifecycle methods? idk)? It'd be fantastic to have the arguments and their types defined and linked to from here so we can get a sense of what we'll be doing in these methods. Thanks for this work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes there are types for this. You'll want to use the CoreSetup
and CoreStart
types from either src/core/public or src/core/server. By making your class implement the Plugin
interface, you'll get an error if you accept any other type. Unfortunately, type interference doesn't assign the types automatically, so you'll have to do it yourself:
import { CoreSetup, CoreStart, Plugin } from '../../src/core/public';
export class MyPlugin implements Plugin {
public setup(core: CoreSetup) { ... }
public start(core: CoreStart) { ... }
public stop() { ... } // does not accept any params at this time
}
These types are fairly stable, though we are still working on removing some from public's CoreSetup that should only be present in CoreStart. Other than that, the only major changes should be new services that are added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is perfect! I'd just use that example in the conventions doc so folks can track down those Core* types if they are curious about what gets passed to those methods. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated with additional detail!
This is Very Good 👏 |
I agree that a summary of our plugin folder structure e.g. What I am not sure though, is if Core is the best place for such a document. Core could have its own For the conventions of the internals of plugins themseves, it feels natural to have it in |
I agree, most developers are not going to be looking here. The reason I put it here for now is that we plan on coming up with a complete strategy on how we want to structure API documentation, developer guides, and examples for NP development. The Migration Guide, API Docs, and this document are the first pieces of content we have for that. I figured we keep it all together for now and until we decide where this content will live long-term. |
Few initial thoughts: 1. I'm not sure if there will be any plugin with multiple applications, especially as I believe @epixa was talking about actually reducing the number of icons in the left sidebar, but If a plugin has multiple apps, an extra "applications" folder is good:
Though, those multiple apps may want to share components between them:
But if the plugin has only one app (I guess most/all plugins will be like that?), I think it should be able to just have a single "application" folder:
I did a quick check; currently, it looks like most X-pack plugins just have an
I guess then we need a reason for having 2. We will soon have Storybook available for all plugins, so the "components" folder could have a structure. Components that are not connected to state (i.e. Redux,
Now, where do we put "connected" components (i.e. the ones with Redux,
Where components in "containers" folder import components from "components" folder and connect them to state. Another pattern—which I prefer better—is instead of having two symmetric folders have everything that is related to a component in a single folder. For example, each component could have "component" and "connected" files—"component" is the one that can be rendered in Storybook and "connected" is the one that connects "component" to state:
That way everything related to a component we can have in a single folder, including tests, stories, CSS; and—as we will be using dynamic imports—sizeable components could also have // lazy.tsx
import { lazy } from 'react';
export default lazy(() => import('./connected')); To summarize, it could look something like this:
3. We were just recently discussing in a team how an extra layer of folders in
That maybe we want to split those 5 folders into 5 plugins instead. (I believe they are independent anyways.) Now, if we introduce another "services" folder layer it would look like this:
It is nice at the first glance. But you will probably have |
4. Something like below can be added about readme:
5. Plugins could optionally have |
Infra already has two "applications" inside of one plugin (Infra Metrics and Logs). I like having a single
I think a general set of conventions is a great idea, but I also think trying to dictate the folder structures of apps will eventually be seen as going a little too far. I think teams should probably figure that out for themselves, in my opinion—it's a fine line but trying to avoid crossing over from "how a Kibana plugin is generally structured" to "how React apps should be structured". |
Couple other areas that I wonder if we should include here:
100% agree with @jasonrhodes on this. Ask 5 devs about the "right" way to structure a React app, and you'll get 5 different answers. I think @joshdover's approach here strikes a good balance: A clear separation of To me, there are two things we get out of this effort:
|
Responses to @streamich
I think having the directory is still helpful even if it's a single application. I believe having a small number of items in the top-level of the directory to be helpful for understanding a plugin's contents. I've updated this to show that if you only have a single application (a common case), you can just call this directory
I think this is a feature, not a bug. When I open the
One thing the New Platform project wants to accomplish is a detailed documentation for 3rd party developers. This means extracting docs into the AsciiDoctor pipeline we use for all other documentation on elastic.co. Though we haven't worked on this yet, the way I see this working is extracting TSDocs from code to generate asciidoc files. We still need to determine how more "prose-like" documentation (user guides, examples) should fit into this. One way we could do this is still via TSDocs, leveraging the For example, instead of a README, each plugin could have a top-level documentation block in their index.ts file: /**
* Data plugin for data fetching.
*
* @remarks
* Lots of detail about how this thing works.
*
* @example
* Here's a code example:
* ```ts
* data.doTheThing()
* ```
*
* @example
* Here's a second example:
* ```ts
* data.doTheOtherThing()
* ```
*
* @packageDocumentation
*/ It may turn out that this is not very practical and we need to supplement it with raw asciidocs file in the plugin directory. Until we build this tooling, I'm hesitant to specify how this should be done. Either way can be easily changed in the future. Responses to @lukeelmers
Good idea, I've added a section for this.
I don't have strong opinions on this other maybe adding an
I think getting into how applications should be structured is a bit too granular for a convention. The goal of having a consistent structure is to help a developer unfamiliar with your plugin be able to open your plugin directory and get a good sense of what are the primary contents of your plugin. The details of how it's implemented will drive the shape of the directory tree, and I don't want to specify how your plugin should be built at that level of detail. In spirit of this, I've removed the "components" directory from applications to let plugin developers decide how to shape this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple of nits
Yeah I brought it up because it is something I'm currently thinking about. I'll follow up with you on it once I have something more concrete. I don't think it needs to stop this PR from moving forward though; we can always supplement the material here later. |
bba3073
to
62d3830
Compare
Summary
This is a WIP document aimed at collecting all the conventions we're adopting for developing plugins in the New Platform.
Please feel free to contribute more by pushing to this branch.
View Rendered
[skip-ci]