Custom component library

Updated at:

This topic describes how to develop and use a custom component library on the Mobi platform. Install the scaffolding to flexibly develop and debug your component library.

Overview

The Mobi platform includes two built-in system component libraries. For more information, see System component libraries. To extend the customization capabilities of the Mobi platform, a scaffolding tool is provided. Use this scaffolding to develop custom component libraries in your local Integrated Development Environment (IDE) that comply with Mobi platform specifications. After development, upload the library to the Mobi platform.

Develop a custom component library

Prerequisites

Before developing a custom component library with the scaffolding, ensure your development environment meets the following requirements:

  • Node.js >= 20.0.0

  • npm >= 9.0.0

Check the versions:

node -v   # Should display v20.0.0 or later
npm -v    # Should display 9.0.0 or later

If your versions are outdated, upgrade Node.js and npm.

Install the scaffolding

Install the scaffolding tool globally:

npm install -g mobi-ccl-cli

After installation completes, you can use the mccl command from any directory.

Verify the installation:

mccl -v
# or
mccl --version

Getting started

1. Initialize the project

In the directory where you want to create the project, run:

mccl init

The scaffolding prompts you for the following information:

  1. Component library name: Enter the component library name.

    • Example: my-custom-components

    • Description: The name of the component library. This name is used as the category for your components in the materials panel by default.

  2. Component library description: Enter the component library description.

    • Example: This is a custom component library based on antd

    • Description: Describe the purpose of your component library.

  3. Component library global variable name: Enter the global variable name for the component library.

    • Example: MyCustomComponents

    • Description: Use PascalCase. The first letter must be uppercase, and subsequent characters can be uppercase letters, lowercase letters, or numbers. This name serves as a unique identifier. Do not modify it after it is set.

After initialization, a new project directory is created. The directory name matches the global variable name you entered.

Generated project structure:

YourGlobalName/
├── mobi.config.js          # Configuration file
├── package.json            # Project dependency configuration
├── tsconfig.json           # TypeScript configuration
├── tsconfig.node.json      # TypeScript configuration file for the Node.js environment
├── .gitignore              # Git ignore file
├── .nvmrc                  # Node.js version specification
├── README.md               # Project documentation
└── src/                    # Component source directory
    └── HelloMobi/          # Sample component
        ├── index.tsx       # Component implementation
        └── config.ts       # Component configuration

Note:

  • Do not modify the global variable name after it is set, because it is the unique identifier for the component.

  • Initialization creates a new folder in the current directory and does not overwrite existing files.

2. Enter the project directory and install dependencies

cd YourGlobalName  # Replace with your global variable name
npm install # or pnpm install

3. Start the debug mode

mccl dev
# or
npm run dev

Scenarios:

  • Preview changes in real time during component development.

  • Debug component configurations.

  • Perform integration testing with the Mobi platform.

Stop the service:

Press Ctrl+C to exit debug mode.

  • Note:

    • Debug mode must be used with the Mobi platform. For more information, see the following sections.

4. Build the production version

mccl build
# or
npm run build

Build artifacts:

After the build completes, a dist.zip file is generated in the project's root directory. Upload this build artifact to the Mobi console to use it. For more information, see the following sections.

Command reference

1. mccl -v / --version - View the version

Function: View the current version of the scaffolding.

Usage:

mccl -v
# or
mccl --version

2. mccl -h / --help - View help

Function: View the help documentation for the scaffolding.

Usage:

mccl -h
# or
mccl --help

Configuration file reference

mobi.config.js - Core configuration file

mobi.config.js is the core configuration file for the scaffolding and is located in the project root directory. It defines the basic information of the component library, component scanning rules, and build configurations.

Configuration file structure
// Mobi custom component library configuration file
export default {
  // === Basic library information ===
  library: {
    name: "QiDian Components",
    description: "This is a custom component library",
  },

  // === Component configuration ===
  components: {
    // Component directory
    dir: "src",
    // Specifies whether to automatically scan the component directory
    autoScan: true,
    // Manually specify components (used when autoScan is false)
    include the following: [],
    // Excluded components
    exclude: [],
  },

  // === Build configuration ===
  build: {
    // UMD global variable name (PascalCase)
    globalName: "MyCompoLib",
    // Output directory
    outDir: "dist",
    // External dependencies (not bundled)
    external: ["react", "react-dom", "antd", "dayjs", "@ant-design/icons"],
    // Global variable mapping
    globals: {
      react: "React",
      "react-dom": "ReactDOM",
      antd: "antd",
      dayjs: "dayjs",
      "@ant-design/icons": "AntdIcons",
    },
  },
};
library - Basic library information

Function: Defines the basic metadata for the component library.

Parameters:

Parameter

Type

Required

Description

Example

name

string

✅

The name of the component library. This name is displayed in the component list.

