80 lines
2.0 KiB
JavaScript
80 lines
2.0 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readdirSync, readFileSync } from 'node:fs'
|
|
import { join, relative } from 'node:path'
|
|
import test from 'node:test'
|
|
|
|
const MAX_SOURCE_UNIT_LINES = 800
|
|
const REPO_ROOT = new URL('../..', import.meta.url).pathname
|
|
|
|
const FRONTEND_SOURCE_ROOTS = [
|
|
'web/src/components',
|
|
'web/src/composables',
|
|
'web/src/utils',
|
|
'web/src/views',
|
|
]
|
|
|
|
const FRONTEND_EXTENSIONS = new Set(['.html', '.js', '.mjs', '.ts', '.tsx', '.vue'])
|
|
|
|
function extensionOf(path) {
|
|
const index = path.lastIndexOf('.')
|
|
return index === -1 ? '' : path.slice(index)
|
|
}
|
|
|
|
function countLines(source) {
|
|
return source.length === 0 ? 0 : source.split('\n').length
|
|
}
|
|
|
|
function walkFiles(root, shouldInclude) {
|
|
const result = []
|
|
const stack = [root]
|
|
|
|
while (stack.length > 0) {
|
|
const current = stack.pop()
|
|
const entries = readdirSync(current, { withFileTypes: true })
|
|
|
|
for (const entry of entries) {
|
|
const path = join(current, entry.name)
|
|
if (entry.isDirectory()) {
|
|
if (!['node_modules', 'dist', 'build', 'coverage'].includes(entry.name)) {
|
|
stack.push(path)
|
|
}
|
|
continue
|
|
}
|
|
|
|
if (shouldInclude(path)) {
|
|
result.push(path)
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
function listOversizedFrontendUnits() {
|
|
return FRONTEND_SOURCE_ROOTS.flatMap((root) => {
|
|
const absoluteRoot = join(REPO_ROOT, root)
|
|
return walkFiles(
|
|
absoluteRoot,
|
|
(path) => FRONTEND_EXTENSIONS.has(extensionOf(path))
|
|
)
|
|
})
|
|
.map((path) => ({
|
|
path: relative(REPO_ROOT, path),
|
|
lines: countLines(readFileSync(path, 'utf8')),
|
|
}))
|
|
.filter((item) => item.lines > MAX_SOURCE_UNIT_LINES)
|
|
.sort((left, right) => right.lines - left.lines)
|
|
}
|
|
|
|
test('前端核心组件和模块不超过 800 行', () => {
|
|
const oversized = listOversizedFrontendUnits()
|
|
|
|
assert.deepEqual(
|
|
oversized,
|
|
[],
|
|
`以下前端核心源文件超过 ${MAX_SOURCE_UNIT_LINES} 行:\n${
|
|
oversized.map((item) => `- ${item.path}: ${item.lines}`).join('\n')
|
|
}`
|
|
)
|
|
})
|