const fs = require('fs') const path = require('path') const PROJECT_ROOT = process.cwd() const IGNORED_SEGMENTS = ['node_modules', 'miniprogram_npm', 'coverage', '.worktrees'] function shouldIgnore(filePath) { return IGNORED_SEGMENTS.some(segment => filePath.includes(`${path.sep}${segment}${path.sep}`)) } function getProjectFiles(extension) { const pendingDirs = [PROJECT_ROOT] const collectedFiles = [] while (pendingDirs.length) { const currentDir = pendingDirs.pop() const entries = fs.readdirSync(currentDir, { withFileTypes: true }) entries.forEach(entry => { const absolutePath = path.join(currentDir, entry.name) if (shouldIgnore(absolutePath)) { return } if (entry.isDirectory()) { pendingDirs.push(absolutePath) return } if (entry.isFile() && absolutePath.endsWith(extension)) { collectedFiles.push(absolutePath) } }) } return collectedFiles } function getDirectoryImportViolations() { const requirePattern = /require\((['"])(\.[^'"]+)\1\)/g return getProjectFiles('.js').flatMap(filePath => { const source = fs.readFileSync(filePath, 'utf8') const violations = [] let match = requirePattern.exec(source) while (match) { const specifier = match[2] const targetPath = path.resolve(path.dirname(filePath), specifier) if (fs.existsSync(targetPath) && fs.statSync(targetPath).isDirectory()) { violations.push({ filePath: path.relative(PROJECT_ROOT, filePath), specifier }) } match = requirePattern.exec(source) } return violations }) } function getImportTarget(wxssPath, importPath) { return path.resolve(path.dirname(wxssPath), importPath) } function getTDesignSourceFallback(importPath) { const generatedPrefix = './miniprogram_npm/tdesign-miniprogram/' if (!importPath.startsWith(generatedPrefix)) { return null } return path.join( PROJECT_ROOT, 'node_modules', 'tdesign-miniprogram', 'miniprogram_dist', importPath.slice(generatedPrefix.length) ) } describe('miniprogram compatibility', () => { test('avoids directory-level require paths that the miniprogram runtime cannot resolve reliably', () => { expect(getDirectoryImportViolations()).toEqual([]) }) test('app.wxss points at a TDesign style entry that can be resolved before or after npm build', () => { const appWxssPath = path.join(PROJECT_ROOT, 'app.wxss') const appWxss = fs.readFileSync(appWxssPath, 'utf8') const match = appWxss.match(/@import ['"]([^'"]+)['"];/) const importPath = match && match[1] const generatedTarget = importPath && getImportTarget(appWxssPath, importPath) const sourceFallbackTarget = importPath && getTDesignSourceFallback(importPath) expect(match).not.toBeNull() expect( fs.existsSync(generatedTarget) || (sourceFallbackTarget && fs.existsSync(sourceFallbackTarget)) ).toBe(true) }) })