Token导航 LogoToken导航

Agent Skill · 研究检索

formily-migration-guide(正式迁移指南)

formily-migration-guide 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

formily-migration-guide 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为只读;许可证为 MIT,暂无第三方扫描结果,按安装量在研究检索类的 73,675 个 Skill 里排第 15,687。

总安装 7,663周安装 306GitHub Stars 公开资料未说明下载 2,097核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:formily-migration-guide(正式迁移指南)
来源仓库:https://github.com/whinc/my-claude-plugins
仓库路径:skills/formily-migration-guide
安装命令:
npx skills add whinc/my-claude-plugins --skill "formily-migration-guide"
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

AgentSkills.tonpx skills
npx skills add whinc/my-claude-plugins --skill "formily-migration-guide"

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

formily-migration-guide 提供从传统表单方案迁移至 Formily 的路径指引。适用于已有项目改造或技术栈升级时的平滑过渡支持。包含组件替换策略、状态迁移方法与兼容性处理建议。使用前需评估项目规模与依赖复杂度,分阶段实施降低风险。建议先在测试环境验证关键路径,确保数据流与 UI 表现一致。

来源仓库内路径:skills/formily-migration-guide

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add whinc/my-claude-plugins --skill "formily-migration-guide";命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它标注为只读,先用只读任务试一次,确认行为符合预期再扩大使用范围。

常见问题

6 条

formily-migration-guide 怎么安装?

在终端执行 npx skills add whinc/my-claude-plugins --skill "formily-migration-guide"。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

formily-migration-guide 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

formily-migration-guide 需要什么权限?

权限级别是只读。该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

formily-migration-guide 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

formily-migration-guide 用的人多吗?

公开数据是累计安装 7,663 次,近一周安装 306 次,下载 2,097 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

formily-migration-guide 安全吗?

没有查到第三方扫描结果,安全性无法从公开资料判断,安装前请自行审查源码、依赖和命令行为。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 标注为只读权限,试用阶段不容易误改本地文件。

先想清楚的地方

  • 没有第三方扫描结果,安全性只能靠自己读源码判断。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 只想先试试效果、不希望它改动本地文件的人。

不太适合

  • 要求有安全扫描结论才肯安装的团队。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
formily-migration-guide

正式迁移指南 · 本页

7,663—只读MIT未收录

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Formily Migration Guide

This skill provides comprehensive guidance for converting existing React forms to Formily. Focus on migration strategies, common patterns, and step-by-step conversion processes for different form libraries and vanilla React forms with TypeScript.

Migration Overview

Why Migrate to Formily?

  1. Better TypeScript support - Type-safe form management
  2. Schema-driven approach - Declarative form definitions
  3. Improved performance - Efficient reactivity and minimal re-renders
  4. Powerful validation - Built-in validation with custom rules
  5. Better developer experience - Less boilerplate, more maintainability

Migration Strategies

  1. Incremental migration - Convert forms one at a time
  2. Parallel development - Build new forms with Formily while maintaining existing ones
  3. Complete rewrite - Replace entire form system at once

From Vanilla React Forms

Before: Vanilla React Form

import React, { useState, FormEvent } from 'react'

interface ContactForm {
  name: string
  email: string
  message: string
}

const VanillaContactForm: React.FC = () => {
  const [formData, setFormData] = useState<ContactForm>({
    name: '',
    email: '',
    message: ''
  })

  const [errors, setErrors] = useState<Partial<ContactForm>>({})
  const [isSubmitting, setIsSubmitting] = useState(false)

  const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value } = e.target
    setFormData(prev => ({ ...prev, [name]: value }))
    // Clear error when user starts typing
    if (errors[name as keyof ContactForm]) {
      setErrors(prev => ({ ...prev, [name]: '' }))
    }
  }

  const validateForm = (): boolean => {
    const newErrors: Partial<ContactForm> = {}

    if (!formData.name.trim()) {
      newErrors.name = 'Name is required'
    }

    if (!formData.email.trim()) {
      newErrors.email = 'Email is required'
    } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
      newErrors.email = 'Invalid email format'
    }

    if (!formData.message.trim()) {
      newErrors.message = 'Message is required'
    }

    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault()

    if (!validateForm()) {
      return
    }

    setIsSubmitting(true)

    try {
      // Submit form data
      await submitForm(formData)
      alert('Form submitted successfully!')
      setFormData({ name: '', email: '', message: '' })
    } catch (error) {
      console.error('Submission error:', error)
      alert('Submission failed. Please try again.')
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Name:</label>
        <input
          type="text"
          name="name"
          value={formData.name}
          onChange={handleChange}
        />
        {errors.name && <span className="error">{errors.name}</span>}
      </div>

      <div>
        <label>Email:</label>
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
        />
        {errors.email && <span className="error">{errors.email}</span>}
      </div>

      <div>
        <label>Message:</label>
        <textarea
          name="message"
          value={formData.message}
          onChange={handleChange}
        />
        {errors.message && <span className="error">{errors.message}</span>}
      </div>

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? 'Submitting...' : 'Submit'}
      </button>
    </form>
  )
}

