Skip to content

v2.7 升级指南

本文档为 v2.7 版本的升级指南,主要介绍了 v2.7 版本的主要新特性、升级步骤和注意事项。

升级前请先阅读 v2.7 更新日志,了解 v2.7 版本的变更内容。

主要变更内容

1. 注册表声明方式变更

v2.7 版本对注册表的声明方式进行了重大调整,采用了基于唯一 ID 的新注册方式,使配置更加灵活和精确。

旧版注册表方式

javascript
// 旧版注册表配置示例
const register = {
  root: {
    id: 'engine.root',
    metas: [GenerateCodeService, GlobalService]
  },
  config: engineConfig,
  layout: {
    ...Layout
    options: {...}
  },
  themes: [
    {
      id: 'engine.theme.light'
    },
    {
      id: 'engine.theme.dark'
    }
  ],
  toolbars: [Media, Save],
  plugins: [Materials, Tree],
  settings: [Props, Styles],
  Canvas: Canvas
}

新版注册表方式

javascript
import { META_APP } from '@opentiny/tiny-engine'
// 新版注册表配置示例
const register = {
  'engine.root': {
    id: 'engine.root',
    metas: [GenerateCodeService, GlobalService]
  },
  'engine.config': engineConfig,
  // 覆盖官方的配置
  [META_APP.Layout]: {
    options: {...}
  },
  // 配置 false 隐藏工具栏清空按钮,并且在构建的时候,会将工具栏插件的相关代码做 tree-shaking
  [META_APP.Clean]: false,
  // 替换整个页面JS插件,手动配置 tree-shaking 为 true,会将原来的页面JS插件的代码做 tree-shaking
  /* #__TINY_ENGINE_TREE_SHAKING__: true */
  [META_APP.Script]: scriptPlugin,
  // 新增的插件,需要使用与官方插件不相同的唯一 id
  'engine.plugins.customPlugin': {
    ...customPlugin,
    id: 'engine.plugins.customPlugin'
  }
}

升级步骤

  1. 将注册表配置从旧的分类式结构(toolbars, plugins, settings等)调整为基于唯一 ID 的扁平结构
  2. 对于已存在的官方组件,使用其唯一 ID 作为对象的键
  3. 移除不需要的插件时,将其值设置为 false
  4. 添加新插件时,确保使用与官方插件不同的唯一 ID

重要提示⚠️:v2.7 开始,如果对原插件没有改动(配置、替换、删除),则不需要在注册表中进行声明,因为官方内置了全量的注册表。

详细内容请参考 新注册表

API 变更

@opentiny/tiny-engine-meta-register 包 API 变化

v2.7 版本对 @opentiny/tiny-engine-meta-register 包的 API 进行了重大重构,以下是主要变化:

移除的 API

1. getMergeRegistry 函数

变更说明getMergeRegistry 函数已被完全移除,不再提供此 API。

旧版用法

javascript
import { getMergeRegistry } from '@opentiny/tiny-engine'

// 根据类型和 ID 获取合并后的注册表项
const plugin = getMergeRegistry('plugins', 'engine.plugins.materials')
const allPlugins = getMergeRegistry('plugins')

新版替代方案

javascript
import { getMergeMeta, getMergeMetaByType, getAllMergeMeta } from '@opentiny/tiny-engine'

// 根据 ID 获取特定的注册表项
const plugin = getMergeMeta('engine.plugins.materials')

// 根据类型获取所有注册表项
const allPlugins = getMergeMetaByType('plugins')

// 获取所有注册表项
const allMetas = getAllMergeMeta()
2. getLayoutComponent 函数

变更说明getLayoutComponent 函数已被移除,不再单独提供布局组件获取功能。

旧版用法

javascript
import { getLayoutComponent } from '@opentiny/tiny-engine-meta-register'

const layoutComponent = getLayoutComponent({ id: 'engine.layout.header' })

新版替代方案: 布局组件现在通过新的注册表机制进行管理,应使用 getMergeMeta 获取:

javascript
import { getMergeMeta } from '@opentiny/tiny-engine'

const layoutMeta = getMergeMeta('engine.layout')

新增的 API

1. getMergeMetaByType 函数

功能说明:根据类型获取所有匹配的注册表项。

javascript
import { getMergeMetaByType } from '@opentiny/tiny-engine'

// 获取所有插件类型的注册表项
const plugins = getMergeMetaByType('plugins')
2. getAllMergeMeta 函数

功能说明:获取所有的注册表项。

javascript
import { getAllMergeMeta } from '@opentiny/tiny-engine'

// 获取完整的注册表
const allMetas = getAllMergeMeta()
3. initHotfixRegistry 函数

功能说明:初始化热修复注册表,支持远程动态加载注册表配置。

javascript
import { initHotfixRegistry } from '@opentiny/tiny-engine-meta-register'

