Component Spec
This page explains how a component must be organised so the platform can recognise, preview and publish it. A component is not "a file" but a folder.
Entry file
The folder name is the component name. The entry file is fixed per framework:
| Framework | Entry file | Notes |
|---|---|---|
| Vue 2 / Vue 3 | index.vue | Its presence alone means Vue |
| React 17 / 18 | index.jsx / index.tsx | Must default export |
| Web Component | index.js | The source must register a custom element |
Do not depend on both vue and react, or the platform cannot determine the framework.
Recommended directory structure
MyComponent/
├── index.vue # Entry (required)
├── README.md # Props, events, examples (recommended)
├── comp.json # Generated by the platform: __id__ / name / version
├── main.js # Global side effects executed in the preview environment only (optional)
├── demo/
│ ├── index.vue # Mini preview
│ └── full.vue # Full-screen preview
├── assets/
│ └── bg.png # Resources shipped with the component
└── screenshot_mini.png # Thumbnail (usually generated automatically)demo/ is a convention rather than a requirement: any .vue, .jsx or .tsx file in the folder can be chosen as a preview file; for Web Components, pick an .html file.
Referencing assets
Vue / React: use relative paths with import, not aliases such as @/.
// Correct
import bg from "./assets/bg.png";
// Wrong: the platform cannot resolve project aliases
import bg from "@/assets/bg.png";Web Component: the source is ESM executed directly by the browser, so images, fonts and styles cannot be imported. Locate them with new URL:
const bg = new URL("./assets/bg.png", import.meta.url);Relative src / href / srcset inside the preview HTML are resolved by the platform against the component directory, so plain relative paths are enough.
Dependency declaration
Third-party dependencies do not need to be written into comp.json. The platform scans the import statements in your source, extracts them automatically, then resolves and pre-compiles them from your local project's node_modules.
Therefore: every package the component uses must already be installed locally.
npm install echartsThe scan result appears under "Component Dependencies" on the upload page, so you can review it before publishing.
demo and previews
demo/index.vue: the mini preview shown on list cards.demo/full.vue: the full-screen preview on the detail page; recommended.
A Web Component preview is plain HTML:
<!-- demo/mini.html -->
<my-element text="Hello"></my-element>
<script type="module" src="../index.js"></script>Requirements:
- Contain at least one
<script type="module">. - The module script must be inside
<body>; one placed in<head>is ignored. - The script's
srcresolves relative to the HTML file itself.
Automatic scaling of the mini preview
The platform automatically measures the fixed width and height of the mini demo and fits it into the panel with contain (proportional, fully visible, centred). The demo code needs no scaling logic at all.
You only need to fix the content to its design size:
<template>
<div class="mini-content">Content designed at 320 × 240</div>
</template>
<style scoped>
.mini-content {
width: 320px;
height: 240px;
overflow: hidden;
}
</style>Do not write width: 100%
A root element that fills its container makes the platform measure the "natural size", so the scale factor drifts with the content. Fix the design width and height instead.
What main.js is for
main.js runs only in the preview environment, so it is the place for global side effects:
Vue 2: register a UI library
import Vue from "vue";
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
Vue.use(Antd);Vue 3: register through the Vue.app provided by the platform
import * as Vue from "vue";
import ArcoVue from "@arco-design/web-vue";
import "@arco-design/web-vue/dist/arco.css";
Vue.app.use(ArcoVue);React: put global styles here
import "antd/dist/reset.css";Do not put global styles inside index.jsx: when a consumer imports the component entry it runs too, which pulls them in a second time.
Naming conventions
- Unique within the same space (the public platform or one team).
- Only PascalCase (
UserGrowthChart) or kebab-case (alipay-data-table). _, camelCase and names starting with a digit are not supported.- Adding a prefix to separate business domains is recommended:
company-business-domain-component-name.
Size and count limits
| Limit | Maximum |
|---|---|
| Single file | 3 MB |
| Total component size | 10 MB |
| Number of files | 30 (including subdirectories) |
When you exceed them, compress static assets first, or move large files to external links.
Minimal examples
Vue
<!-- MyButton/index.vue -->
<template>
<button class="my-button" @click="$emit('click')">{{ text }}</button>
</template>
<script>
export default {
name: "MyButton",
props: { text: { type: String, default: "Click me" } }
};
</script>
<style scoped>
.my-button {
padding: 8px 16px;
border: none;
border-radius: 4px;
background: #409eff;
color: #fff;
cursor: pointer;
}
</style>React
// MyCard/index.jsx
import { Card } from "antd";
export default function MyCard({ title = "Hello" }) {
return <Card>{title}</Card>;
}Web Component
// MyElement/index.js
class MyElement extends HTMLElement {
connectedCallback() {
this.innerHTML = `<span>${this.getAttribute("text") || "Hello"}</span>`;
}
}
customElements.define("my-element", MyElement);<!-- MyElement/demo/mini.html -->
<my-element text="Hello"></my-element>
<script type="module" src="../index.js"></script>Self-check list
- [ ] The folder name follows the naming conventions and does not clash within the current space.
- [ ] The entry file exists and, for React, has a
default export. - [ ] Assets use relative paths; Web Components use
new URL. - [ ] The dependencies in use are installed locally.
- [ ] The mini demo has a fixed design width and height.
- [ ] The Web Component preview HTML contains a
<script type="module">inside<body>. - [ ] File sizes and counts are within the limits.
Next steps
- Send the component to the platform: Upload & Publish
- Keep iterating after publishing: Update & Versioning