After: Formily Version

import React from 'react'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
import { Form, FormItem, Input, Button } from '@formily/antd'

interface ContactForm {
  name: string
  email: string
  message: string
}

const FormilyContactForm: React.FC = () => {
  const form = createForm<ContactForm>({
    initialValues: {
      name: '',
      email: '',
      message: ''
    },
    validateFirst: true
  })

  const schema = {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        title: 'Name',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input',
        'x-validator': [
          { required: true, message: 'Name is required' }
        ]
      },
      email: {
        type: 'string',
        title: 'Email',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input',
        'x-validator': [
          { required: true, message: 'Email is required' },
          { format: 'email', message: 'Invalid email format' }
        ]
      },
      message: {
        type: 'string',
        title: 'Message',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input.TextArea',
        'x-validator': [
          { required: true, message: 'Message is required' }
        ]
      }
    }
  }

  const SchemaField = createSchemaField({
    components: {
      Form,
      FormItem,
      Input,
      Button
    }
  })

  const handleSubmit = async () => {
    try {
      await form.validate()
      const values = form.values
      await submitForm(values)
      alert('Form submitted successfully!')
      form.reset()
    } catch (error) {
      console.error('Validation errors:', error)
    }
  }

  return (
    <FormProvider form={form}>
      <Form labelCol={6} wrapperCol={16}>
        <SchemaField schema={schema} />
        <FormItem wrapperCol={{ offset: 6, span: 16 }}>
          <Button type="primary" onClick={handleSubmit}>
            Submit
          </Button>
        </FormItem>
      </Form>
    </FormProvider>
  )
}

From Formik

Before: Formik Form

import React from 'react'
import { Formik, Form, Field, ErrorMessage } from 'formik'
import * as Yup from 'yup'

const FormikExample: React.FC = () => {
  const initialValues = {
    firstName: '',
    lastName: '',
    email: '',
    age: ''
  }

  const validationSchema = Yup.object({
    firstName: Yup.string().required('First name is required'),
    lastName: Yup.string().required('Last name is required'),
    email: Yup.string().email('Invalid email').required('Email is required'),
    age: Yup.number().min(18, 'Must be at least 18').required('Age is required')
  })

  const handleSubmit = (values: any, { setSubmitting }: any) => {
    submitForm(values)
    setSubmitting(false)
  }

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      {({ isSubmitting }) => (
        <Form>
          <div>
            <label>First Name</label>
            <Field name="firstName" type="text" />
            <ErrorMessage name="firstName" component="div" />
          </div>

          <div>
            <label>Last Name</label>
            <Field name="lastName" type="text" />
            <ErrorMessage name="lastName" component="div" />
          </div>

          <div>
            <label>Email</label>
            <Field name="email" type="email" />
            <ErrorMessage name="email" component="div" />
          </div>

          <div>
            <label>Age</label>
            <Field name="age" type="number" />
            <ErrorMessage name="age" component="div" />
          </div>

          <button type="submit" disabled={isSubmitting}>
            Submit
          </button>
        </Form>
      )}
    </Formik>
  )
}

After: Formily Version

import React from 'react'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
import { Form, FormItem, Input, InputNumber, Button } from '@formily/antd'

