From 433914ae01ad5223b6d2e5c2eba92f1737ece191 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Fri, 4 Aug 2023 17:26:39 +0300 Subject: [PATCH] docs: revamp plugin documentation pages (#4694) * docs: revamp plugin documentation pages * fix eslint errors * change order of scripts --- docs/content/development/plugins/create.mdx | 242 +++++++++---------- docs/content/development/plugins/publish.mdx | 70 +++--- 2 files changed, 146 insertions(+), 166 deletions(-) diff --git a/docs/content/development/plugins/create.mdx b/docs/content/development/plugins/create.mdx index 14b1e22170..c0e9ef8bf1 100644 --- a/docs/content/development/plugins/create.mdx +++ b/docs/content/development/plugins/create.mdx @@ -12,23 +12,9 @@ In this document, you’ll learn how to create a plugin and some tips for develo ## Prerequisites -This guide uses the Medusa CLI throughout different steps. If you don’t 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 -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: +The recommended way to create a plugin is using the `new` command from Medusa CLI: ```bash 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 +### 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 -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 -"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`. +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`. Additionally, you can remove `@medusajs/medusa-cli` as you don’t 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 you’re done making these changes, re-run the install command to update your `node_modules` directory: ```bash npm2yarn @@ -103,32 +67,11 @@ const plugins = [] 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 :::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 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. -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 "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: @@ -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 - -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 Development ### 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 you’re 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 you’re integrating. - -To pass a plugin its configurations on a Medusa backend, you have to add it to the `plugins` array in `medusa-config.js`: +Developers that use your plugin will pass options to your plugin in the `plugins` array in `medusa-config.js`: ```js title=medusa-config.js 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 class MyService extends TransactionBaseService { constructor(container, options) { super(container) - // options contains plugin configurations + // options contains plugin options 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 // in an endpoint in your plugin export default (rootDirectory, options) => { - // options contain the plugin configurations + // options contain the plugin options const router = Router() router.get("/hello-world", (req, res) => { @@ -433,7 +390,7 @@ export default (rootDirectory, options) => { :::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. -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 const plugins = [ @@ -465,7 +422,7 @@ For example: class MyService extends TransactionBaseService { constructor(container, options) { super(container) - // options contains plugin configurations + // options contains plugin options const { enableUI, ...otherOptions } = options // pass otherOptions to a third-party service const client = new Client(otherOptions) @@ -476,7 +433,7 @@ class MyService extends TransactionBaseService { :::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 -While you develop your plugin, you’ll 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, you’ll 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 + + + + + In the root of your plugin directory, run the `build` command: + + ```bash + npm run build + ``` + + + + + 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). + + + + +### Step 2: Link Package 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 ``` -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 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. -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 -# in the directory of the plugin -npm run watch +As your plugin has the `@medusajs/medusa` package installed, and the Medusa backend has `@medusajs/medusa` installed as well, this can cause dependency errors. + +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 you’re running the `watch` command, you don’t 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: -::: - -Then, add your plugin into the array of plugins in `medusa-config.js`: - -```js title=medusa-config.js +```js const plugins = [ - // ... + // other plugins... { resolve: `medusa-plugin-custom`, - // if your plugin has configurations 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 plugin’s 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 -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 #### Error: The class must be a valid service implementation @@ -582,12 +582,6 @@ npm run start Where `` is the path to your Medusa backend, `` is the path to your plugin and `` 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 diff --git a/docs/content/development/plugins/publish.mdx b/docs/content/development/plugins/publish.mdx index c48805e070..59b760eaac 100644 --- a/docs/content/development/plugins/publish.mdx +++ b/docs/content/development/plugins/publish.mdx @@ -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 @@ -46,56 +46,42 @@ Before publishing your plugin, make sure you've set the following fields in your - 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 "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" } ``` - 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. - - This new script requires installing the package `cross-env` as a development dependency: - - ```bash npm2yarn - npm install --save-dev cross-env - ``` + The `prepare` script facilitates your publishing process. You would typically run this script before publishing your plugin. 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 "scripts": { // other scripts... - "build": "tsc -p ./tsconfig.server.json && medusa-admin bundle", - "prepare": "cross-env NODE_ENV=production npm run build" + "build:server": "cross-env npm run clean && tsc -p tsconfig.json", + "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 `prepare` command 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 - ``` + 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` script creates a production build of both backend and admin resources. -### - ### 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. @@ -125,6 +111,8 @@ src .prettierrc build .cache +.yarn +uploads # These are files that are included in 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). -### 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): @@ -151,37 +139,35 @@ Before you publish or update your plugin, make sure to run the `prepare` command npm run prepare ``` -### Login +### Step 2: Publish Plugin Package -In your terminal, log in with your NPM account: - -```bash -npm login -``` - -You’ll be asked to enter your NPM email and password. - -### Publish Plugin Package - -Once you’re logged in, you can publish your package with the following command: +You can publish your package with the following command: ```bash 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. -### 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 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 npm version