前端代码质量保证:让你的代码更可靠

前端代码质量保证:让你的代码更可靠

毒舌时刻

代码质量?听起来就像是前端工程师为了显得自己很专业而特意搞的一套复杂流程。你以为随便写几个测试就能保证代码质量?别做梦了!到时候你会发现,测试代码比业务代码还多,维护起来比业务代码还麻烦。

你以为ESLint能解决所有问题?别天真了!ESLint只能检查代码风格,无法检查逻辑错误。还有那些所谓的代码质量工具,看起来高大上,用起来却各种问题。

为什么你需要这个

  1. 减少错误:代码质量保证可以帮助你发现和修复代码中的错误,减少生产环境中的问题。
  2. 提高可维护性:高质量的代码更容易理解和维护,减少后期的维护成本。
  3. 促进团队协作:统一的代码质量标准可以便于团队成员之间的协作,减少沟通成本。
  4. 提高开发效率:高质量的代码可以减少调试和修复错误的时间,提高开发效率。
  5. 提升代码安全性:代码质量保证可以帮助你发现和修复安全漏洞,提升代码的安全性。

反面教材

// 这是一个典型的代码质量问题示例 // 1. 代码风格不一致 function getUser(id) { return fetch(`/api/users/${id}`) .then(res => res.json()) .then(data => { return data; }); } function getProduct(id){ return fetch(`/api/products/${id}`).then(res=>res.json()).then(data=>data); } // 2. 未使用的变量 function calculateTotal(price, quantity) { const tax = 0.08; const discount = 0.1; return price * quantity; } // 3. 硬编码值 function getShippingCost(weight) { if (weight < 10) { return 5.99; } else if (weight < 20) { return 9.99; } else { return 14.99; } } // 4. 缺少错误处理 function fetchData() { fetch('/api/data') .then(response => response.json()) .then(data => console.log(data)); } // 5. 复杂的条件语句 function getDiscount(user, product) { if (user.isMember && user.membershipLevel >= 3) { if (product.category === 'electronics') { return 0.2; } else if (product.category === 'clothing') { return 0.15; } else { return 0.1; } } else if (user.isMember) { if (product.category === 'electronics') { return 0.1; } else if (product.category === 'clothing') { return 0.08; } else { return 0.05; } } else { return 0; } } 

问题

  • 代码风格不一致,影响可读性
  • 未使用的变量,增加代码复杂度
  • 硬编码值,难以维护
  • 缺少错误处理,容易导致应用崩溃
  • 复杂的条件语句,难以理解和维护

正确的做法

代码风格规范

// 1. ESLint配置 // .eslintrc.js module.exports = { env: { browser: true, es2021: true, node: true }, extends: [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:react-hooks/recommended' ], parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: 12, sourceType: 'module' }, plugins: [ 'react', 'react-hooks' ], rules: { 'react/prop-types': 'off', 'react/react-in-jsx-scope': 'off', 'indent': ['error', 2], 'linebreak-style': ['error', 'unix'], 'quotes': ['error', 'single'], 'semi': ['error', 'always'], 'no-unused-vars': 'error', 'no-console': 'warn' } }; // 2. Prettier配置 // .prettierrc.js module.exports = { semi: true, trailingComma: 'es5', singleQuote: true, printWidth: 80, tabWidth: 2 }; // 3. EditorConfig配置 // .editorconfig root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false 

代码质量工具

// 1. ESLint // 安装 npm install --save-dev eslint eslint-plugin-react eslint-plugin-react-hooks // 配置脚本 { "scripts": { "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0" } } // 2. Prettier // 安装 npm install --save-dev prettier // 配置脚本 { "scripts": { "format": "prettier --write ." } } // 3. Stylelint // 安装 npm install --save-dev stylelint stylelint-config-standard // 配置 // .stylelintrc.js module.exports = { extends: 'stylelint-config-standard', rules: { 'indentation': 2, 'string-quotes': 'single' } }; // 配置脚本 { "scripts": { "lint:css": "stylelint '**/*.css'" } } // 4. TypeScript // 安装 npm install --save-dev typescript @types/react @types/react-dom // 配置 // tsconfig.json { "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx" }, "include": ["src"] } // 配置脚本 { "scripts": { "typecheck": "tsc --noEmit" } } 

测试工具

