docs: revamp plugin documentation pages (#4694)

* docs: revamp plugin documentation pages

* fix eslint errors

* change order of scripts
This commit is contained in:
Shahed Nasser
2023-08-04 17:26:39 +03:00
committed by GitHub
parent 1260b1a806
commit 433914ae01
2 changed files with 146 additions and 166 deletions
+118 -124
View File
@@ -12,23 +12,9 @@ In this document, youll learn how to create a plugin and some tips for develo
## Prerequisites ## Prerequisites
This guide uses the Medusa CLI throughout different steps. If you dont have the Medusa CLI installed you can install it with the following command: You must have an existing Medusa project that you want to create the plugin with.
```bash npm2yarn The recommended way to create a plugin is using the `new` command from Medusa CLI:
npm install @medusajs/medusa-cli -g
```
:::note
If you run into any errors while installing the CLI tool, check out the [troubleshooting guide](../../troubleshooting/cli-installation-errors.mdx).
:::
---
## Initialize Project
The recommended way to create a plugin is using the Medusa CLI. Run the following command to create a new Medusa project:
```bash ```bash
npx @medusajs/medusa-cli@latest new medusa-plugin-custom npx @medusajs/medusa-cli@latest new medusa-plugin-custom
@@ -42,51 +28,29 @@ By convention, all plugin names start with `medusa` followed by a descriptive na
## Changes to package.json ## Changes to package.json
### Package Name
By default, your package name in `package.json` will be `medusa-starter-default`. This should instead be the name of your plugin. For example, the Stripe plugin's package name is `medusa-payment-stripe`.
### Change Dependencies ### Change Dependencies
A basic Medusa backend installed with the `medusa new` command has dependencies similar to this: A basic Medusa backend installed with the `medusa new` command has dependencies that are necessary for the backend, but not necessary for plugins.
```json title=package.json For example, can remove the dependencies `medusa-fulfillment-manual`, `medusa-payment-manual`, and `medusa-payment-stripe` as they are fulfillment and payment plugins necessary for a Medusa backend, but not for a plugin. The same goes for modules like `@medusajs/cache-inmemory`.
"dependencies": {
"@babel/preset-typescript": "^7.21.4",
"@medusajs/cache-inmemory": "^1.8.0",
"@medusajs/cache-redis": "^1.8.0",
"@medusajs/event-bus-local": "^1.8.0",
"@medusajs/event-bus-redis": "^1.8.0",
"@medusajs/medusa": "^1.8.0",
"@medusajs/medusa-cli": "^1.3.9",
"babel-preset-medusa-package": "^1.1.13",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.2",
"medusa-fulfillment-manual": "^1.1.37",
"medusa-interfaces": "^1.3.7",
"medusa-payment-manual": "^1.0.23",
"medusa-payment-stripe": "^2.0.0",
"typeorm": "^0.3.11"
},
"devDependencies": {
"@babel/cli": "^7.14.3",
"@babel/core": "^7.14.3",
"@types/express": "^4.17.13",
"@types/jest": "^27.4.0",
"@types/node": "^17.0.8",
"babel-preset-medusa-package": "^1.1.13",
"cross-env": "^5.2.1",
"eslint": "^6.8.0",
"jest": "^27.3.1",
"mongoose": "^5.13.14",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.7",
"ts-loader": "^9.2.6",
"typescript": "^4.5.2"
},
```
For a plugin, some dependencies are not necessary. For example, can remove the packages `medusa-fulfillment-manual`, `medusa-payment-manual`, and `medusa-payment-stripe` as they are fulfillment and payment plugins necessary for a Medusa backend, but not for a plugin. The same goes for modules like `@medusajs/cache-inmemory`.
Additionally, you can remove `@medusajs/medusa-cli` as you dont need to use the Medusa CLI while developing a plugin. Additionally, you can remove `@medusajs/medusa-cli` as you dont need to use the Medusa CLI while developing a plugin.
You should also add `@medusajs/medusa` as a peer dependency:
```json
"peerDependencies": {
"@medusajs/medusa": "YOUR_MEDUSA_VERSION",
// other peer dependencies...
}
```
Where `YOUR_MEDUSA_VERSION` is the version you're using of the Medusa core package. You should be able to find it under `devDependencies`.
Once youre done making these changes, re-run the install command to update your `node_modules` directory: Once youre done making these changes, re-run the install command to update your `node_modules` directory:
```bash npm2yarn ```bash npm2yarn
@@ -103,32 +67,11 @@ const plugins = []
const modules = {} const modules = {}
``` ```
### Recommended: Change Scripts
It's recommended to remove the `seed` and `start` scripts from your `package.json` as they aren't necessary for plugin development.
Furthermore, if you don't have a `watch` command in your `package.json` it's recommended to add it:
```json title=package.json
"scripts": {
// other scripts...
"watch": "tsc --watch"
}
```
The `watch` command makes the [testing of the plugin](#test-your-plugin) easier.
:::tip
The `watch` command outputs the files in the destination specified in the value of `outDir` in `tsconfig.json`, and the same goes for the `build` command. If you made changes to `tsconfig.json`, make sure the destination is either the `dist` directory or the root of the plugin. You can learn more in the [plugin structure section](#plugin-structure).
:::
### Changes for Admin Plugins ### Changes for Admin Plugins
:::note :::note
Admin customizations are currently in beta and require you to use the `beta` version of `@medusajs/admin` and `@medusajs/medusa`. You can install it with the following command: Admin customizations are currently in beta and require you to use the `beta` version of `@medusajs/admin` and `@medusajs/medusa`. You can install them with the following command:
```bash npm2yarn ```bash npm2yarn
npm install @medusajs/admin@beta @medusajs/medusa@beta npm install @medusajs/admin@beta @medusajs/medusa@beta
@@ -215,16 +158,24 @@ Then, create the file `tsconfig.admin.json` with the following content:
This is the configuration that will be used when transpiling your admin code. This is the configuration that will be used when transpiling your admin code.
Finally, update the `build` script in your project: Finally, update the `build` scripts in your project and add a new `prepare` command:
```json title=package.json ```json title=package.json
"scripts": { "scripts": {
// other scripts... // other scripts...
"build": "tsc -p ./tsconfig.server.json && medusa-admin bundle" "build": "cross-env npm run clean && npm run build:server && npm run build:admin",
"build:server": "cross-env npm run clean && tsc -p tsconfig.json",
"build:admin": "cross-env medusa-admin build",
"prepare": "cross-env NODE_ENV=production npm run build:server && medusa-admin bundle"
} }
``` ```
This `build` script builds the backend customizations, then bundles the admin plugin using `medusa-admin bundle`. Each of these scripts do the following:
- `build`: used to build resources for both admin and backend for development. You'll typically use this script during your plugin development.
- `build:server`: used to build backend resources for development.
- `build:admin`: used to build admin resources for development.
- `prepare`: used to build resources for publishing. You'll typically use this script during plugin testing and publishing.
Furthermore, make sure to add `react` to `peerDependencies` along with `react-router-dom` if you're using it: Furthermore, make sure to add `react` to `peerDependencies` along with `react-router-dom` if you're using it:
@@ -236,11 +187,15 @@ Furthermore, make sure to add `react` to `peerDependencies` along with `react-ro
} }
``` ```
### Delete Irrelevant Files
If you've installed the Medusa backend using the [create-medusa-app](../../create-medusa-app.mdx) command, you might find files under the `src` sub-directories that aren't necessary for your plugin development. For example, `src/model/onboarding.ts` or migrations under the `src/migrations` directory.
Make sure to delete these files if you're not using them in your plugin.
--- ---
## Develop your Plugin ## Plugin Development
Now, You can start developing your plugin. This can include adding services, endpoints, entities, admin customizations, or anything that's relevant to your plugin.
### Plugin Structure ### Plugin Structure
@@ -378,13 +333,11 @@ If you're developing something specific, such as a payment processor plugin, you
}, },
]} /> ]} />
--- ### Plugin Options
## Add Plugin Configuration Plugins often allow developers that will later use them to provide their own option. For example, you can allow developers to specify the API key of a service youre integrating.
Plugins often allow developers that will later use them to enter their own configuration. For example, you can allow developers to specify the API key of a service youre integrating. Developers that use your plugin will pass options to your plugin in the `plugins` array in `medusa-config.js`:
To pass a plugin its configurations on a Medusa backend, you have to add it to the `plugins` array in `medusa-config.js`:
```js title=medusa-config.js ```js title=medusa-config.js
const plugins = [ const plugins = [
@@ -398,26 +351,30 @@ const plugins = [
] ]
``` ```
Then, you can have access to your plugin configuration in the constructor of services in your plugin: In your plugin's services, you can have access to the option in their constructor. The options are passed as a second parameter to the `constructor` method.
```js title=src/service/test.ts For example:
```js title=src/service/my.ts
// In a service in your plugin // In a service in your plugin
class MyService extends TransactionBaseService { class MyService extends TransactionBaseService {
constructor(container, options) { constructor(container, options) {
super(container) super(container)
// options contains plugin configurations // options contains plugin options
this.name = options.name this.name = options.name
} }
// ... // ...
} }
``` ```
You can also have access to the configurations in endpoints in your plugin: You can also access the options in your plugin's endpoints. The second parameter that the function declared in `src/api/index.ts` receives is an object including your plugin's configrations.
For example:
```js title=src/api/index.ts ```js title=src/api/index.ts
// in an endpoint in your plugin // in an endpoint in your plugin
export default (rootDirectory, options) => { export default (rootDirectory, options) => {
// options contain the plugin configurations // options contain the plugin options
const router = Router() const router = Router()
router.get("/hello-world", (req, res) => { router.get("/hello-world", (req, res) => {
@@ -433,7 +390,7 @@ export default (rootDirectory, options) => {
:::tip :::tip
Make sure to include in the README of your plugin the configurations that can be passed to a plugin. Make sure to include in the README of your plugin the options that can be passed to a plugin.
::: :::
@@ -441,7 +398,7 @@ Make sure to include in the README of your plugin the configurations that can be
All plugins accept an option named `enableUI`. This option is useful mainly if your plugin contains admin customizations. It allows users to enable or disable admin customizations in the admin dashboard. All plugins accept an option named `enableUI`. This option is useful mainly if your plugin contains admin customizations. It allows users to enable or disable admin customizations in the admin dashboard.
You can pass the `enableUI` option to plugins as follows: A developer using your plugin can pass the `enableUI` option as part of the plugin's options:
```js title=medusa-config.js ```js title=medusa-config.js
const plugins = [ const plugins = [
@@ -465,7 +422,7 @@ For example:
class MyService extends TransactionBaseService { class MyService extends TransactionBaseService {
constructor(container, options) { constructor(container, options) {
super(container) super(container)
// options contains plugin configurations // options contains plugin options
const { enableUI, ...otherOptions } = options const { enableUI, ...otherOptions } = options
// pass otherOptions to a third-party service // pass otherOptions to a third-party service
const client = new Client(otherOptions) const client = new Client(otherOptions)
@@ -476,7 +433,7 @@ class MyService extends TransactionBaseService {
:::note :::note
Since admin customizations are still in `beta` mode, `enableUI`'s default value is `false` if not provided by the plugin users. This means that it must be enabled manually in a plugin's configuration for the customizations to appear in the admin dashboard. Once the admin customizations are out of beta, this behavior will be reversed. Since admin customizations are still in `beta` mode, `enableUI`'s default value is `false` if not provided by the plugin users. This means that it must be enabled manually in a plugin's option for the customizations to appear in the admin dashboard. Once the admin customizations are out of beta, this behavior will be reversed.
::: :::
@@ -484,7 +441,34 @@ Since admin customizations are still in `beta` mode, `enableUI`'s default value
## Test Your Plugin ## Test Your Plugin
While you develop your plugin, youll need to test it on an actual Medusa backend. This can be done by using the [npm link](https://docs.npmjs.com/cli/v8/commands/npm-link) command. While you develop your plugin, youll need to test it on an actual Medusa backend. This can be done using the [npm link](https://docs.npmjs.com/cli/v8/commands/npm-link) command.
### Step 1: Build Changes
<Tabs groupId="plugin-preference">
<TabItem value="without-admin" label="Without Admin Customizations" default>
In the root of your plugin directory, run the `build` command:
```bash
npm run build
```
</TabItem>
<TabItem value="with-admin" label="With Admin Customizations">
In the root of your plugin directory, run the `prepare` command:
```bash
npm run prepare
```
If the `prepare` script is not available in your project, you can find it in [this section](#changes-for-admin-plugins).
</TabItem>
</Tabs>
### Step 2: Link Package
In the root of your plugin directory, run the following command: In the root of your plugin directory, run the following command:
@@ -492,7 +476,7 @@ In the root of your plugin directory, run the following command:
npm link npm link
``` ```
Then, change to the directory of the Medusa backend you want to test the plugin on and run the following command: Then, in the directory of the Medusa backend you want to test the plugin on, run the following command:
```bash npm2yarn ```bash npm2yarn
npm link medusa-plugin-custom npm link medusa-plugin-custom
@@ -500,46 +484,62 @@ npm link medusa-plugin-custom
Where `medusa-plugin-custom` is the package name of your plugin. Where `medusa-plugin-custom` is the package name of your plugin.
After linking to your plugin in a local Medusa backend, either run the `build` or `watch` commands in your plugin directory: ### Step 3: Remove Medusa Dependency
```bash npm2yarn As your plugin has the `@medusajs/medusa` package installed, and the Medusa backend has `@medusajs/medusa` installed as well, this can cause dependency errors.
# in the directory of the plugin
npm run watch To avoid that, remove the `@medusajs` directory from the `node_modules` of your plugin's directory. For Unix-based operating systems you can use the following command:
```bash
rm -rf node_modules/@medusajs
``` ```
:::tip ### Step 4: Add Plugin to Configurations
If youre running the `watch` command, you dont need to run the `build` command every time you make a change to your plugin. In the `medusa-config.js` file of the Medusa backend you're testing the plugin on, add your custom plugin to the `plugins` array:
::: ```js
Then, add your plugin into the array of plugins in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [ const plugins = [
// ... // other plugins...
{ {
resolve: `medusa-plugin-custom`, resolve: `medusa-plugin-custom`,
// if your plugin has configurations
options: { options: {
name: "My Store", // plugin options...
// if plugin has admin customizations:
enableUI: true,
}, },
}, },
] ]
``` ```
:::note Make sure to change `medusa-plugin-custom` with the name of your plugin. Also, if your plugin has admin customizations, make sure to include the [enableUI](#enableui-plugin-option) option.
If your plugin has migrations, you must run them before you start the backend. Check out the [Migrations guide](../entities/migrations/overview.mdx#migrate-command) for more details. ### (Optional) Step 5: Run Migrations
::: If your plugin includes migrations, run the following command in the Medusa backend's directory:
Finally, start your backend and test your plugins functionalities: ```bash
npx medusa migrations run
```
### Step 6: Run the Medusa Backend
In the directory of the Medusa backend, start the backend with the `dev` command passing it the `--preserve-symlinks` option:
```bash npm2yarn ```bash npm2yarn
npm run start npm run dev -- -- --preserve-symlinks
``` ```
### Making Changes to the Plugin
While testing your plugin, if you need to make changes you need to re-install the plugin's dependencies:
```bash npm2yarn
npm install
```
Then, after making the changes, run the steps [one](#step-1-build-changes), [three](#step-3-remove-medusa-dependency), and [six](#step-6-run-the-medusa-backend) mentioned above.
### Troubleshoot Errors ### Troubleshoot Errors
#### Error: The class must be a valid service implementation #### Error: The class must be a valid service implementation
@@ -582,12 +582,6 @@ npm run start
Where `<BACKEND_PATH>` is the path to your Medusa backend, `<PLUGIN_PATH>` is the path to your plugin and `<PLUGIN_NAME>` is the name of your plugin as it is in your plugin `package.json` file. Where `<BACKEND_PATH>` is the path to your Medusa backend, `<PLUGIN_PATH>` is the path to your plugin and `<PLUGIN_NAME>` is the name of your plugin as it is in your plugin `package.json` file.
:::note
It is safe to ignore any `cross-env: command not found` error you may receive.
:::
--- ---
## Publish Plugin ## Publish Plugin
+28 -42
View File
@@ -16,7 +16,7 @@ If you haven't created a plugin yet, please check [this guide to learn how to cr
--- ---
## Prepare the Plugin ## Prepare Plugin
### package.json Checklist ### package.json Checklist
@@ -46,56 +46,42 @@ Before publishing your plugin, make sure you've set the following fields in your
<Tabs groupId="plugin-preference"> <Tabs groupId="plugin-preference">
<TabItem value="without-admin" label="Without Admin Customizations" default> <TabItem value="without-admin" label="Without Admin Customizations" default>
Make sure you add the `publish` command to your `scripts` field and make the following change to the `build` command: Make sure you add the `publish` script to your `scripts` field:
```json title=package.json ```json title=package.json
"scripts": { "scripts": {
// other scripts... // other scripts...
"build": "cross-env npm run clean && tsc", "build": "cross-env npm run clean && tsc -p tsconfig.json",
"prepare": "cross-env NODE_ENV=production npm run build" "prepare": "cross-env NODE_ENV=production npm run build"
} }
``` ```
The `build` command ensures that the plugin's built files are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation. The `build` script ensures that the plugin's built files are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation.
The `prepare` command facilitates your publishing process. You would typically run this script before publishing your plugin. The `prepare` script facilitates your publishing process. You would typically run this script before publishing your plugin.
This new script requires installing the package `cross-env` as a development dependency:
```bash npm2yarn
npm install --save-dev cross-env
```
</TabItem> </TabItem>
<TabItem value="with-admin" label="With Admin Customizations"> <TabItem value="with-admin" label="With Admin Customizations">
First, make sure to change `tsconfig` files as recommended in the [create guide](./create.mdx#changes-for-admin-plugins). First, make sure to change `tsconfig` files as recommended in the [create guide](./create.mdx#changes-for-admin-plugins).
Then, add the `publish` command to your `scripts` field and make the following change to the `build` command: Then, add the following `prepare` and `build` scripts to your `scripts`
```json title=package.json ```json title=package.json
"scripts": { "scripts": {
// other scripts... // other scripts...
"build": "tsc -p ./tsconfig.server.json && medusa-admin bundle", "build:server": "cross-env npm run clean && tsc -p tsconfig.json",
"prepare": "cross-env NODE_ENV=production npm run build" "prepare": "cross-env NODE_ENV=production npm run build:server && medusa-admin bundle"
} }
``` ```
The `build` command ensures that the plugin's built files are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation, and bundles the admin customizations. The `build:server` script builds the resources of the backend for development and ensures they are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation.
The `prepare` command facilitates your publishing process. You would typically run this script before publishing your plugin. The `prepare` script creates a production build of both backend and admin resources.
This new script requires installing the package `cross-env` as a development dependency:
```bash npm2yarn
npm install --save-dev cross-env
```
</TabItem> </TabItem>
</Tabs> </Tabs>
###
### Plugin Structure ### Plugin Structure
Make sure your plugin's structure is as described in the [Create Plugin](./create.mdx#plugin-structure) documentation. If you've made the changes mentioned in [the above section to the scripts](#scripts-in-packagejson) in `package.json`, you should have the correct structure when you run the `prepare` command. Make sure your plugin's structure is as described in the [Create Plugin](./create.mdx#plugin-structure) documentation. If you've made the changes mentioned in [the above section to the scripts](#scripts-in-packagejson) in `package.json`, you should have the correct structure when you run the `prepare` command.
@@ -125,6 +111,8 @@ src
.prettierrc .prettierrc
build build
.cache .cache
.yarn
uploads
# These are files that are included in a # These are files that are included in a
# Medusa project and can be removed from a # Medusa project and can be removed from a
@@ -143,7 +131,7 @@ This section explains how to publish your plugin to NPM.
Before you publish a plugin, you must [create an account on NPM](https://www.npmjs.com/signup). Before you publish a plugin, you must [create an account on NPM](https://www.npmjs.com/signup).
### Run Prepare Command ### Step 1: Run Prepare Command
Before you publish or update your plugin, make sure to run the `prepare` command [defined earlier](#packagejson-checklist): Before you publish or update your plugin, make sure to run the `prepare` command [defined earlier](#packagejson-checklist):
@@ -151,37 +139,35 @@ Before you publish or update your plugin, make sure to run the `prepare` command
npm run prepare npm run prepare
``` ```
### Login ### Step 2: Publish Plugin Package
In your terminal, log in with your NPM account: You can publish your package with the following command:
```bash
npm login
```
Youll be asked to enter your NPM email and password.
### Publish Plugin Package
Once youre logged in, you can publish your package with the following command:
```bash ```bash
npm publish npm publish
``` ```
If you haven't logged in before with your NPM account, you'll be asked to login first.
Your package is then published on NPM and everyone can use it and install it. Your package is then published on NPM and everyone can use it and install it.
### Install Plugin ---
To install your published plugin, you can run the following command on any Medusa backend project: ## Install Plugin
To install your published plugin, run the following command on any Medusa backend project:
```bash npm2yarn ```bash npm2yarn
npm install medusa-plugin-custom npm install medusa-plugin-custom
``` ```
### Update Plugin Where `medusa-plugin-custom` is your plugin's package name.
To update your plugin at a later point, you can run the following command to change the NPM version: ---
## Update Plugin
If you make changes to your plugin and you want to publish those changes, run the following command to change the NPM version:
```bash ```bash
npm version <type> npm version <type>