This Skill corresponds to @opensig/open-scripts v1.0.6(generated 2026-07), minimum dependency version ≥1.0.6. To find out in which version a specific command API was introduced/changed, check
ReleaseNote。
@opensig/open-scripts is the CLI build toolkit of the OpenDesign ecosystem, providing full-process build capabilities from SVG icon generation to component library packaging.
Installation
pnpm add -D @opensig/open-scripts
# 或
npm install -D @opensig/open-scripts
After installation, you can use the package.json in the scripts of open-scripts command.
Who needs which commands?
The 5 commands of open-scripts fall into two usage scenarios. Please choose according to your project type:
Component library development (such as @opensig/opendesign itself)
When building and publishing a component library npm package, you need to useall 5 commands:
| Command | When to use |
|---|---|
gen:icon |
After adding/modifying SVG icons, regenerate the icon Vue components |
clean:svg |
After receiving the original SVG delivered by the designer, clean it first and then hand it to gen:icon |
build:component |
Build component library artifacts (ES/CJS/UMD) before publishing |
build:style |
Compile SCSS styles into CSS artifacts before publishing |
gen:token |
After the design token JSON is updated, regenerate the theme CSS variable files (used for the build of the @opensig/opendesign-token package) |
Standard build process:gen:icon → build:component → build:style
Business project development (websites/applications using the OpenDesign component library)
Business projectsdo not need build:component、build:style and gen:token:
build:component/build:styleare specifically for building component library npm packages; business projects can directly install@opensig/opendesignand that is enoughgen:tokenis specifically for building the@opensig/opendesign-tokenpackage; business projects can directly install that package and import the CSS file for the corresponding theme (see the installation section of the opendesign-components skill)
Commands that business projects may use:
| Command | When to use |
|---|---|
gen:icon |
When the project has its own custom icons (not the component library's built-in icons), convert the SVG into Vue components for unified use |
clean:svg |
Clean the original SVG delivered by the designer (optional, depending on SVG quality) |
Command index
- gen:icon — Generate Vue icon components from SVG files (component library + business projects) · Reference documentation
- clean:svg — Clean and optimize SVG files (component library + business projects) · Reference documentation
- build:component — Build a Vue component library (component library development only) · Reference documentation
- build:style — Compile SCSS styles into CSS (component library development only) · Reference documentation
- gen:token — Generate design token CSS variables from JSON (token package building only) · Reference documentation
gen:icon
Classify the SVG icon files provided by the designer into three types by fill/stroke/color, optimize them with SVGO, and automatically convert them into Vue single-file components that can be imported and used directly.
Applicable scenarios: Both component library development and business projects can use it. In business projects, when the design draft contains custom icons that are not built into the component library, use this command for unified management.
Workflow from design mockups to code for SVG assets
When a design mockup (Pixso/Figma, etc.) contains slices that can be converted into SVG icons, follow the process below:
- Prefer obtaining via MCP: If the design tool provides MCP (Model Context Protocol) capabilities, prefer calling its MCP interface to batch export SVG assets, rather than manually exporting them one by one
- Manually export SVG: If there is no MCP capability, export the icon slices from the design mockup one by one as
.svgformat - Store by category: Determine the type based on the icon content, and place the SVG into the corresponding subdirectory (see "SVG Export Specifications and Classification Rules" below)
- Optional cleanup: If the exported SVG contains redundant attributes, first run
clean:svgcleanup - After all exports are complete, run the
gen:iconcommand once to generate the Vue components for all icons - Import and use in business code (see "How to Import Icon Components" below)
Note: You should run
gen:iconuniformly only after all SVG slices have been exported, because this command clears the output directory and regenerates all components each time it is executed.
Best Practices for Adding and Modifying Icons
When a task involvesaddingormodifyingicons, the following principles must be followed:
- Prioritize reusing existing icons: Before adding an icon, first check the SVG source file directory (the
inputsubdirectory pointed to by thefill/、stroke/、color/configuration) and the already generated icon components to confirm whether an identical or semantically similar icon already exists. If a usable icon already exists, import and use it directly; do not add it again - Adopt an incremental strategy: When new icons need to be added, onlyappendthe new SVG files to the corresponding
fill/、stroke/、color/subdirectory, anddo not delete or overwriteexisting SVG files.gen:iconreads all SVGs from theinputdirectory and regenerates the components, so you only need to ensure the new files are placed correctly - Replace in place when modifying icons: If you need to modify the visual style of an existing icon, directly replace the file with the same namewith the new SVG, keeping the file name unchanged, so that the generated component name and all referencing code do not need to be changed
How to Check Existing Icons:
- Check the file names in each subdirectory under the SVG source file directory, and determine whether the semantics match according to the naming convention
- Search the generated icon component directory (the directory pointed to by the
outputconfiguration), and look it up by component name - If the project uses built-in icons from a component library (
@opensig/opendesign), you should also check whether the required icon is already built into the component library
Anti-pattern: Do not clear the SVG source file directory and then put all files back in just to be "clean"—this will cause a large number of meaningless deletion + addition records in Git history, and it is easy to miss existing icons.
SVG Export Specifications and Classification Rules
Export Specifications:
- Icons should be exported asa square with appropriate white marginscanvas, preferably using the 24×24px size
- If an icon has special size requirements, still export the SVG at the standard size, and adjust the display size at the call site via CSS
font-sizeorwidth/height. - Remove unnecessary layers, masks, and clipping paths during export.
- Paths that need dynamic styling: If a certain
<path>needs to change color or style individually during interaction, a meaningful IDshould be set for that path in the design tool (such ashighlight、badge),gen:iconThe SVGO process will automatically convertidtoclass, so the caller can control the style of that path through a CSS class selector.
<!-- 示例:通过类名控制 SVG 内部路径的颜色 -->
<OIcon :icon="OIconNotification" class="my-icon" />
<style scoped>
/* 设计师在 SVG 中为小红点路径设置了 id="badge",生成后变为 class="badge" */
.my-icon :deep(.badge) {
fill: red;
}
</style>
Classification Rules—Determine which subdirectory to place it in based on the visual content of the icon:
| Directory | Basis for Determination | Color Control Method After Generation | Typical Scenarios |
|---|---|---|---|
fill/ |
The icon is mainlysolid filled, with color controlled by the fill attribute. |
Use CSS color to change color uniformly. |
Solid arrows, solid checkmarks, solid favorite stars. |
stroke/ |
The icon is mainlyline stroked, with color controlled by the stroke attribute. |
Use CSS color to change color uniformly. |
Wireframe close, wireframe search, wireframe settings. |
color/ |
The icon containsmultiple fixed colors, and should not have its color changed uniformly by CSS. | Preserve the original SVG colors. | Brand logos, color illustrations, multi-color status icons. |
Judgment Tips: Open the SVG in a text editor. If elements such as
<path>mainly use thefillattribute for coloring →fill/; if they mainly use thestrokeattribute for coloring →stroke/; if they use multiple different color values at the same time →color/。
SVG File Naming Conventions
The SVG file name directly determines the generated Vue component name (such as arrow-right.svg → OIconArrowRight), and should follow unified naming rules:
Naming Format:{语义名}[-{形态变体}].svg
- Semantic name: Describes the meaning of the icon, uses kebab-case (lowercase + hyphens), and consists of an "object" or an "action".
- Form variant(optional): A suffix for different visual forms of the same semantic meaning.
Semantic Name Selection Rules:
| Priority | Composition Method | Example |
|---|---|---|
| 1 | A single action or object (when the meaning is clear) | search.svg、home.svg、close.svg |
| 2 | Action + Object | file-download.svg、user-add.svg、link-copy.svg |
| 3 | Object + Qualifier | arrow-right.svg、chevron-down.svg、caret-up.svg |
Common Form Variant Suffixes:
| Suffix | Meaning | Example |
|---|---|---|
-circle |
With circular background | check-circle.svg、info-circle.svg |
-square |
With square background | plus-square.svg |
-line |
Linear stroke version | heart-line.svg |
-solid |
Solid fill version | heart-solid.svg |
Common Semantic Word Reference:
| Category | Recommended Vocabulary |
|---|---|
| Navigation | arrow-{up/down/left/right}、chevron-{方向}、caret-{方向}、expand、collapse、menu、more |
| Action | add、delete、edit、search、download、upload、save、copy、share、refresh、close、filter、sort |
| Object | file、folder、user、home、calendar、mail、image、link、bell、lock、key、settings |
| State | check、warning、error、info、loading、success、question |
| Media | play、pause、stop、mute、volume |
Naming Principles:
- Based on the icon'svisual meaning/purposeNaming, do not name by business function (
close.svginstead ofdialog-dismiss.svg) - Keep the same prefix for a group of related icons (
arrow-up、arrow-down、arrow-left、arrow-right) - Avoid redundant prefixes—the file is already in the
fill/、stroke/、color/subdirectory, so there is no need to repeat the type information in the file name
How to import icon components
The generated icon components support multiple import methods; choose the appropriate one according to the project structure:
<script setup>
// 方式 1:从组件库包导入(使用组件库内置图标)
import { OIconArrowRight, OIconClose } from '@opensig/opendesign';
// 方式 2:通过路径别名导入(业务项目自定义图标,需在 vite.config / tsconfig 中配置别名)
import { OIconCustom } from '@/icon-components';
// 方式 3:相对路径导入
import { OIconCustom } from '../icon-components';
// 方式 4:从 monorepo 的其他子包导入(通过包名引用)
import { DocIconLogo } from '@my-org/docs-icons';
</script>
Best practices:
- Built-in icons in the component libraryImport directly from
@opensig/opendesign, no need to rungen:icon - Custom icons for business projectsIt is recommended to configure a path alias (such as
@/icon-components) to avoid deep relative paths - Sharing icons across packages in a monorepoIt is recommended to generate icons into a separate subpackage and publish it, and other packages import it by package name
open-scripts gen:icon --config ./icons/icon.config.ts
Core configuration file fields:
| Field | Type | Required | Default value | Description |
|---|---|---|---|---|
input |
string |
No | './svgs' |
SVG source file directory, must contain the fill/、stroke/、color/ subdirectory |
output |
string |
No | './components/' |
Output directory for the generated Vue components |
prefix |
string |
No | '' |
Component name prefix (such as 'o-' generates OIconXxx) |
componentClass |
string |
No | 'svg-icon' |
CSS class name of the SVG root element |
renderOnServer |
boolean |
No | false |
Whether SSR is supported (when false, icons are rendered only on the client) |
Configuration example
// icon.config.ts
export default {
input: './svgs',
output: '../src/icon-components/',
componentClass: 'o-svg-icon',
prefix: 'o-',
};
SVG directory structure requirements:
svgs/
├── fill/ ← 填充型图标(移除 fill 属性,通过 CSS color 控制颜色)
│ ├── arrow-right.svg
│ └── check.svg
├── stroke/ ← 描边型图标(移除 stroke 属性,通过 CSS color 控制颜色)
│ └── close.svg
└── color/ ← 多色图标(保留原始颜色)
└── logo.svg
For detailed configuration instructions, please see references/gen-icon.md
clean:svg
Use SVGO to batch clean and optimize SVG files, remove redundant attributes, style elements, and scripts, and output streamlined SVG files. Usually used before gen:icon to preprocess the original SVGs delivered by designers.
Applicable scenarios: Can be used for both component library development and business projects. When the SVG exported by the designer contains redundant <style>、<script>, inline styles, and other redundant information, use this command to batch clean it first.
open-scripts clean:svg --config ./icons/cleansvg.config.ts
Core configuration file fields:
| Field | Type | Required | Default value | Description |
|---|---|---|---|---|
input |
string |
No | './src/icons/svgs' |
SVG source file directory |
output |
string |
No | './src/icons/output/' |
Cleaned output directory |
svgo |
Config |
No | Built-in default configuration | SVGO optimization configuration |
Configuration example
// cleansvg.config.ts
export default {
input: './svgs',
output: './_svgs',
};
For detailed configuration instructions, please see references/clean-svg.md
build:component
Use Vite to build the Vue component library and output three module formats: ES Module (es/)、CommonJS(lib/) and UMD (dist/). It also generates TypeScript type declaration files. This command does not accept a configuration file; execute it directly in the root directory of the component library package.
Applicable scenarios: Only used for component library development. Business projects can directly install the @opensig/opendesign npm package; there is no need to build the component library yourself.
open-scripts build:component
Build artifacts:
| Directory | Format | Description |
|---|---|---|
es/ |
ESM(.mjs) |
Preserves module structure and supports tree-shaking |
lib/ |
CJS(.js) |
CommonJS format, compatible with Node.js |
dist/opendesign.js |
UMD | Direct browser import |
dist/opendesign.min.js |
UMD (minified) | For production use |
dist/opendesign-icon.js |
UMD | Icons packaged separately |
dist/opendesign-icon.min.js |
UMD (minified) | Icon production bundle |
For detailed instructions, see references/build-component.md
build:style
Compile the component library's SCSS style files into CSS, generating style artifacts with multiple import methods. This command does not accept a config file and reads the hardcoded ./src directory as input.
Use case: For component library development only. Business projects import the already-compiled styles via import '@opensig/opendesign/es/index.css' and do not need to compile SCSS themselves.
open-scripts build:style
Build artifacts:
| Artifact | Description |
|---|---|
es/**/*.scss + lib/**/*.scss |
Copy of the original SCSS files |
es/**/*.css + lib/**/*.css |
Compiled CSS |
es/**/css.js + lib/**/css.js |
CSS import entry (replaces the SCSS entry) |
dist/index.css |
Full styles |
dist/index.min.css |
Full styles (minified) |
dist/theme/*/index.css |
Styles for each theme |
For detailed instructions, see references/build-style.md
gen:token
Generate multi-theme CSS variable files and VS Code snippet files from a JSON-format design token definition file. Used to convert tokens exported by designers from tools such as Pixso/Figma into CSS custom properties usable on the frontend.
Use case: Only for building the @opensig/opendesign-token token package. Business projectsdo not need torun this command—simply install @opensig/opendesign-token and import the CSS file for the corresponding theme:
pnpm add @opensig/opendesign-token
// main.ts — 以 openEuler 社区为例
import '@opensig/opendesign-token/themes/e.light.token.css'
import '@opensig/opendesign-token/themes/e.dark.token.css'
open-scripts gen:token --config ./tokens/token.config.ts
Core config file fields:
| Field | Type | Required | Default value | Description |
|---|---|---|---|---|
prefix |
string |
Yes | — | CSS variable prefix (e.g. '--o-') |
output |
string |
No | './' |
Output directory |
tokenFile |
string[] |
Yes | — | Array of token JSON file paths |
themeMap |
Array<{valueKey, name, root?}> |
Yes | — | Theme mapping (defines the CSS selector for each theme) |
codeSnippetsFile |
string |
No | — | VS Code snippet output path |
Config example
// token.config.ts
export default {
prefix: '--o-',
output: './dist',
themeMap: [
{ valueKey: 'light', name: ['o.light', 'default'] },
{ valueKey: 'dark', name: 'o.dark' },
{ valueKey: 'light', name: 'o', root: true },
],
tokenFile: ['./opendesign-token.json'],
codeSnippetsFile: './dist/opendesign.token.code-snippets',
};
For detailed configuration instructions, see references/gen-token.md
Typical build workflow
Component library release build
In the OpenDesign component library, the standard execution order before release is:
gen:icon → build:component → build:style
Corresponding package.json configuration:
{
"scripts": {
"gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts",
"clean:svg": "open-scripts clean:svg --config ./icons/cleansvg.config.ts",
"build:component": "open-scripts build:component",
"build:style": "open-scripts build:style",
"gen:token": "open-scripts gen:token --config ./tokens/token.config.ts",
"build": "pnpm gen:icon && pnpm build:component && pnpm build:style"
}
}
Business project usage
Business projects only need to configure the commands they use:
{
"scripts": {
"gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts"
}
}
Command dependencies
| Command | Prerequisite | Description |
|---|---|---|
clean:svg |
None | Can be executed independently, used to preprocess SVG |
gen:icon |
clean:svg(optional) |
It is recommended to clean up the SVG first, but not mandatory |
build:component |
gen:icon |
Icon components must be generated first before they can be packaged together |
build:style |
None | Independent of build:component , but usually executed after it |
gen:token |
None | Executed independently, does not depend on other commands |
Git ignore rules for build artifacts
The output directories of all commands are automatically generated artifacts and should not be included in version control. Please add the corresponding rules in the project's .gitignore . Before executing any command, first check whether .gitignore already covers that command's output directory; if not, add it immediately.
Recommended .gitignore configuration:
# open-scripts 构建产物(自动生成,勿提交)
# gen:icon 生成的图标组件
icon-components
# clean:svg 清理后的 SVG 输出
_svgs
# build:component 构建产物
es
lib
dist
# gen:token 生成的令牌 CSS(若 output 为 dist 则已被上方覆盖)
Note: if a command's
outputis configured with a custom path, make sure that path is also.gitignorecovered.
First use: automatically create missing files and directories
When a command requires a configuration file or input directory but the corresponding file/directory does not exist, it should be created automatically according to the following best practices:
gen:icon
If the configuration file and input directory are missing, create the following structure:
icons/
├── icon.config.ts ← 配置文件
└── svgs/ ← input 目录
├── fill/ ← 存放单色填充图标
├── stroke/ ← 存放单色描边图标
└── color/ ← 存放多色图标
Configuration file template:
// icons/icon.config.ts
export default {
input: './svgs',
output: '../src/icon-components/',
componentClass: 'o-svg-icon',
prefix: 'o-',
};
Also in package.json add:
{
"scripts": {
"gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts"
}
}
and make sure .gitignore contains icon-components。
clean:svg
If the configuration file and input directory are missing, create the following structure:
icons/
├── cleansvg.config.ts ← 配置文件
└── svgs/ ← input 目录(可与 gen:icon 共用)
Configuration file template:
// icons/cleansvg.config.ts
export default {
input: './svgs',
output: './_svgs',
};
Also in package.json add:
{
"scripts": {
"clean:svg": "open-scripts clean:svg --config ./icons/cleansvg.config.ts"
}
}
and make sure .gitignore contains _svgs。
gen:token
If the configuration file and token JSON file are missing, create the following structure:
tokens/
├── token.config.ts ← 配置文件
└── opendesign-token.json ← 令牌 JSON 数据(从设计工具导出)
Configuration file template:
// tokens/token.config.ts
export default {
prefix: '--o-',
output: './dist',
themeMap: [
{ valueKey: 'light', name: ['o.light', 'default'] },
{ valueKey: 'dark', name: 'o.dark' },
],
tokenFile: ['./opendesign-token.json'],
};
Also in package.json add:
{
"scripts": {
"gen:token": "open-scripts gen:token --config ./tokens/token.config.ts"
}
}
build:component / build:style
These two commands do not require a configuration file, but they require the project to have a specific source directory structure. If the structure is missing, it means the project has not yet completed the component library source setup and empty directories should not be created directly—the component development should be completed first before using these two commands.
Path planning in monorepo projects
In a monorepo project, each command's configuration file, input directory, and output directory should be placed inthe corresponding subpackage, and paths are resolved relative to the directory containing the configuration file. The following is the recommended directory structure (using opendesign-components as a reference):
Component library package (e.g. packages/opendesign/)
packages/opendesign/
├── package.json ← scripts 定义在此
├── icons/
│ ├── icon.config.ts ← gen:icon 配置
│ ├── cleansvg.config.ts ← clean:svg 配置
│ └── svgs/ ← SVG 源文件(提交到 git)
│ ├── fill/
│ ├── stroke/
│ └── color/
├── src/
│ ├── index.ts ← 组件主入口
│ ├── icon/
│ │ └── index.ts ← 图标入口
│ ├── icon-components/ ← gen:icon 输出(git 忽略)
│ └── {component}/
│ └── style/
│ └── index.scss
├── es/ ← build:component 输出(git 忽略)
├── lib/ ← build:component 输出(git 忽略)
└── dist/ ← build:component UMD 输出(git 忽略)
corresponds to package.json scripts:
{
"scripts": {
"gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts",
"clean:svg": "open-scripts clean:svg --config ./icons/cleansvg.config.ts",
"build:component": "open-scripts build:component",
"build:style": "open-scripts build:style",
"build": "pnpm gen:icon && pnpm build:component && pnpm build:style"
}
}
in icon.config.ts, output: '../src/icon-components/' means relative to the icons/ directory, go up one level to the package root directory and then enter src/icon-components/。
Business application package (e.g. packages/docs/)
packages/docs/
├── package.json
├── icons/
│ ├── icon.config.ts ← gen:icon 配置
│ └── svgs/
│ ├── fill/
│ ├── stroke/
│ └── color/
└── src/
└── icon-components/ ← gen:icon 输出(git 忽略)
Business application packages usually only use gen:icon,prefix should use a prefix different from the component library (e.g. 'doc-') to avoid naming conflicts:
// packages/docs/icons/icon.config.ts
export default {
input: './svgs',
output: '../src/icon-components/',
componentClass: 'o-svg-icon',
prefix: 'doc-', // 使用不同前缀,避免与组件库图标冲突
};
Key principles
- Place configuration files inside subpackages: each subpackage has its own configuration, pointed to via the
--configparameter - input paths are relative to the configuration file:
input: './svgs'means thesvgs/directory at the same level as the configuration file - output paths are relative to the configuration file:
output: '../src/icon-components/'means a relative path starting from the configuration file's location - Commit SVG source files to git:
inputdirectory (svgs/) contains the original SVG assets delivered by designers and should be included in version control - Generated artifacts are not committed:
outputdirectory and build artifact directory should all be covered by.gitignorecovered - Each subpackage uses a different prefix: when multiple packages in a monorepo use
gen:icon, differentprefixshould be set (e.g.'o-'、'doc-') to prevent component name conflicts