'my-custom-components'

description

string

✅

The description of the component library.

'This is a custom component library'

components - Component scanning configuration

Function: Configures component scanning rules to tell the scaffolding how to find and identify components.

Parameters:

Parameter

Type

Required

Description

Example

dir

string

✅

The component source directory, relative to the project root.

'src'

autoScan

boolean

✅

Specifies whether to automatically scan the component directory.

true

include

string[ ]

❌

A list of manually specified components. This parameter is used when autoScan is false.

['Button', 'Input']

exclude

string[ ]

❌

The component directories to exclude. This parameter takes effect only when autoScan is true.

['_internal', 'utils']

autoScan: true (automatic scan mode)

Recommended. This mode is suitable for most scenarios. The scaffolding automatically scans all first-level subdirectories in the dir directory as components.

Scanning rules:

  • ✅ Scans all first-level subdirectories in the dir directory.

  • ❌ Ignores directories specified in the exclude list.

Example:

components: {
  dir: 'src',
  autoScan: true,
  exclude: ['_internal', 'utils', 'types'],
}

Example directory structure:

src/
├── Button/          ✅ Recognized as the Button component
├── Input/           ✅ Recognized as the Input component
├── Card/            ✅ Recognized as the Card component
└── utils/           ❌ Excluded (in the exclude list)

autoScan: false (manual specification mode)

Scenario: Use this mode when you need to precisely control which components are included.

Configuration:

components: {
  dir: 'src',
  autoScan: false,
  include the following: ['Button', 'Input', 'Card'],
}

Note:

  • When autoScan is false, only the components specified in the include list are scanned.

  • The exclude configuration is invalid in manual mode.

  • If a directory specified in include does not exist, the component is skipped during the build.


build - Build configuration

Function: Configures build-related parameters, including the output directory, external dependencies, and global variable mapping.

Parameters:

Parameter

Type

Required

Description

Example

outDir

string

✅

The build output directory.

'dist'

external

string[]

✅

A list of external dependencies. These dependencies are not bundled into the UMD file.

['react', 'react-dom']

globals

Record<string, string>

✅

Global variable mapping. Maps external dependencies to global variables.

{ react: 'React' }

outDir - Output directory

Function: Specifies the output directory for build artifacts.

Example:

outDir: 'dist'  // Build artifacts are output to the dist.zip directory.

external - External dependencies

Function: Specifies which dependencies are not bundled into the UMD file and are instead treated as external dependencies.

Why you need this configuration:

  • Reduce the UMD file size.

  • Avoid duplicate packaging. The Mobi platform already integrates dependencies such as React, ReactDOM, and antd.

  • Improve loading performance.

Common external dependencies:

external: [
  'react',        // React library
  'react-dom',    // ReactDOM library
  'antd',         // Ant Design component library
  'dayjs',        // Date handling library
  '@ant-design/icons',       // Ant Design icon library
]

Note:

  • All dependencies declared in external must have a corresponding global variable mapping configured in globals.

  • If a dependency is not declared in external, it is bundled into the UMD file.

  • Add 'react', 'react-dom', 'antd', 'dayjs', and '@ant-design/icons' to external to reduce the file size and improve build efficiency.

globals - Global variable mapping

Function: Maps external dependencies to browser global variables.

Configuration rules:

  • key: The npm package name. This must correspond to a name in external.

  • value: The global variable name in the browser.

Example:

globals: {
  'react': 'React',           // The npm package react corresponds to the global variable React.
  'react-dom': 'ReactDOM',     // The npm package react-dom corresponds to the global variable ReactDOM.
  'antd': 'antd',             // The npm package antd corresponds to the global variable antd.
  'dayjs': 'dayjs',           // The npm package dayjs corresponds to the global variable dayjs.
}

How to determine the global variable name:

  1. React / ReactDOM: Usually React and ReactDOM.

  2. Third-party libraries: Check the library's documentation or inspect the global variables in the browser console.

  3. Custom libraries: Determine the name based on the library's UMD build configuration.

Note:

  • Each key in globals must also exist in external.

  • The global variable name must match the global variable name in the actual runtime environment. Otherwise, a runtime error occurs.


Component development guide

Component directory structure

Each component must be in a separate folder within the src directory:

src/
└── ComponentName/          # Component directory
    ├── index.tsx          # Component implementation
    └── config.ts          # Component configuration

File descriptions:

  • index.tsx: The React implementation code for the component.

  • config.ts: The component's configuration for the low-code platform.


Component implementation (index.tsx)

Basic structure:

import React from 'react';
import { Button as AntdButton } from 'antd';

export interface ButtonProps {
  text?: string;
  type?: 'primary' | 'default';
  onClick?: () => void;
}

const Button: React.FC<ButtonProps> = ({
  text = 'Click',
  type = 'primary',
  onClick,
}) => {
  return (
    <AntdButton type={type} onClick={onClick}>
      {text}
    </AntdButton>
  );
};