// 1. Jest // 安装 npm install --save-dev jest @testing-library/react @testing-library/jest-dom // 配置 // jest.config.js module.exports = { testEnvironment: 'jsdom', transform: { '^.+\\.(js|jsx)$': 'babel-jest' }, moduleNameMapper: { '\\.(css|less|scss|sass)$': 'identity-obj-proxy' }, setupFilesAfterEnv: ['<rootDir>/src/setupTests.js'] }; // 配置脚本 { "scripts": { "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage" } } // 2. React Testing Library // 测试示例 import { render, screen, fireEvent } from '@testing-library/react'; import App from './App'; test('renders learn react link', () => { render(<App />); const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); }); test('increments counter when button is clicked', () => { render(<App />); const buttonElement = screen.getByText(/increment/i); const counterElement = screen.getByText(/count:/i); fireEvent.click(buttonElement); expect(counterElement).toHaveTextContent('Count: 1'); }); // 3. Playwright (E2E测试) // 安装 npm install --save-dev @playwright/test // 配置 // playwright.config.js module.exports = { use: { baseURL: 'http://localhost:3000', headless: true, viewport: { width: 1280, height: 720 }, ignoreHTTPSErrors: true } }; // 测试示例 // tests/example.spec.js const { test, expect } = require('@playwright/test'); test('has title', async ({ page }) => { await page.goto('/'); await expect(page).toHaveTitle(/React App/); }); test('get started link', async ({ page }) => { await page.goto('/'); await page.click('text=Learn React'); await expect(page).toHaveURL(/.*react.dev/); }); // 配置脚本 { "scripts": { "test:e2e": "playwright test" } } 

代码审查

// 1. GitHub Actions配置 // .github/workflows/code-quality.yml name: Code Quality on: push: branches: [ main ] pull_request: branches: [ main ] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '16' - name: Install dependencies run: npm install - name: Run ESLint run: npm run lint - name: Run Prettier run: npm run format -- --check - name: Run TypeScript run: npm run typecheck - name: Run tests run: npm test // 2. 代码审查工具 // 安装 npm install --save-dev eslint-plugin-security eslint-plugin-sonarjs // 配置 // .eslintrc.js module.exports = { plugins: [ 'security', 'sonarjs' ], rules: { 'security/detect-unsafe-regex': 'error', 'security/detect-buffer-noassert': 'error', 'sonarjs/cognitive-complexity': ['error', 15], 'sonarjs/no-duplicate-string': ['error', { threshold: 3 }] } }; 

最佳实践

// 1. 代码组织 // 按功能组织文件 /src /components /Button Button.jsx Button.css Button.test.jsx /Card Card.jsx Card.css Card.test.jsx /pages /Home Home.jsx Home.css Home.test.jsx /About About.jsx About.css About.test.jsx /utils api.js helpers.js constants.js /hooks useAuth.js useLocalStorage.js /context AuthContext.jsx ThemeContext.jsx // 2. 命名规范 // 组件名:PascalCase function UserProfile() { return <div>User Profile</div>; } // 变量名:camelCase const userCount = 10; // 常量:UPPER_SNAKE_CASE const API_BASE_URL = 'https://api.example.com'; // 函数名:camelCase function getUserData() { return fetch('/api/user'); } // 3. 错误处理 async function fetchData() { try { const response = await fetch('/api/data'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error('Error fetching data:', error); throw error; } } // 4. 注释 /** * 获取用户信息 * @param {number} id - 用户ID * @returns {Promise<Object>} 用户信息 */ async function getUser(id) { const response = await fetch(`/api/users/${id}`); return response.json(); } // 5. 模块化 // utils/api.js export async function fetchUsers() { const response = await fetch('/api/users'); return response.json(); } export async function fetchProducts() { const response = await fetch('/api/products'); return response.json(); } // 使用 import { fetchUsers, fetchProducts } from './utils/api'; async function loadData() { const [users, products] = await Promise.all([ fetchUsers(), fetchProducts() ]); return { users, products }; } 

毒舌点评

代码质量保证确实很重要,但我见过太多开发者滥用这个特性,导致开发流程变得过于复杂。

想象一下,当你为了通过代码审查,写了大量的测试代码和注释,结果导致代码量增加了几倍,这真的值得吗?

还有那些过度使用代码质量工具的开发者,为了满足工具的要求,写了大量的冗余代码,结果导致代码变得难以理解和维护。

所以,在进行代码质量保证时,一定要把握好度。不要为了追求代码质量而牺牲开发效率,要根据实际情况来决定代码质量保证的策略。

当然,对于大型项目来说,代码质量保证是必不可少的。但对于小型项目,过度的代码质量保证反而会增加开发成本和维护难度。

最后,记住一句话:代码质量保证的目的是为了提高代码的可靠性和可维护性,而不是为了炫技。如果你的代码质量保证策略导致开发变得更慢或更复杂,那你就失败了。

