Экспорт компонента из модуля в зависимости от установленных зависимостей

Я разрабатываю пакет react-компонентов и преполагаю использовать его в проектах с разными UI-китами, поэтому мне нужно иметь несколько типовых вариантов с разными зависимостями.

В моём исполнении каждый вариант компонента пишется независимо в директории названной по основной зависимости, а также вариант без зависимостей в директории core.

структура файлов

index.ts:

const isModuleInstalled = (moduleName: string | string[]) => {
    try {
        if (Array.isArray(moduleName))
            for (const name of moduleName)
                require.resolve(name)
        else
            require.resolve(moduleName)
        return true // Module found
    } catch (e) {
        return false // Module not found
    }
}

let selectedViews: Awaited<typeof import('./core')>
if (isModuleInstalled(['@mui/material', '@mui/icons-material', '@emotion/styled'])) {
    selectedViews = await import('./mui')
} else if (isModuleInstalled('antd')) {
    selectedViews = await import('./antd')
} else {
    selectedViews = await import('./core')
}

export * as Antd from './antd'
export * as Mui from './mui'
export * as Core from './core'

export const Views = selectedViews
export default Views

Сборкой занимается tsup и запускается без аргументов. Собственно мой вопрос как оптимальнее всё это организовать, чтобы не создавать лишних ошибок при импорте и не закидывать в билд продукта использующего пакет лишние файлы, которые он никогда не откроет?

В идеале ещё бы понять как менять типы в зависимости от выбранного модуля, так как сейчас берётся тип из core, а динамический экспорт очевидно не разрешён.

package.json:

{
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "files": ["dist"],

  ...

  "peerDependencies": {
    "@emotion/styled": "^11.14.0",
    "@mui/icons-material": "^7.1.2",
    "@mui/material": "^7.1.2",
    "antd": "^5.18.0",
    "react": "^19.1.1"
  },
  "peerDependenciesMeta": {
    "@emotion/styled": { "optional": true },
    "@mui/icons-material": { "optional": true },
    "@mui/material": { "optional": true },
    "antd": { "optional": true }
  }
}

Ответы (0 шт):