const FormilyFormikExample: React.FC = () => {
  const form = createForm({
    initialValues: {
      firstName: '',
      lastName: '',
      email: '',
      age: undefined
    }
  })

  const schema = {
    type: 'object',
    properties: {
      firstName: {
        type: 'string',
        title: 'First Name',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input',
        'x-validator': [{ required: true, message: 'First name is required' }]
      },
      lastName: {
        type: 'string',
        title: 'Last Name',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input',
        'x-validator': [{ required: true, message: 'Last name is required' }]
      },
      email: {
        type: 'string',
        title: 'Email',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input',
        'x-validator': [
          { required: true, message: 'Email is required' },
          { format: 'email', message: 'Invalid email format' }
        ]
      },
      age: {
        type: 'number',
        title: 'Age',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'InputNumber',
        'x-validator': [
          { required: true, message: 'Age is required' },
          { minimum: 18, message: 'Must be at least 18' }
        ]
      }
    }
  }

  const SchemaField = createSchemaField({
    components: {
      Form,
      FormItem,
      Input,
      InputNumber,
      Button
    }
  })

  const handleSubmit = async () => {
    try {
      await form.validate()
      const values = form.values
      await submitForm(values)
      form.reset()
    } catch (error) {
      console.error('Validation errors:', error)
    }
  }

  return (
    <FormProvider form={form}>
      <Form labelCol={6} wrapperCol={16}>
        <SchemaField schema={schema} />
        <FormItem wrapperCol={{ offset: 6, span: 16 }}>
          <Button type="primary" onClick={handleSubmit}>
            Submit
          </Button>
        </FormItem>
      </Form>
    </FormProvider>
  )
}

From React Hook Form

Before: React Hook Form

import React from 'react'
import { useForm, SubmitHandler } from 'react-hook-form'
import { yupResolver } from '@hookform/resolvers/yup'
import * as Yup from 'yup'

interface FormData {
  username: string
  email: string
  password: string
  confirmPassword: string
}

const schema = Yup.object({
  username: Yup.string().required('Username is required'),
  email: Yup.string().email('Invalid email').required('Email is required'),
  password: Yup.string().min(8, 'Password must be at least 8 characters').required('Password is required'),
  confirmPassword: Yup.string().oneOf([Yup.ref('password')], 'Passwords must match').required('Confirm password is required')
})

const ReactHookFormExample: React.FC = () => {
  const { register, handleSubmit, formState: { errors }, watch } = useForm<FormData>({
    resolver: yupResolver(schema)
  })

  const watchedPassword = watch('password')

  const onSubmit: SubmitHandler<FormData> = (data) => {
    console.log(data)
    // Submit logic
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>Username</label>
        <input {...register('username')} />
        {errors.username && <span>{errors.username.message}</span>}
      </div>

      <div>
        <label>Email</label>
        <input type="email" {...register('email')} />
        {errors.email && <span>{errors.email.message}</span>}
      </div>

      <div>
        <label>Password</label>
        <input type="password" {...register('password')} />
        {errors.password && <span>{errors.password.message}</span>}
      </div>

      <div>
        <label>Confirm Password</label>
        <input type="password" {...register('confirmPassword')} />
        {errors.confirmPassword && <span>{errors.confirmPassword.message}</span>}
      </div>

      <button type="submit">Submit</button>
    </form>
  )
}

After: Formily Version

import React from 'react'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
import { Form, FormItem, Input, Button } from '@formily/antd'

interface FormData {
  username: string
  email: string
  password: string
  confirmPassword: string
}

const FormilyReactHookFormExample: React.FC = () => {
  const form = createForm<FormData>({
    initialValues: {
      username: '',
      email: '',
      password: '',
      confirmPassword: ''
    },
    effects() {
      // Custom validation for password match
      onFieldChange('confirmPassword', ['value'], (field) => {
        const password = form.values.password
        const confirmPassword = field.value

        if (confirmPassword && password !== confirmPassword) {
          field.errors = ['Passwords must match']
        } else {
          field.errors = []
        }
      })
    }
  })

  const schema = {
    type: 'object',
    properties: {
      username: {
        type: 'string',
        title: 'Username',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input',
        'x-validator': [{ required: true, message: 'Username is required' }]
      },
      email: {
        type: 'string',
        title: 'Email',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input',
        'x-validator': [
          { required: true, message: 'Email is required' },
          { format: 'email', message: 'Invalid email format' }
        ]
      },
      password: {
        type: 'string',
        title: 'Password',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input.Password',
        'x-validator': [
          { required: true, message: 'Password is required' },
          { min: 8, message: 'Password must be at least 8 characters' }
        ]
      },
      confirmPassword: {
        type: 'string',
        title: 'Confirm Password',
        required: true,
        'x-decorator': 'FormItem',
        'x-component': 'Input.Password',
        'x-validator': [{ required: true, message: 'Please confirm your password' }]
      }
    }
  }

  const SchemaField = createSchemaField({
    components: {
      Form,
      FormItem,
      Input,
      Button
    }
  })

  const handleSubmit = async () => {
    try {
      await form.validate()
      const values = form.values
      console.log(values)
      // Submit logic
      form.reset()
    } catch (error) {
      console.error('Validation errors:', error)
    }
  }

  return (
    <FormProvider form={form}>
      <Form labelCol={6} wrapperCol={16}>
        <SchemaField schema={schema} />
        <FormItem wrapperCol={{ offset: 6, span: 16 }}>
          <Button type="primary" onClick={handleSubmit}>
            Submit
          </Button>
        </FormItem>
      </Form>
    </FormProvider>
  )
}