// 从远程 URL 加载热修复注册表
await initHotfixRegistry({
  url: 'https://example.com/hotfix-registry.js'
})

升级指导

  1. 替换 getMergeRegistry 调用

    • getMergeRegistry(type, id) 替换为 getMergeMeta(id)
    • getMergeRegistry(type) 替换为 getMergeMetaByType(type)
  2. 移除 getLayoutComponent 调用

    • 使用 getMergeMeta() 获取布局相关的注册表项
    • 通过新的布局配置机制管理布局组件
  3. 利用新增 API

    • 使用 getAllMergeMeta() 获取完整注册表信息,便于调试和开发
    • 使用 initHotfixRegistry() 实现热修复功能

详细API请参考 注册表 API

Vite 配置要求

registryPath 配置

重要说明⚠️:v2.7 版本开始,为了使注册表的 tree-shaking 功能正常工作,您需要在 vite.config.js 中配置 registryPath 参数。

javascript
// vite.config.js
import { defineConfig, mergeConfig } from 'vite'
import { useTinyEngineBaseConfig } from '@opentiny/tiny-engine-vite-config'

export default defineConfig((configEnv) => {
  const baseConfig = useTinyEngineBaseConfig({
    viteConfigEnv: configEnv,
    root: __dirname,
    // 其他配置...
    registryPath: './registry.js'  // 必须配置,指向注册表文件路径
  })
  
  // 其他配置...
  return mergeConfig(baseConfig, customConfig)
})

这个配置主要用于:

  • 支持插件的 tree-shaking 优化
  • 识别被设置为 false 的插件并在构建时移除相关代码
  • 解析注册表中的特殊注释指令

2. 布局(layout)变更

v2.7 版本对布局配置进行了优化,使布局更加灵活可配置。

布局配置变更

新版布局配置提供了两种配置方式:

  • layoutConfig:完整布局配置,自定义整个布局结构
  • relativeLayoutConfig:局部调整插件顺序,适用于仅调整部分插件位置
javascript
// 布局配置示例
export default {
  'engine.layout': {
    options: {
      // 完整布局配置(二选一)
      layoutConfig: {
        plugins: {
          left: {
            top: [/* 左侧顶部插件列表 */],
            bottom: [/* 左侧底部插件列表 */]
          },
          right: {
            top: [/* 右侧顶部插件列表 */]
          }
        },
        toolbars: {
          left: [/* 左侧工具栏 */],
          center: [/* 中间工具栏 */],
          right: [/* 右侧工具栏(二维数组支持分组) */],
          collapse: [/* 折叠菜单(二维数组支持分组) */]
        }
      },
      
      // 局部调整插件顺序(二选一)
      relativeLayoutConfig: {
        // 插件相对位置配置
        'engine.plugins.customPlugin': {
          insertBefore: 'engine.plugins.materials'  // 显示在物料面板前面
        },
        'engine.plugins.anotherPlugin': {
          insertAfter: 'engine.plugins.i18n'  // 显示在国际化插件后面
        }
      }
    }
  }
}

注意⚠️:当同时配置 layoutConfigrelativeLayoutConfig 时,layoutConfig 优先级更高,relativeLayoutConfig 将被忽略。

详细内容请参考 布局配置

3. 插件配置变更

3.1 插件 align 配置的废弃

在 v2.7 版本中,插件的 align 配置属性已被废弃,不再作为定位插件位置的方式。新版本中应使用 layoutConfigrelativeLayoutConfig 来定位插件。

旧版写法:

javascript
// 不再支持的写法
const plugin = {
  id: 'engine.plugins.customPlugin',
  align: 'leftTop'  // 已废弃
  // 其他配置...
}

新版写法:

javascript
// 新写法 - 使用 layoutConfig 定位插件
const register = {
  'engine.layout': {
    options: {
      layoutConfig: {
        plugins: {
          left: {
            top: ['engine.plugins.customPlugin', /* 其他插件... */]
          }
        }
      }
    }
  }
}

// 或使用 relativeLayoutConfig
const register = {
  'engine.layout': {
    options: {
      relativeLayoutConfig: {
        'engine.plugins.customPlugin': {
          insertBefore: 'engine.plugins.materials'
        }
      }
    }
  }
}

3.2 插件 type: setting 配置的废弃

在 v2.7 版本中,右侧设置面板插件不再使用 type: 'setting' 来标识,而是统一使用插件 ID 来区分。

旧版写法:

javascript
// 不再支持的写法
export default {
  id: 'engine.setting.props',
  title: '属性',
  type: 'settings',  // 已废弃
  name: 'props',
  icon: 'form'
}

新版写法:

javascript
// 新写法
export default {
  id: 'engine.setting.props',
  title: '属性',
  type: 'plugins',  // 统一使用 plugins 类型
  name: 'props',
  icon: 'form'
}

