Files
hermes-desktop/tests/client/no-naive-ui.test.ts
T
toor 01d9e301fc
Build / build (push) Canceled after 0s
Playwright / browser (push) Canceled after 0s
initialize Electron desktop app and remove unused files
2026-10-25 01:09:01 +08:00

78 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readdirSync, readFileSync, statSync } from 'fs'
import { join } from 'path'
import { describe, expect, it } from 'vitest'
const SRC_ROOT = 'packages/client/src'
const listFiles = (dir: string): string[] =>
readdirSync(dir).flatMap((name) => {
const full = join(dir, name)
return statSync(full).isDirectory() ? listFiles(full) : [full]
})
const sourceFiles = listFiles(SRC_ROOT).filter((file) =>
/\.(vue|ts|js)$/.test(file),
)
/**
* naive-ui 的类名在迁移时最容易漏:`grep naive-ui` 只匹配 import,
* 匹配不到样式块里的 `:deep(.n-button__content)` 这种写法,也不匹配
* JS 里的字符串字面量(`document.querySelector('.n-modal-mask')`)。
* 这两种都会在 Arco 下静默失效,不报错、测试也测不出来。
*/
const NAIVE_CLASS_PATTERN = /\.n-[a-z][\w-]*/i
const findOffenders = (pattern: RegExp) =>
sourceFiles
.filter((file) => pattern.test(readFileSync(file, 'utf8')))
.map((file) => file.replace(`${SRC_ROOT}/`, ''))
describe('naive-ui removal', () => {
it('has source files to scan', () => {
expect(sourceFiles.length).toBeGreaterThan(100)
})
it('never imports from naive-ui', () => {
expect(findOffenders(/from\s+['"]naive-ui['"]/)).toEqual([])
})
it('never imports naive-ui types or helpers by deep path', () => {
// packages/client/src 下没有深层导入,但防止将来有人从 @css-render 绕进来
expect(
findOffenders(/from\s+['"](vueuc|@css-render\/vue3-ssr|vdirs|seemly)['"]/),
).toEqual([])
})
it('never references naive-ui CSS class names', () => {
// 覆盖样式块里的 :deep(.n-*) 与 JS 字符串字面量两种写法
expect(findOffenders(NAIVE_CLASS_PATTERN)).toEqual([])
})
it('never registers naive-ui components globally', () => {
const main = readFileSync(join(SRC_ROOT, 'main.ts'), 'utf8')
expect(main).toContain('ArcoVue')
expect(main).not.toMatch(/N[A-Z][A-Za-z]*Provider/)
})
it('does not depend on naive-ui in package.json', () => {
const pkg = JSON.parse(readFileSync('package.json', 'utf8'))
const all = { ...pkg.dependencies, ...pkg.devDependencies }
expect(Object.keys(all)).not.toContain('naive-ui')
for (const dep of Object.keys(all)) {
expect(dep).not.toBe('vueuc')
expect(dep).not.toBe('vdirs')
}
})
it('does not chunk naive-ui in the vite config', () => {
const config = readFileSync('vite.config.ts', 'utf8')
expect(config).not.toMatch(/['"]naive-ui['"]/)
// Arco 的 scope 名含 "vue" 子串,判断必须排在 vue-vendor 之前,
// 否则整个 UI 库会被打进 vue chunk。见 vite.config.ts 的注释。
const arcoIndex = config.indexOf('@arco-design')
const vueIndex = config.indexOf('vue-vendor')
expect(arcoIndex).toBeGreaterThan(-1)
expect(arcoIndex).toBeLessThan(vueIndex)
})
})