From 85f5ca94412ebb2728e50ecc8b0b301fe3180a50 Mon Sep 17 00:00:00 2001 From: nikek Date: Fri, 13 Mar 2020 18:51:54 +0100 Subject: [PATCH] Structure documentation in /docs --- README.md | 38 +-------- docs/README.md | 7 ++ docs/architecture-terminology.md | 9 +++ .../getting-started/Plugin development.md | 23 +++--- docs/getting-started/README.md | 11 +++ docs/getting-started/create-a-plugin.md | 21 +++++ .../getting-started}/create-plugin_output.png | Bin .../getting-started/create-run-an-instance.md | 15 ++++ .../getting-started}/my-plugin_screenshot.png | Bin docs/getting-started/set-up-environment.md | 11 +++ docs/getting-started/structure-of-a-plugin.md | 76 ++++++++++++++++++ docs/reference/README.md | 8 ++ docs/reference/createPlugin-router.md | 21 +++++ docs/reference/createPlugin.md | 40 +++++++++ 14 files changed, 235 insertions(+), 45 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/architecture-terminology.md rename plugins/README.md => docs/getting-started/Plugin development.md (76%) create mode 100644 docs/getting-started/README.md create mode 100644 docs/getting-started/create-a-plugin.md rename {plugins => docs/getting-started}/create-plugin_output.png (100%) create mode 100644 docs/getting-started/create-run-an-instance.md rename {plugins => docs/getting-started}/my-plugin_screenshot.png (100%) create mode 100644 docs/getting-started/set-up-environment.md create mode 100644 docs/getting-started/structure-of-a-plugin.md create mode 100644 docs/reference/README.md create mode 100644 docs/reference/createPlugin-router.md create mode 100644 docs/reference/createPlugin.md diff --git a/README.md b/README.md index 4f1f7d34ae..f8a56714f2 100644 --- a/README.md +++ b/README.md @@ -39,39 +39,9 @@ _\* not yet released_ ![overview](backstage_overview.png) -## Getting started +## Documentation -### Install Dependencies - -To run the frontend, you will need to have the following installed: - -- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) -- [NodeJS](https://nodejs.org/en/download/) - Active LTS Release, currently v12 -- [yarn](https://classic.yarnpkg.com/en/docs/install) - -## Running the frontend locally - -Open a terminal window and start the web app using the following commands from the project root: - -```bash -$ yarn # may take a while - -$ yarn start -``` - -The final `yarn start` command should open a local instance of Backstage in your browser, otherwise open one of the URLs printed in the terminal. - -## Plugins - -### Creating a Plugin - -To create a new plugin, make sure you're run `yarn` to install dependencies, then run the following: - -```bash -$ yarn create-plugin -``` - -For more information see [Developing a Backstage Plugin](plugins/README.md). +[Find the docs here.](docs/README.md) ## Developer support @@ -80,10 +50,6 @@ Please join our [Discord](https://discordapp.com/) server: - [#general](https://discord.gg/MUpMjP2) - Developer focused discussions - [#support](https://discord.gg/dKhwsBp) - Support in how to use Backstage -## Documentation - -_TODO: Add links to docs on backstage.io_ - ## License Copyright 2020 Spotify AB. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..74e71370e1 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,7 @@ +# Documentation + +Check out [https://backstage.io]() or see the table of content below. + +- [Architecture and terminology](architecture-terminology.md) +- [Getting started](getting-started/README.md) +- [References](reference/README.md) diff --git a/docs/architecture-terminology.md b/docs/architecture-terminology.md new file mode 100644 index 0000000000..89801f11e6 --- /dev/null +++ b/docs/architecture-terminology.md @@ -0,0 +1,9 @@ +# Architecture and Terminology + +Backstage is constructed out of three parts. We separate Backstage in this way because we see three groups of contributors to make an instance of Backstage a success. + +- Core - Base functionality - built by core devs in the open source project +- App - The app is an instance of a Backstage app that is deployed and tweaked. The app ties together core functionality with additional plugins - built and maintained by app developers, usually a productivity team within a company. +- Plugins - Additional functionality to make your Backstage app useful for your company. Plugins can be specific to a company or open sourced and reusable. At Spotify we have over 100 plugins built by over 50 different teams. It is very powerful to have contributions from various infrastructure teams into a single unified developer experience. + +[Back to Docs](README.md) diff --git a/plugins/README.md b/docs/getting-started/Plugin development.md similarity index 76% rename from plugins/README.md rename to docs/getting-started/Plugin development.md index 6d15c60776..45cb171ef9 100644 --- a/plugins/README.md +++ b/docs/getting-started/Plugin development.md @@ -1,12 +1,13 @@ # Plugin Development in Backstage -Backstage plugins provide features to a Backstage App. -Each plugin is treated as a self-contained web app and can include almost any type of content. -Plugins all use a common set of platform APIs and reusable UI components. -Plugins can fetch data from external sources using the regular browser APIs or by depending on +Backstage plugins provide features to a Backstage App. + +Each plugin is treated as a self-contained web app and can include almost any type of content. +Plugins all use a common set of platform APIs and reusable UI components. +Plugins can fetch data from external sources using the regular browser APIs or by depending on external modules to do the work. -## Creating a new plugin + ## Developing guidelines - Consider writing plugins in `TypeScript`. - Plan the directory structure of your plugin so that it becomes easy to manage. +- Prefer using the Backstage components, otherwise go with [Material-UI](https://material-ui.com/). +- Check out the shared Backstage APIs before building a new one. ## Plugin concepts / API ### Routing + Each plugin is responsible for registering its components to corresponding routes in the app. -The app will call the `createPlugin` method on each plugin, passing in a `router` object with a set +The app will call the `createPlugin` method on each plugin, passing in a `router` object with a set of methods on it. ```typescript @@ -48,6 +52,7 @@ export default createPlugin({ ``` #### `router` API + ```typescript type RouterHooks = { registerRoute( diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md new file mode 100644 index 0000000000..16f405dcb9 --- /dev/null +++ b/docs/getting-started/README.md @@ -0,0 +1,11 @@ +# Getting started with Backstage + +Here is a collection of tutorials that will guide you through setting up and extending an instance of Backstage with your own plugins. + +- [Set up the environment](set-up-environment.md) +- [Create/Run an instance of Backstage](create-run-an-instance.md) +- [Create a Backstage plugin](create-a-plugin.md) +- [Structure of a plugin](structure-of-a-plugin.md) +- Using Backstage components (TODO) + +[Back to Docs](../README.md) diff --git a/docs/getting-started/create-a-plugin.md b/docs/getting-started/create-a-plugin.md new file mode 100644 index 0000000000..be3be26abb --- /dev/null +++ b/docs/getting-started/create-a-plugin.md @@ -0,0 +1,21 @@ +# Create a plugin + +To create a new plugin, make sure you've run `yarn` and installed dependencies, then run the following on your command line (invoking the `backstage-cli`). + +```bash +yarn create-plugin +``` + +![](create-plugin_output.png) + +This will create a new Backstage Plugin based on the ID that was provided. It will be built and +added to the Backstage App automatically. + +_If `yarn start` is already running you should be able to see the default page for your new +plugin directly by navigating to `http://localhost:3000/my-plugin`._ + +![](my-plugin_screenshot.png) + +[Next Step - Structure of a plugin](structure-of-a-plugin.md) + +[Back to Getting Started](README.md) diff --git a/plugins/create-plugin_output.png b/docs/getting-started/create-plugin_output.png similarity index 100% rename from plugins/create-plugin_output.png rename to docs/getting-started/create-plugin_output.png diff --git a/docs/getting-started/create-run-an-instance.md b/docs/getting-started/create-run-an-instance.md new file mode 100644 index 0000000000..65754beb21 --- /dev/null +++ b/docs/getting-started/create-run-an-instance.md @@ -0,0 +1,15 @@ +# Run an instance of Backstage + +Open a terminal window and start the web app using the following commands from the project root: + +```bash +$ yarn # may take a while + +$ yarn start +``` + +The final `yarn start` command should open a local instance of Backstage in your browser, otherwise open one of the URLs printed in the terminal. + +[Next step - Create a Backstage plugin](./create-a-plugin.md) + +[Back to Getting Started](README.md) diff --git a/plugins/my-plugin_screenshot.png b/docs/getting-started/my-plugin_screenshot.png similarity index 100% rename from plugins/my-plugin_screenshot.png rename to docs/getting-started/my-plugin_screenshot.png diff --git a/docs/getting-started/set-up-environment.md b/docs/getting-started/set-up-environment.md new file mode 100644 index 0000000000..eb57609f79 --- /dev/null +++ b/docs/getting-started/set-up-environment.md @@ -0,0 +1,11 @@ +### Set up environment + +To run the frontend, you will need to have the following installed: + +- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- [NodeJS](https://nodejs.org/en/download/) - Active LTS Release, currently v12 +- [yarn](https://classic.yarnpkg.com/en/docs/install) + +[Next step - Run an instance of the Backstage app](./create-run-an-instance.md) + +[Back to Getting Started](README.md) diff --git a/docs/getting-started/structure-of-a-plugin.md b/docs/getting-started/structure-of-a-plugin.md new file mode 100644 index 0000000000..c6034261f1 --- /dev/null +++ b/docs/getting-started/structure-of-a-plugin.md @@ -0,0 +1,76 @@ +# Structure of a newly created plugin + +Nice, you have a new plugin! We'll soon see how we can develop it into doing great things. But first off, let's look at what we get out of the box. + +## Folder structure + +The new plugin should look something like: + +``` +new-plugin/ + dist/ + node_modules/ + src/ + components/ + ExampleComponent/ + ExampleComponent.test.tsx + ExampleComponent.tsx + index.ts + ExampleFetchComponent/ + ExampleFetchComponent.test.tsx + ExampleFetchComponent.tsx + index.ts + index.ts + plugin.test.ts + plugin.ts + jest.config.js + jest.setup.ts + package.json + README.md + tsconfig.json +``` + +You might note a thing or two. Yes, a plugin looks like a mini project on it's own with a `package.json` and a `src` folder. And this is because we want plugins to be separate packages. This makes it possible to ship plugins on npm and it lets you work on a plugin in isolation, without loading all the other plugins in a potentially big Backstage app. + +The `index.ts` files are there to let us import from the folder path and not specific files. It's a way to have control over the exports in one file per folder. + +## Base files + +In the root folder you have some configuration for typescript and jest, the test runner. You get a readme to populate with info about your plugin and a package.json to declare the plugin dependencies, metadata and scripts. + +## The plugin file + +In the `src` folder we get to the interesting bits. Check out the `plugin.ts`: + +```jsx +import { createPlugin } from '@spotify-backstage/core'; +import ExampleComponent from './components/ExampleComponent'; + +export default createPlugin({ + id: 'new-plugin', + register({ router }) { + router.registerRoute('/new-plugin', ExampleComponent); + }, +}); +``` + +This is where the plugin is created and where it hooks into the app by declaring what component should be shown on what url. See reference docs for [createPlugin(coming soon)](http://github.com/spotify/backstage/) or [router(coming soon)](http://github.com/spotify/backstage/). + +## Components + +The generated plugin includes two example components to showcase how we structure our plugins. There are usually one or multiple page components and next to them you can split up the UI in as many components as you feel like. + +We have the `ExamplePage` to show an example Backstage page component. The `ExampleFetchComponent` show cases the common task of making an async request to a public API and plot the response data in a table using Material-UI components. + +You may tweak these components, rename them and/or replace them completely. + +## Connecting the plugin to the Backstage app + +There are two things needed for a Backstage app to start making use of a plugin. + +1. Add plugin as dependency in `app/package.json` +2. `import` plugin in `app/src/plugins.ts` + +Luckily these two steps happen automatically when you create a plugin with the Backstage CLI. + +[Back to Getting Started](README.md) diff --git a/docs/reference/README.md b/docs/reference/README.md new file mode 100644 index 0000000000..8438917945 --- /dev/null +++ b/docs/reference/README.md @@ -0,0 +1,8 @@ +# Reference documentation + +APIs and Components + +- [createPlugin](createPlugin.md) +- [createPlugin - router](createPlugin-router.md) + +[Back to Docs](../README.md) diff --git a/docs/reference/createPlugin-router.md b/docs/reference/createPlugin-router.md new file mode 100644 index 0000000000..fa1a9cfa5b --- /dev/null +++ b/docs/reference/createPlugin-router.md @@ -0,0 +1,21 @@ +# createPlugin - router + +The router that is passed to the `register` function includes makes it possible for plugins to hook into routing of the Backstage app and provide the end users with new views to navigate to. + +```typescript +type RouterHooks = { + registerRoute( + path: RoutePath, + Component: ComponentType, + options?: RouteOptions, + ): void; + + registerRedirect( + path: RoutePath, + target: RoutePath, + options?: RouteOptions, + ): void; +}; +``` + +[Back to References](README.md) diff --git a/docs/reference/createPlugin.md b/docs/reference/createPlugin.md new file mode 100644 index 0000000000..779e1ef820 --- /dev/null +++ b/docs/reference/createPlugin.md @@ -0,0 +1,40 @@ +# createPlugin + +Taking a plugin config as argument and returns a new plugin. + +## Plugin Config + +```typescript +function createPlugin(config: PluginConfig): BackstagePlugin; + +type PluginConfig = { + id: string; + register?(hooks: PluginHooks): void; +}; + +type PluginHooks = { + router: RouterHooks; +}; +``` + +[Read more about the router here](createPlugin-router.md) + +## Example Uses + +### Creating a basic plugin + +Showcasing adding multiple routes and a redirect. + +```jsx +import { createPlugin } from '@spotify-backstage/core'; +import ExampleComponent from './components/ExampleComponent'; + +export default createPlugin({ + id: 'new-plugin', + register({ router }) { + router.registerRoute('/new-plugin', ExampleComponent); + }, +}); +``` + +[Back to References](README.md)