Migration Checklist

Pre-Migration Preparation

  1. Analyze existing forms

- Count total forms to migrate - Identify form complexity levels - Document validation logic - Note custom components used

  1. Set up Formily

- Install Formily packages - Configure TypeScript types - Set up Ant Design integration - Create basic form components

  1. Plan migration strategy

- Choose incremental vs complete rewrite - Define migration timeline - Assign team responsibilities - Set up testing strategy

Migration Steps

  1. Convert form structure

- Replace useState with createForm - Convert field definitions to schema - Update validation logic - Replace onChange handlers

  1. Update validation

- Convert Yup schemas to Formily validators - Implement custom validation rules - Set up async validation - Configure error messages

  1. Migrate components

- Replace Formik/React Hook Form components - Update Ant Design integration - Convert custom field components - Update form submission logic

  1. Test migration

- Unit test individual forms - Integration test form workflows - Test validation scenarios - Performance test large forms

Post-Migration

  1. Validation

- All forms render correctly - Validation works as expected - Form submission functions properly - TypeScript types are correct

  1. Optimization

- Remove unused dependencies - Optimize form performance - Update documentation - Train team on Formily

Common Migration Patterns

State Management Migration

// Before: Multiple useState hooks
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [errors, setErrors] = useState({})

// After: Single form instance
const form = createForm({
  initialValues: { name: '', email: '' }
})

Validation Migration

// Before: Manual validation
const validateForm = () => {
  const errors = {}
  if (!name) errors.name = 'Name is required'
  if (!email) errors.email = 'Email is required'
  setErrors(errors)
}

// After: Schema-based validation
const schema = {
  type: 'object',
  properties: {
    name: { type: 'string', required: true },
    email: { type: 'string', required: true, format: 'email' }
  }
}

Form Submission Migration

// Before: Manual submission handling
const handleSubmit = (e) => {
  e.preventDefault()
  if (validateForm()) {
    submitForm({ name, email })
  }
}

// After: Formily submission
const handleSubmit = async () => {
  await form.validate()
  submitForm(form.values)
}

Additional Resources

Templates

  • templates/migration-template.tsx - Reusable migration template
  • templates/validation-converter.ts - Validation logic converter utility

Reference Files

  • references/migration-comparison.md - Side-by-side comparison table
  • references/common-pitfalls.md - Migration pitfalls and solutions
  • references/validation-mapping.md - Validation rule mapping guide

Migration Tools

  • Use automated code migration scripts for simple forms
  • Create custom transformation utilities for complex forms
  • Implement gradual migration wrappers for mixed environments

Best Practices

  1. Start simple - Migrate basic forms first to learn the pattern
  2. Maintain type safety - Convert all forms to TypeScript
  3. Test thoroughly - Validate each migrated form matches original behavior
  4. Document changes - Keep track of migration decisions and patterns
  5. Iterate gradually - Improve forms after initial migration
  6. Monitor performance - Watch for performance issues in complex forms
  7. Train the team - Ensure all developers understand Formily patterns
  8. Plan for rollbacks - Keep original forms as backup during migration

平台分布

Claude Code

28.92%
按下载量换算606

windsurf

21.78%
按下载量换算457

trae

18.01%
按下载量换算378

OpenCode

14.25%
按下载量换算299

Codex

7.7%
按下载量换算161

Antigravity

3.82%
按下载量换算80

安全审计

暂无安全审计结果可展示。

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills