chore(web): new lint setup (#30020)

Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
This commit is contained in:
Stephen Zhou
2025-12-23 16:58:55 +08:00
committed by GitHub
parent 9701a2994b
commit f2842da397
3356 changed files with 85046 additions and 81278 deletions

View File

@@ -4,8 +4,8 @@
* It is intended to be used as a replacement for `next start`.
*/
import { cp, mkdir, stat } from 'node:fs/promises'
import { spawn } from 'node:child_process'
import { cp, mkdir, stat } from 'node:fs/promises'
import path from 'node:path'
// Configuration for directories to copy

View File

@@ -15,40 +15,41 @@ const sizes = [
{ size: 128, name: 'icon-128x128.png' },
{ size: 144, name: 'icon-144x144.png' },
{ size: 152, name: 'icon-152x152.png' },
];
]
const inputPath = path.join(__dirname, '../public/icon.svg');
const outputDir = path.join(__dirname, '../public');
const inputPath = path.join(__dirname, '../public/icon.svg')
const outputDir = path.join(__dirname, '../public')
// Generate icons
async function generateIcons() {
try {
console.log('Generating PWA icons...');
console.log('Generating PWA icons...')
for (const { size, name } of sizes) {
const outputPath = path.join(outputDir, name);
const outputPath = path.join(outputDir, name)
await sharp(inputPath)
.resize(size, size)
.png()
.toFile(outputPath);
console.log(`✓ Generated ${name} (${size}x${size})`);
.toFile(outputPath)
console.log(`✓ Generated ${name} (${size}x${size})`)
}
// Generate apple-touch-icon
await sharp(inputPath)
.resize(180, 180)
.png()
.toFile(path.join(outputDir, 'apple-touch-icon.png'));
console.log('✓ Generated apple-touch-icon.png (180x180)');
console.log('\n✅ All icons generated successfully!');
} catch (error) {
console.error('Error generating icons:', error);
process.exit(1);
.toFile(path.join(outputDir, 'apple-touch-icon.png'))
console.log('✓ Generated apple-touch-icon.png (180x180)')
console.log('\n✅ All icons generated successfully!')
}
catch (error) {
console.error('Error generating icons:', error)
process.exit(1)
}
}
generateIcons();
generateIcons()

View File