export default Button;

Export requirements:

  • ✅ Use export default to export the component.

  • ✅ The component name should match the directory name.

  • ❌ Anonymous exports are not supported.


Component configuration (config.ts)

Function: Defines the component's configuration in the low-code platform, including the properties panel, layout configuration, and metadata.

Basic structure:

const ButtonConfig = {
  // ========== Basic information ==========
  title: 'Custom Button',
  description: 'This is a button component',
  icon: 'https://xxx.jpg',
  category: 'Basic Components',
  
  // ========== Container related ==========
  isContainer: false,
  
  // ========== Properties panel configuration ==========
  inspectorConfig: [
    {
      title: 'Content',
      items: [
        {
          type: 'control',
          title: 'Button Text',
          name: 'text',
          defaultValue: 'Button',
          valueType: 'string',
          control: {
            type: 'Code',
            props: {},
          },
        },
      ],
    },
  ],
  
  // ========== Grid layout configuration ==========
  gridConfig: {
    dragRect: {
      w: 4,
      h: 32,
    },
    initHeight: () => ({ type: 'auto' }),
    supportHeightType: ['fixed', 'auto'],
  },
  
  // ========== Expose configuration ==========
  exposeConfig: {

    methods: [ ],

  },
};

export default ButtonConfig;

For more information about the configuration parameters, see Component configuration development specifications.

Use a custom component library

Component library management

Create a component library

Use the mccl build command. A dist.zip file is generated in the project's root directory if you set outDir: 'dist' in the mobi.config.js file. Upload this dist.zip file to the Mobi platform for management.

Update a component library

Click Update in the Actions column for the component library you want to update. Enter the new version and update description. Then, upload the new version of the component library to update it.

Click View in the Actions column to see the release information for each version of the component library in the release history.

Note:

  • When you update a component library, make sure its globalName remains unchanged.

Use a component library

Component libraries uploaded to the Mobi platform can be loaded and used in Mobi applications.

Go to Settings > Component Library > Custom Component Library and click Add.

In the dialog box that appears, select the custom component library you want to use in the application and add it.

Select the version of the component library to use.

After the library is added, drag its components onto the canvas to use them.

Enable debug mode

Debug mode provides real-time previews during component library development. When you change your local code, the component on the canvas automatically updates. Debug mode is a temporary state. After you finish developing the component, disable debug mode. Then, build the component into a formal component library and upload it to the Mobi console for management and long-term use.

First, run mccl dev locally to enable debug mode.

Then, enable debug mode in the Mobi application by going to Settings > Component Library. When the name of the component library being debugged appears at the bottom of the page, the library is in debug mode. If you drag a component from this library onto the canvas, the component displays a "Debugging" label. When you modify the local component code, the component on the canvas updates automatically.

FAQ

Q1: How do I add a new component?

A: Create a new component folder in the src directory. The folder must contain an index.tsx file and an optional config.ts file. If autoScan is true, the scaffolding automatically detects the new component.

Example:

mkdir src/MyNewComponent
touch src/MyNewComponent/index.tsx
touch src/MyNewComponent/config.ts

Then, write the component code and configuration.

Q2: How do I exclude a component from being scanned?

A: Use the `exclude` configuration:

components: {
  autoScan: true,
  exclude: ['MyComponent'],  // Exclude MyComponent
}

Q3: How do I exclude an external dependency?

A: Follow these two steps:

  1. Configure mobi.config.js:

build: {
  external: ['react', 'react-dom', 'your-package'],  // Add to external
  globals: {
    'react': 'React',
    'react-dom': 'ReactDOM',
    'your-package': 'YourPackageGlobal',  // Add global variable mapping
  },
}
  1. Import the external dependency in your Mobi application:

For example, if you excluded lodash during the build, import the CDN resource for lodash in the Mobi platform.

Q4: What should I do if a component does not appear?

A: Troubleshoot the issue as follows:

  1. Check the directory structure: Make sure the component directory contains an index.tsx file.

  2. Check the export method: Make sure the component is exported using export default.

  3. Check the configuration: Make sure the components.dir setting in mobi.config.js is correct.

  4. Check the exclusion list: Make sure the component is not in the exclude list.

  5. Check the build log: Run mccl build and check for any error messages.

Q5: Which versions of React are supported?

A: React 18.x is recommended.

Q6: What should I do if the build fails?

A: Troubleshoot the issue as follows:

  1. Check the Node.js version: Make sure it is 20.0.0 or later.

  2. Check the configuration file: Make sure the format of mobi.config.js is correct.

  3. Check the component code: Make sure there are no syntax errors in your component code.

  4. Check the error message: When a build fails, a detailed error message is displayed. Use the error message to fix the problem.