右侧设置面板的插件现在也通过布局配置的 layoutConfigrelativeLayoutConfig 进行定位:

javascript
const register = {
  'engine.layout': {
    options: {
      layoutConfig: {
        plugins: {
          right: {
            top: ['engine.setting.props', 'engine.setting.styles', 'engine.setting.event']
          }
        }
      }
    }
  }
}

3.3 仅支持在第一层声明(子层声明不会生效)

自 v2.7 起,我们只读取注册表对象的“第一层”。只有第一层的键会被注册进 metaHashMap

也就是说:把插件/配置项写在子层(无论是把唯一 ID 放到某个插件的子属性里,还是通过 metas 往里塞)都不会被注册,getMergeMeta/getMergeMetaByType/getAllMergeMeta 也就找不到它们。

简而言之:请把所有需要生效的插件/配置项,都放到注册表的第一层来声明。

错误示例(不会生效):

javascript
import { META_APP } from '@opentiny/tiny-engine'
import testMeta from './testMeta'

export default {
  // 1) 在子层直接再次声明插件/配置项(无效,不会注册到 metaHashMap)
  [META_APP.Materials]: {
    'engine.plugins.test': testMeta
  },

  // 2) 通过 metas 在子层注入(无效,不会注册到 metaHashMap)
  [META_APP.Materials]: {
    options: {
      displayComponentIds: ['engine.plugins.test'],
      metas: [testMeta]
    }
  }
}

正确示例(第一层声明 + 通过 ID 引用):

javascript
import { META_APP } from '@opentiny/tiny-engine'
import testMeta from './testMeta' // testMeta.id = 'engine.plugins.test'

export default {
  // 作为第一层键单独注册
  [testMeta.id]: testMeta,

  // 在需要的插件或布局中通过 ID 引用
  [META_APP.Materials]: {
    options: {
      displayComponentIds: ['engine.plugins.test']
    }
  }
}

适用范围:所有插件与配置项都遵循该规则。用户注册表只支持:

  • 把已有的插件/配置项设为 false(删除默认);
  • 在第一层新增插件/配置项;
  • 在第一层用相同 ID 覆盖默认配置。
物料插件(Materials 插件)迁移建议

如果你旧版本是在 Materials 插件内部(例如 Materials.metas 或把自定义 ID 放到 Materials 的子属性里)扩展物料插件,请按下面方式迁移:

错误示例(不会生效):

javascript
import { META_APP } from '@opentiny/tiny-engine'
import MyMaterial from './MyMaterial' // MyMaterial.id = 'engine.plugins.myMaterial'

export default {
  [META_APP.Materials]: {
    // 通过 metas 向物料插件塞入物料项(无效)
    options: {
      metas: [MyMaterial]
    }
  }
}

正确示例(第一层声明 + 在物料插件中引用):

javascript
import { META_APP } from '@opentiny/tiny-engine'
import MyMaterial from './MyMaterial' // MyMaterial.id = 'engine.plugins.myMaterial'

export default {
  // 1) 物料项作为第一层键单独注册
  [MyMaterial.id]: MyMaterial,

  // 2) 在 Materials 插件中通过 ID Tab 组件显示
  [META_APP.Materials]: {
    options: {
      displayComponentIds: ['engine.plugins.myMaterial']
    }
  }
}

4. 注册表热修复功能

v2.7 版本新增了注册表热修复(hotfix)功能,可以通过覆盖官方插件的特定函数或模板,实现紧急 bug 修复,而不需要等待官方版本发布。

javascript
// hotfix 注册表示例
export default {
  'engine.plugins.i18n': {
    overwrite: {
      lifeCycles: {
        'Main': {
          onMounted: [
            (ctx) => () => {
              // 覆盖 i18n 插件的 onMounted 生命周期方法
              const { i18nSearchTypes, currentSearchType } = ctx()
              currentSearchType.value = i18nSearchTypes[0].value
            }
          ]
        }
      }
    }
  }
}

详细内容请参考 注册表高级配置

其他改进

  • 默认注册表内置:v2.7 版本内置了全量的默认注册表,如果对原插件没有改动(配置、替换、删除),则不需要在注册表中进行声明。

升级步骤建议

  1. 检查当前项目中的注册表配置,将其调整为新的基于唯一 ID 的扁平结构
  2. 更新布局配置,使用 layoutConfigrelativeLayoutConfig 来定位插件
  3. 移除插件中的 align 配置和 type: 'setting' 配置
  4. 如有必要,使用注册表热修复功能解决紧急问题

常见问题

如何查找插件的唯一 ID?

可以参考官方默认的全局注册表:默认注册表

我的插件在升级后无法正常显示

请检查以下几点:

  1. 插件的唯一 ID 是否正确
  2. 布局配置中是否包含了该插件
  3. 插件是否被设置为 false