DEV Community

Cover image for Whats Medusa an introduction part 3 Modules
Norbert Fuhs
Norbert Fuhs

Posted on

Whats Medusa an introduction part 3 Modules

In this blogpost I will introduce you to Modules and how you can use them.

Modules are self-contained reusable pieces of code which add functionality to your ecommerce application.
Modules increase Medusas extensibilty and can be seen as small units of independent code. Modules can run independently of Medusas core package.

Modules are created and loaded similarly to plugins. They can be loaded from a local project or can be installed from an NPM package.

Create a module

Create a directory with the following structure in it:

custom-module
|
|--index.ts
|
|--services // directory
Enter fullscreen mode Exit fullscreen mode

The directory can be an NPM project but that's optional. index.ts is the entry point to our module. The services directory holds extra services. The following TypeScript configuration file tsconfig.json should be added in the root of the project.

{
  "compilerOptions": {
    "lib": [
      "es2020"
    ],
    "target": "2020",
    "outDir": "./dist",
    "esModuleInterop": true,
    "declaration": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "noImplicitReturns": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "allowJs": true,
    "skipLibCheck": true,
  },
  "include": ["src"],
  "exclude": [
    "dist",
    "./src/**/__tests__",
    "./src/**/__mocks__",
    "./src/**/__fixtures__",
    "node_modules"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Implementing the module

When developing the module you'll later reference the module using a file path to a index.js or index.ts file.
This file acts as an entry point to our module.

Export the module

To use the module withe the medusa backend we need to export it. This is done in the file index.ts the file must export an object with the following properties:

type ModuleExports = {
  service: Constructor<any>
  loaders?: ModuleLoaderFunction[]
  migrations?: any[]
  models?: Constructor<any>[]
  runMigrations?(
    options: LoaderOptions,
    moduleDeclaration: InternalModuleDeclaration
  ): Promise<void>
  revertMigration?(
    options: LoaderOptions,
    moduleDeclaration: InternalModuleDeclaration
  ): Promise<void>
}
Enter fullscreen mode Exit fullscreen mode

Reference module

To use the module in the Medusa backend add your module to medusa-config.js:

module.exports = {
  // ...
  modules: { 
    // ...
    moduleType: {
      resolve: "module-name-or-path", 
      options: {
        // options if necessary
      },
      // optional
      resources: "shared",
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

Module reference

If a module is installed as NPM package the value of the resolve property should be the name of the package:

module.exports = {
  // ...
  modules: { 
    // ...
    moduleType: {
      resolve: "custom-module", 
      // ...
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

Whe using a local module you must reference the module from using an relative file path to ot from the Medusa backend.

|
|---custom module
|   |
|   |---index.ts
|   |
|   |---services
|   |    |
|   |    |---custom-service.ts
|
|
|
---medusa-backend
Enter fullscreen mode Exit fullscreen mode

You can reference your module in two ways:

  1. Referencing the directory the index.ts file is in the root of the directory

medusa-config.js:

module.exports = {
  // ...
  modules: { 
    // ...
    moduleType: {
      resolve: "../custom-module", 
      // ...
    },
  },
}
Enter fullscreen mode Exit fullscreen mode
  1. Referencing the index file medusa-config.js
module.exports = {
  // ...
  modules: { 
    // ...
    moduleType: {
      resolve: "../custom-module/index.ts", 
      // ...
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

Test your module

Test your module running the following command:

npx @medusajs/medusa-cli develop
Enter fullscreen mode Exit fullscreen mode

Howto publish a module

You'll need an NPM account to publish a module.

Create an NPM project

Run the folllowing commands to create a directory and init an NPM project in it:

mkdir my-module
yarn init
Enter fullscreen mode Exit fullscreen mode

A package.json file will be created inside the directory.

Changes to package.json

In your package.json file add the following fields:

{
  // other fields
  "main": "dist/index.js",
  "publishConfig": {
    "access": "public"
  },
  "files": [
    "dist"
  ],
  "devDependencies": {
    "@medusajs/types": "^0.0.2",
    "cross-env": "^5.2.1",
    "typescript": "^4.4.4"
  },
  "scripts": {
    "watch": "tsc --build --watch",
    "prepare": "cross-env NODE_ENV=production npm run build",
    "build": "tsc --build",
  },
  "dependencies": {
    "@medusajs/modules-sdk": "^0.1.0",
  }
}
Enter fullscreen mode Exit fullscreen mode

Configure tsconfig.json

Create a tsconfig.json file in the root of your NPM project:

tsconfig.json

{
  "compilerOptions": {
    "lib": [
      "es2020"
    ],
    "target": "2020",
    "outDir": "./dist",
    "esModuleInterop": true,
    "declaration": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "noImplicitReturns": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "allowJs": true,
    "skipLibCheck": true,
  },
  "include": ["src"],
  "exclude": [
    "dist",
    "./src/**/__tests__",
    "./src/**/__mocks__",
    "./src/**/__fixtures__",
    "node_modules"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Publish and use module

Run prepare command

yarn prepare
Enter fullscreen mode Exit fullscreen mode

Login into your npm account:

npm login
Enter fullscreen mode Exit fullscreen mode

Publish module package

npm publish
Enter fullscreen mode Exit fullscreen mode

Thats all for now on modules in Medusa.js I hope you enjoyed this blogpost.

Top comments (1)

Collapse
 
jlozanof profile image
Joel Lozano

Me gustaria empezar desde el inicio! recien estoy conociendo medusa y me gustaria leer un poco mas