Read more

前端环境配置(nvm、nodejs、npm)

前端环境配置(nvm、nodejs、npm)

一、安装nvm 1. 下载vnm url: https://nvm.uihtm.com/doc/download-nvm.html 2. 解压文件后双击exe文件进行安装 3. 选择nvm的安装地址,我是安装在D:\App\nvm 4. 选择nodejs的安装地址,我是安装在C:\Program Files\nodejs 5. 点击next 一直点击 完成安装; 6. 找到nvm的settings.txt文件打开后: 给该文件添加这两行命令: node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: https://npmmirror.com/mirrors/npm/ 二、环境变量配置 1.

【DeepSeek R1部署至RK3588】RKLLM转换→板端部署→局域网web浏览

【DeepSeek R1部署至RK3588】RKLLM转换→板端部署→局域网web浏览

本文为DeepSeek R1 7B 以qwen为底座的LLM在瑞芯微RK3588 SoC上的完整部署流程,记录从开发板驱动适配烧录开始,到最终的开发板终端访问模型和局域网web访问模型的完整流程,有不足之处希望大家共同讨论。 文章目录 * 一、项目背景介绍 * 二、所需工具介绍 * 1.硬件工具 * 1.X86 PC虚拟机Ubuntu20.04 * 2. 准备NPU驱动为0.9.8的RK3588开发板 * 2.软件工具 * 三、获取.safetensors模型权重 * 四、safetensors转RKLLM * 1.转换环境搭建 * 2.模型转换 * 五、RKLLM模型板端部署及推理 * 六、集成开源gradio工具实现web访问 一、项目背景介绍 先来介绍下项目背景吧,目前有一个空闲的firefly出厂的搭载瑞芯微RK3588 SoC的arm64开发板,样式如图所示: 博主之前主要进行CV领域的模型的RK开发板部署,对于LLM和VLM的接触并不算多,但现在大模型是趋势所向,并且瑞芯微及时的完成了针对各开源

想做多语言项目?试试Hunyuan-MT-7B-WEBUI快速部署方案

想做多语言项目?试试Hunyuan-MT-7B-WEBUI快速部署方案 你有没有遇到过这样的情况:手头有个跨境项目,要同时处理日语产品说明、西班牙语用户反馈、维吾尔语政策文件,甚至还有藏文古籍数字化需求——可翻来翻去,不是翻译质量差强人意,就是部署起来像在解一道高数题?在线工具不敢传敏感数据,本地跑模型又卡在CUDA版本、依赖冲突、显存爆炸上……最后只能靠人工硬啃,进度一拖再拖。 Hunyuan-MT-7B-WEBUI 就是为这种真实困境而生的。它不讲大道理,不堆参数,不做“实验室里的冠军”,而是把腾讯混元团队打磨出的最强开源翻译模型,连同网页界面、一键脚本、预装环境,全打包进一个镜像里。你不需要懂Transformer结构,不用查PyTorch兼容表,甚至不用打开终端敲命令——点一下,等两分钟,就能在浏览器里开始翻译38种语言。 这不是又一个“需要调参、需要写代码、需要配环境”的AI工具。这是你今天下午就能用上的多语言工作台。 1. 为什么这款翻译镜像值得你立刻试试? 1.1 它真能覆盖你没想过的语言 很多翻译模型标榜“支持多语言”,但实际打开列表一看:英、法、

前端实现Word文档在线编辑与导出:基于mammoth.js与Blob对象的完整解决方案

如何在浏览器中直接编辑Word文档并导出?本文将深入探索一种基于mammoth.js和Blob对象的完整技术方案。 在当今的Web应用开发中,实现文档的在线编辑与导出已成为常见需求。无论是企业内部系统、教育平台还是项目管理工具,都迫切需要让用户能够在浏览器中直接编辑Word文档,而无需安装桌面软件。本文将详细介绍如何利用mammoth.js和Blob对象实现这一功能,并对比其他可行方案。 一、为什么选择mammoth.js与Blob方案? 在Web前端实现Word文档处理,主要有三种主流方案:浏览器原生Blob导出、mammoth.js专业转换和基于模板的docxtemplater方案。它们各有优劣,适用于不同场景。 mammoth.js的核心优势在于它能将.docx文档转换为语义化的HTML,而非简单复制视觉样式。这意味着它生成的HTML结构清晰、易于维护和样式定制。配合Blob对象,我们可以轻松将编辑后的内容重新导出为Word文档。 与直接使用Microsoft Office Online或Google Docs嵌入相比,mammoth.js方案不依赖外部服务,能更好地