@@ -10,14 +10,14 @@ import { fileURLToPath } from 'node:url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
console.log('🔧 Optimizing standalone output...');
console.log('🔧 Optimizing standalone output...')
const standaloneDir = path.join(__dirname, '..', '.next', 'standalone');
const standaloneDir = path.join(__dirname, '..', '.next', 'standalone')
// Check if standalone directory exists
if (!fs.existsSync(standaloneDir)) {
console.error('❌ Standalone directory not found. Please run "next build" first.');
process.exit(1);
console.error('❌ Standalone directory not found. Please run "next build" first.')
process.exit(1)
}
// List of paths to remove (relative to standalone directory)
@@ -28,126 +28,136 @@ const pathsToRemove = [
'node_modules/.pnpm/terser-webpack-plugin@*/node_modules/jest-worker',
// Remove actual jest-worker packages (directories only, not symlinks)
'node_modules/.pnpm/jest-worker@*',
];
]
// Function to safely remove a path
function removePath(basePath, relativePath) {
const fullPath = path.join(basePath, relativePath);
const fullPath = path.join(basePath, relativePath)
// Handle wildcard patterns
if (relativePath.includes('*')) {
const parts = relativePath.split('/');
let currentPath = basePath;
const parts = relativePath.split('/')
let currentPath = basePath
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
const part = parts[i]
if (part.includes('*')) {
// Find matching directories
if (fs.existsSync(currentPath)) {
const entries = fs.readdirSync(currentPath);
const entries = fs.readdirSync(currentPath)
// replace '*' with '.*'
const regexPattern = part.replace(/\*/g, '.*');
const regexPattern = part.replace(/\*/g, '.*')
const regex = new RegExp(`^${regexPattern}$`);
const regex = new RegExp(`^${regexPattern}$`)
for (const entry of entries) {
if (regex.test(entry)) {
const remainingPath = parts.slice(i + 1).join('/');
const matchedPath = path.join(currentPath, entry, remainingPath);
const remainingPath = parts.slice(i + 1).join('/')
const matchedPath = path.join(currentPath, entry, remainingPath)
try {
// Use lstatSync to check if path exists (works for both files and symlinks)
const stats = fs.lstatSync(matchedPath);
const stats = fs.lstatSync(matchedPath)
if (stats.isSymbolicLink()) {
// Remove symlink
fs.unlinkSync(matchedPath);
console.log(`✅ Removed symlink: ${path.relative(basePath, matchedPath)}`);
} else {
// Remove directory/file
fs.rmSync(matchedPath, { recursive: true, force: true });
console.log(`✅ Removed: ${path.relative(basePath, matchedPath)}`);
fs.unlinkSync(matchedPath)
console.log(`✅ Removed symlink: ${path.relative(basePath, matchedPath)}`)
}
} catch (error) {
else {
// Remove directory/file
fs.rmSync(matchedPath, { recursive: true, force: true })
console.log(`✅ Removed: ${path.relative(basePath, matchedPath)}`)
}
}
catch (error) {
// Silently ignore ENOENT (path not found) errors
if (error.code !== 'ENOENT') {
console.error(`❌ Failed to remove ${matchedPath}: ${error.message}`);
console.error(`❌ Failed to remove ${matchedPath}: ${error.message}`)
}
}
}
}
}
return;
} else {
currentPath = path.join(currentPath, part);
return
}
else {
currentPath = path.join(currentPath, part)
}
}
} else {
}
else {
// Direct path removal
if (fs.existsSync(fullPath)) {
try {
fs.rmSync(fullPath, { recursive: true, force: true });
console.log(`✅ Removed: ${relativePath}`);
} catch (error) {
console.error(`❌ Failed to remove ${fullPath}: ${error.message}`);
fs.rmSync(fullPath, { recursive: true, force: true })
console.log(`✅ Removed: ${relativePath}`)
}
catch (error) {
console.error(`❌ Failed to remove ${fullPath}: ${error.message}`)
}
}
}
}
// Remove unnecessary paths
console.log('🗑️ Removing unnecessary files...');
console.log('🗑️ Removing unnecessary files...')
for (const pathToRemove of pathsToRemove) {
removePath(standaloneDir, pathToRemove);
removePath(standaloneDir, pathToRemove)
}
// Calculate size reduction
console.log('\n📊 Optimization complete!');
console.log('\n📊 Optimization complete!')
// Optional: Display the size of remaining jest-related files (if any)
const checkForJest = (dir) => {
const jestFiles = [];
const jestFiles = []
function walk(currentPath) {
if (!fs.existsSync(currentPath)) return;
if (!fs.existsSync(currentPath))
return
try {
const entries = fs.readdirSync(currentPath);
const entries = fs.readdirSync(currentPath)
for (const entry of entries) {
const fullPath = path.join(currentPath, entry);
const fullPath = path.join(currentPath, entry)
try {
const stat = fs.lstatSync(fullPath); // Use lstatSync to handle symlinks
const stat = fs.lstatSync(fullPath) // Use lstatSync to handle symlinks
if (stat.isDirectory() && !stat.isSymbolicLink()) {
// Skip node_modules subdirectories to avoid deep traversal
if (entry === 'node_modules' && currentPath !== standaloneDir) {
continue;
continue
}
walk(fullPath);
} else if (stat.isFile() && entry.includes('jest')) {
jestFiles.push(path.relative(standaloneDir, fullPath));
walk(fullPath)
}
} catch (err) {
else if (stat.isFile() && entry.includes('jest')) {
jestFiles.push(path.relative(standaloneDir, fullPath))
}
}
catch (err) {
// Skip files that can't be accessed
continue;
continue
}
}
} catch (err) {
}
catch (err) {
// Skip directories that can't be read
return;
}
}
walk(dir);
return jestFiles;
};
const remainingJestFiles = checkForJest(standaloneDir);
if (remainingJestFiles.length > 0) {
console.log('\n⚠ Warning: Some jest-related files still remain:');
remainingJestFiles.forEach(file => console.log(` - ${file}`));
} else {
console.log('\n✨ No jest-related files found in standalone output!');
walk(dir)
return jestFiles
}
const remainingJestFiles = checkForJest(standaloneDir)
if (remainingJestFiles.length > 0) {
console.log('\n⚠ Warning: Some jest-related files still remain:')
remainingJestFiles.forEach(file => console.log(` - ${file}`))
}
else {
console.log('\n✨ No jest-related files found in standalone output!')
}