From af9c577bf6a90a5373d6aec9c6c07e1973bd3849 Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Wed, 18 Mar 2026 19:50:58 +0800 Subject: [PATCH] optimize deps --- .../steps/install.tsx | 6 +- .../steps/install.tsx | 6 +- .../update-plugin/plugin-version-picker.tsx | 2 +- web/utils/semver.ts | 90 ++----------------- web/vite.config.ts | 8 ++ 5 files changed, 20 insertions(+), 92 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index b115800548..1e36daefc1 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -5,12 +5,12 @@ import { RiLoader2Line } from '@remixicon/react' import * as React from 'react' import { useEffect, useMemo } from 'react' import { Trans, useTranslation } from 'react-i18next' +import { gte } from 'semver' import Button from '@/app/components/base/button' import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed' import { useAppContext } from '@/context/app-context' import { uninstallPlugin } from '@/service/plugins' import { useInstallPackageFromLocal, usePluginTaskList } from '@/service/use-plugins' -import { gte } from '@/utils/semver' import Card from '../../../card' import { TaskStatus } from '../../../types' import checkTaskStatus from '../../base/check-task-status' @@ -117,7 +117,7 @@ const Installed: FC = ({ return ( <>
-
+

{t(`${i18nPrefix}.readyToInstall`, { ns: 'plugin' })}

= ({ />

{!isDifyVersionCompatible && ( -

+

{t('difyVersionNotCompatible', { ns: 'plugin', minimalDifyVersion: payload.meta.minimum_dify_version })}

)} diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx index c2779aece8..275d4ca47b 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -5,11 +5,11 @@ import { RiLoader2Line } from '@remixicon/react' import * as React from 'react' import { useEffect, useMemo } from 'react' import { useTranslation } from 'react-i18next' +import { gte } from 'semver' import Button from '@/app/components/base/button' import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed' import { useAppContext } from '@/context/app-context' import { useInstallPackageFromMarketPlace, usePluginDeclarationFromMarketPlace, usePluginTaskList, useUpdatePackageFromMarketPlace } from '@/service/use-plugins' -import { gte } from '@/utils/semver' import Card from '../../../card' // import { RiInformation2Line } from '@remixicon/react' import { TaskStatus } from '../../../types' @@ -133,10 +133,10 @@ const Installed: FC = ({ return ( <>
-
+

{t(`${i18nPrefix}.readyToInstall`, { ns: 'plugin' })}

{!isDifyVersionCompatible && ( -

+

{t('difyVersionNotCompatible', { ns: 'plugin', minimalDifyVersion: pluginDeclaration?.manifest.meta.minimum_dify_version })}

)} diff --git a/web/app/components/plugins/update-plugin/plugin-version-picker.tsx b/web/app/components/plugins/update-plugin/plugin-version-picker.tsx index a1e18ba123..d662c2b6e0 100644 --- a/web/app/components/plugins/update-plugin/plugin-version-picker.tsx +++ b/web/app/components/plugins/update-plugin/plugin-version-picker.tsx @@ -4,6 +4,7 @@ import type { Placement } from '@/app/components/base/ui/placement' import * as React from 'react' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' +import { lt } from 'semver' import Badge from '@/app/components/base/badge' import { Popover, @@ -13,7 +14,6 @@ import { import useTimestamp from '@/hooks/use-timestamp' import { useVersionListOfPlugin } from '@/service/use-plugins' import { cn } from '@/utils/classnames' -import { lt } from '@/utils/semver' type Props = { disabled?: boolean diff --git a/web/utils/semver.ts b/web/utils/semver.ts index 811f55d8e7..aea84153ec 100644 --- a/web/utils/semver.ts +++ b/web/utils/semver.ts @@ -1,93 +1,13 @@ -type SemverIdentifier = number | string +import semver from 'semver' -type ParsedSemver = { - core: number[] - prerelease: SemverIdentifier[] -} - -const parseIdentifier = (value: string): SemverIdentifier => { - if (/^\d+$/.test(value)) - return Number(value) - - return value -} - -const parseSemver = (version: string): ParsedSemver => { - const normalized = version.trim().replace(/^v/i, '').split('+')[0] - const [corePart, prereleasePart] = normalized.split('-', 2) - - return { - core: corePart.split('.').map(part => Number(part) || 0), - prerelease: prereleasePart - ? prereleasePart.split('.').filter(Boolean).map(parseIdentifier) - : [], - } -} - -const compareIdentifier = (left: SemverIdentifier, right: SemverIdentifier) => { - if (typeof left === 'number' && typeof right === 'number') - return Math.sign(left - right) - - if (typeof left === 'number') - return -1 - - if (typeof right === 'number') - return 1 - - return left.localeCompare(right) -} - -const comparePrerelease = (left: SemverIdentifier[], right: SemverIdentifier[]) => { - if (!left.length && !right.length) - return 0 - - if (!left.length) - return 1 - - if (!right.length) - return -1 - - const maxLength = Math.max(left.length, right.length) - for (let i = 0; i < maxLength; i += 1) { - const leftId = left[i] - const rightId = right[i] - - if (leftId === undefined) - return -1 - - if (rightId === undefined) - return 1 - - const result = compareIdentifier(leftId, rightId) - if (result !== 0) - return result - } - - return 0 +export const getLatestVersion = (versionList: string[]) => { + return semver.rsort(versionList)[0] } export const compareVersion = (v1: string, v2: string) => { - const left = parseSemver(v1) - const right = parseSemver(v2) - const maxCoreLength = Math.max(left.core.length, right.core.length) - - for (let i = 0; i < maxCoreLength; i += 1) { - const diff = (left.core[i] || 0) - (right.core[i] || 0) - if (diff !== 0) - return Math.sign(diff) - } - - return comparePrerelease(left.prerelease, right.prerelease) -} - -export const gte = (v1: string, v2: string) => compareVersion(v1, v2) >= 0 - -export const lt = (v1: string, v2: string) => compareVersion(v1, v2) < 0 - -export const getLatestVersion = (versionList: string[]) => { - return [...versionList].sort((left, right) => compareVersion(right, left))[0] + return semver.compare(v1, v2) } export const isEqualOrLaterThanVersion = (baseVersion: string, targetVersion: string) => { - return gte(baseVersion, targetVersion) + return semver.gte(baseVersion, targetVersion) } diff --git a/web/vite.config.ts b/web/vite.config.ts index de74154651..1995c3ed79 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -79,6 +79,14 @@ export default defineConfig(({ mode }) => { // SyntaxError: Named export not found. The requested module is a CommonJS module, which may not support all module.exports as named exports noExternal: ['emoji-mart'], }, + environments: { + rsc: { + optimizeDeps: { include: ['semver'] }, + }, + ssr: { + optimizeDeps: { include: ['semver'] }, + }, + }, } : {}),