乐闻世界logo
搜索文章和话题

前端面试题手册

RxJS 中 Hot Observable 和 Cold Observable 有什么区别?

Hot Observable vs Cold ObservableCold Observable(冷 Observable)定义: Cold Observable 是惰性的,每个订阅者都会独立执行 Observable 的逻辑。特点:每个订阅者都会获得独立的数据流订阅时才开始执行不共享数据生产者不会主动推送数据示例:import { Observable } from 'rxjs';const cold$ = new Observable(subscriber => { console.log('Observable executed'); subscriber.next(Math.random()); subscriber.complete();});cold$.subscribe(value => console.log('Subscriber 1:', value));// Observable executed// Subscriber 1: 0.123456cold$.subscribe(value => console.log('Subscriber 2:', value));// Observable executed// Subscriber 2: 0.789012// 注意:每次订阅都重新执行,产生不同的随机数常见的 Cold Observable:of()from()interval()timer()ajax()http.get() (Angular)大多数创建操作符Hot Observable(热 Observable)定义: Hot Observable 是主动的,多个订阅者共享同一个数据流。特点:所有订阅者共享同一个数据流即使没有订阅者也会执行共享数据生产者主动推送数据示例:import { Observable, Subject } from 'rxjs';const hot$ = new Observable(subscriber => { console.log('Observable executed'); subscriber.next(Math.random()); subscriber.complete();});const subject = new Subject();hot$.subscribe(subject);subject.subscribe(value => console.log('Subscriber 1:', value));// Observable executed// Subscriber 1: 0.123456subject.subscribe(value => console.log('Subscriber 2:', value));// Subscriber 2: 0.123456// 注意:两个订阅者收到相同的值常见的 Hot Observable:Subject 及其变体BehaviorSubjectReplaySubjectAsyncSubjectDOM 事件(通过 fromEvent)WebSocket 连接share() 转换后的 Observable转换方法1. 使用 share() 将 Cold 转换为 Hotimport { interval } from 'rxjs';import { share, take } from 'rxjs/operators';const cold$ = interval(1000).pipe( take(5));const hot$ = cold$.pipe( share() // 转换为 Hot Observable);hot$.subscribe(value => console.log('Subscriber 1:', value));hot$.subscribe(value => console.log('Subscriber 2:', value));// 两个订阅者共享同一个数据流2. 使用 shareReplay() 缓存值import { interval } from 'rxjs';import { shareReplay, take } from 'rxjs/operators';const hot$ = interval(1000).pipe( take(5), shareReplay(1) // 缓存最后一个值);hot$.subscribe(value => console.log('Subscriber 1:', value));setTimeout(() => { hot$.subscribe(value => console.log('Subscriber 2:', value)); // 新订阅者会立即收到缓存的值}, 3000);3. 使用 publish() 和 connect()import { interval } from 'rxjs';import { publish, take } from 'rxjs/operators';const cold$ = interval(1000).pipe( take(5));const hot$ = cold$.pipe( publish() // 转换为 Hot Observable);hot$.subscribe(value => console.log('Subscriber 1:', value));hot$.subscribe(value => console.log('Subscriber 2:', value));hot$.connect(); // 开始执行实际应用场景Cold Observable 适用场景HTTP 请求// 每次订阅都会发起新的请求http.get('/api/data').subscribe(data => { console.log('Request 1:', data);});http.get('/api/data').subscribe(data => { console.log('Request 2:', data);});独立的数据处理// 每个订阅者需要独立的数据流of(1, 2, 3).pipe( map(x => x * 2)).subscribe(value => console.log(value));需要重新执行的场景// 每次订阅都重新计算const calculation$ = new Observable(subscriber => { const result = expensiveCalculation(); subscriber.next(result); subscriber.complete();});Hot Observable 适用场景共享数据// 多个组件共享同一个数据流const userData$ = http.get('/api/user').pipe( share());component1.userData$.subscribe(user => { console.log('Component 1:', user);});component2.userData$.subscribe(user => { console.log('Component 2:', user);});// 只发起一次请求,两个组件共享结果事件流// 多个订阅者监听同一个事件const click$ = fromEvent(document, 'click').pipe( share());click$.subscribe(event => { console.log('Handler 1:', event);});click$.subscribe(event => { console.log('Handler 2:', event);});WebSocket 连接// 多个订阅者共享同一个 WebSocket 连接const socket$ = webSocket('ws://localhost:8080').pipe( share());socket$.subscribe(message => { console.log('Handler 1:', message);});socket$.subscribe(message => { console.log('Handler 2:', message);});性能对比Cold Observable 性能特点优点:每个订阅者获得独立的数据流不会相互影响适合需要独立处理的场景缺点:可能重复执行相同的操作浪费资源(如重复的 HTTP 请求)内存占用可能更高Hot Observable 性能特点优点:共享数据流,避免重复执行节省资源(如只发起一次 HTTP 请求)内存占用更低缺点:订阅者可能错过之前的数据需要管理订阅时机可能出现竞态条件选择指南使用 Cold Observable 当:每个订阅者需要独立的数据流需要重新执行操作订阅者之间不应该相互影响数据源是按需生成的使用 Hot Observable 当:多个订阅者需要共享数据需要避免重复执行(如 HTTP 请求)数据源是主动推送的(如事件、WebSocket)需要缓存数据供后续订阅者使用最佳实践1. HTTP 请求共享// ❌ 错误:每次订阅都发起请求class UserService { getUser(id: string) { return http.get(`/api/users/${id}`); }}// ✅ 正确:共享请求结果class UserService { private cache = new Map<string, Observable<User>>(); getUser(id: string) { if (!this.cache.has(id)) { this.cache.set(id, http.get(`/api/users/${id}`).pipe( shareReplay(1) )); } return this.cache.get(id)!; }}2. 事件处理// 使用 share() 共享事件流const resize$ = fromEvent(window, 'resize').pipe( debounceTime(200), share());resize$.subscribe(event => { updateLayout1(event);});resize$.subscribe(event => { updateLayout2(event);});3. 状态管理// 使用 BehaviorSubject 管理状态const state$ = new BehaviorSubject(initialState);state$.subscribe(state => { console.log('Listener 1:', state);});state$.subscribe(state => { console.log('Listener 2:', state);});// 更新状态state$.next(newState);常见陷阱1. 忘记共享导致重复请求// ❌ 错误示例const data$ = http.get('/api/data');data$.subscribe(data => console.log('Component 1:', data));data$.subscribe(data => console.log('Component 2:', data));// 发起两次请求// ✅ 正确示例const data$ = http.get('/api/data').pipe( share());data$.subscribe(data => console.log('Component 1:', data));data$.subscribe(data => console.log('Component 2:', data));// 只发起一次请求2. 错误的共享时机// ❌ 错误示例const data$ = http.get('/api/data').pipe( share());// 立即订阅触发请求data$.subscribe();// 后续订阅者可能错过数据setTimeout(() => { data$.subscribe(data => console.log(data));}, 2000);// ✅ 正确示例const data$ = http.get('/api/data').pipe( shareReplay(1) // 缓存数据);3. 不当使用 shareReplay// ❌ 错误示例:缓存过多数据const data$ = interval(1000).pipe( shareReplay(1000) // 缓存1000个值,占用大量内存);// ✅ 正确示例:合理设置缓存大小const data$ = interval(1000).pipe( shareReplay(1) // 只缓存最后一个值);总结理解 Hot 和 Cold Observable 的区别对于编写高效的 RxJS 代码至关重要:Cold Observable: 惰性、独立执行、适合按需生成的数据Hot Observable: 主动、共享执行、适合主动推送的数据转换方法: 使用 share()、shareReplay() 等操作符进行转换性能考虑: Hot Observable 可以避免重复执行,提高性能选择原则: 根据场景选择合适的类型,避免不必要的资源浪费正确使用这两种 Observable 类型,可以显著提升应用的性能和可维护性。
阅读 0·2月21日 16:59

如何在 Monorepo 项目中配置和使用 Prettier?

Prettier 在 Monorepo 项目中的应用Monorepo 项目中统一管理多个包的代码格式是一个重要挑战,Prettier 提供了多种解决方案来确保整个 monorepo 的代码风格一致。Monorepo 配置策略1. 根目录统一配置在 monorepo 根目录创建 .prettierrc:{ "semi": true, "singleQuote": true, "tabWidth": 2, "trailingComma": "es5"}2. 共享配置包创建独立的配置包 @my-org/prettier-config:// packages/prettier-config/index.jsmodule.exports = { semi: true, singleQuote: true, tabWidth: 2, trailingComma: "es5", printWidth: 80,};在各个包中使用:{ "prettier": "@my-org/prettier-config"}不同包的差异化配置使用 overrides 为不同包设置不同规则:{ "semi": true, "overrides": [ { "files": "packages/ui/**/*", "options": { "printWidth": 100 } }, { "files": "packages/server/**/*", "options": { "printWidth": 80 } } ]}工具集成1. Turborepo 集成在 turbo.json 中配置:{ "pipeline": { "format": { "outputs": [] } }}在 package.json 中添加脚本:{ "scripts": { "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,md}\"", "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,md}\"" }}2. Nx 集成Nx 提供了专门的 Prettier 支持:{ "targets": { "format": { "executor": "@nx/vite:format", "options": { "write": true } } }}3. Lerna 集成使用 Lerna 的 --scope 选项格式化特定包:lerna exec --scope @my-org/ui -- prettier --write "**/*.js"性能优化1. 增量格式化# 只格式化修改的文件git diff --name-only --diff-filter=ACM | grep '\.js$' | xargs prettier --write2. 并行处理# 使用 GNU parallel 并行格式化find . -name "*.js" | parallel prettier --write3. 缓存机制# 使用 Prettier 缓存prettier --write --cache "**/*.js"CI/CD 集成GitHub Actions 配置:name: Format Checkon: [push, pull_request]jobs: format: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm ci - run: npm run format:check最佳实践1. 配置管理在根目录维护统一的 Prettier 配置使用共享配置包确保一致性定期同步各包的配置2. 依赖管理在根目录安装 Prettier锁定 Prettier 版本使用 workspace 协议管理依赖3. 团队协作在文档中说明 monorepo 的格式化策略提供统一的编辑器配置在 CI 中强制检查格式4. 性能考虑使用缓存提高格式化速度合理配置 .prettierignore只格式化必要的文件通过合理配置,Prettier 可以在 monorepo 项目中有效统一代码风格,提高开发效率。
阅读 0·2月21日 16:56

如何在 CI/CD 流程中集成 Prettier 进行代码格式检查?

Prettier 在 CI/CD 中的集成实践将 Prettier 集成到 CI/CD 流程中可以确保所有提交的代码都符合统一的格式规范,提高代码质量和团队协作效率。Git Hooks 集成使用 Husky 和 lint-staged 在 Git 提交前自动格式化代码:安装依赖 npm install --save-dev husky lint-staged prettier npx husky install npm pkg set scripts.prepare="husky install"配置 lint-staged在 package.json 中添加: { "lint-staged": { "*.{js,jsx,ts,tsx,json,css,scss,md}": [ "prettier --write" ] } }创建 Git Hook npx husky add .husky/pre-commit "npx lint-staged"CI/CD 配置GitHub Actions创建 .github/workflows/prettier.yml:name: Prettier Checkon: [push, pull_request]jobs: prettier: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm install - run: npx prettier --check "**/*.{js,jsx,ts,tsx,json,css,scss,md}"GitLab CI在 .gitlab-ci.yml 中添加:prettier: stage: test script: - npm install - npx prettier --check "**/*.{js,jsx,ts,tsx,json,css,scss,md}" only: - merge_requests - main常用命令格式化文件: npx prettier --write "src/**/*.js"检查格式: npx prettier --check "src/**/*.js"格式化所有文件: npx prettier --write .查看差异: npx prettier --list-different "src/**/*.js"最佳实践团队统一配置: 确保所有开发者使用相同的 Prettier 配置自动化检查: 在 CI/CD 中强制检查代码格式自动修复: 使用 --write 选项自动修复格式问题忽略文件: 合理配置 .prettierignore 避免不必要的格式化版本锁定: 锁定 Prettier 版本确保一致性通过在 CI/CD 中集成 Prettier,可以确保代码库始终保持统一的格式规范,减少代码审查时的格式争议。
阅读 0·2月21日 16:56

Prettier 命令行工具有哪些常用命令和选项?

Prettier 命令行工具详解Prettier 提供了丰富的命令行工具,可以灵活地进行代码格式化、检查和配置管理。基本命令1. 格式化文件# 格式化单个文件prettier --write index.js# 格式化多个文件prettier --write src/**/*.js# 格式化所有支持的文件prettier --write .2. 检查文件格式# 检查文件格式是否正确prettier --check index.js# 检查多个文件prettier --check "src/**/*.{js,jsx,ts,tsx}"# 检查所有文件prettier --check .3. 查看格式化差异# 显示格式化后的差异prettier --diff index.js# 列出需要格式化的文件prettier --list-different "src/**/*.js"常用选项1. 配置相关# 指定配置文件prettier --config .prettierrc.custom --write index.js# 指定忽略文件prettier --ignore-path .prettierignore.custom --write .# 禁用默认忽略prettier --write --ignore-unknown index.js2. 输出控制# 输出到标准输出(不修改文件)prettier index.js# 指定输出目录prettier --out-dir formatted src/**/*.js# 使用缓存prettier --write --cache "src/**/*.js"# 清除缓存prettier --write --cache --cache-strategy content "src/**/*.js"3. 调试相关# 显示调试信息prettier --debug-check index.js# 显示使用的配置prettier --find-config-path index.js# 显示解析器信息prettier --help高级用法1. 与其他工具结合# 与 find 结合使用find src -name "*.js" | xargs prettier --write# 与 git 结合使用git diff --name-only --diff-filter=ACM | grep '\.js$' | xargs prettier --write2. 格式化特定文件类型# 只格式化 JavaScript 文件prettier --write "**/*.js"# 格式化多种文件类型prettier --write "**/*.{js,jsx,ts,tsx,json,css,md}"3. 使用 npx 运行# 使用 npx 运行(无需全局安装)npx prettier --write index.js# 指定版本运行npx prettier@2.8.0 --write index.js实用脚本在 package.json 中添加常用脚本:{ "scripts": { "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"", "format:check": "prettier --check \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"", "format:staged": "lint-staged", "format:all": "prettier --write ." }}常见问题解决1. 文件编码问题# 指定文件编码prettier --write --encoding utf-8 index.js2. 权限问题# 使用 sudo 运行(不推荐)sudo prettier --write index.js3. 性能问题# 使用缓存提高性能prettier --write --cache "**/*.js"掌握 Prettier 命令行工具可以更高效地进行代码格式化管理。
阅读 0·2月21日 16:56

Prettier 与其他代码格式化工具有什么区别?如何选择?

Prettier 与其他代码格式化工具的对比代码格式化工具市场上有多种选择,了解 Prettier 与其他工具的对比有助于选择最适合项目的工具。主要格式化工具对比1. Prettier vs ESLint| 特性 | Prettier | ESLint ||------|----------|--------|| 主要功能 | 代码格式化 | 代码质量检查 || 配置复杂度 | 低(有限选项) | 高(大量规则) || 可扩展性 | 中等 | 高 || 性能 | 快 | 较慢 || 学习曲线 | 低 | 高 |选择建议: 两者结合使用,Prettier 负责格式化,ESLint 负责质量检查。2. Prettier vs Standard.js| 特性 | Prettier | Standard.js ||------|----------|-------------|| 配置灵活性 | 中等 | 低(固定风格) || 零配置 | 支持 | 支持 || 社区活跃度 | 高 | 中等 || 可定制性 | 中等 | 低 |选择建议: Standard.js 适合追求极致零配置的团队,Prettier 适合需要一定灵活性的团队。3. Prettier vs Beautify| 特性 | Prettier | Beautify ||------|----------|----------|| 确定性 | 高 | 低 || AST 解析 | 是 | 否 || 语言支持 | 广泛 | 有限 || 配置选项 | 有限 | 丰富 |选择建议: Prettier 更适合团队协作,Beautify 更适合个人使用。4. Prettier vs Black (Python)| 特性 | Prettier | Black ||------|----------|-------|| 目标语言 | 多语言 | Python || 设计理念 | 代码格式化 | 代码格式化 || 配置选项 | 有限 | 极少 || 社区支持 | 广泛 | Python 社区 |选择建议: Python 项目使用 Black,其他语言使用 Prettier。Prettier 的优势1. 确定性输出相同输入总是产生相同输出避免格式化争议适合团队协作2. 广泛的语言支持支持 JavaScript、TypeScript、CSS、HTML 等通过插件支持更多语言一站式格式化解决方案3. 零配置开箱即用提供合理的默认配置减少配置时间快速上手4. 强大的编辑器集成VS Code、WebStorm 等主流编辑器支持保存时自动格式化实时预览格式化效果Prettier 的局限性1. 配置选项有限无法满足所有个性化需求某些格式无法调整可能与团队习惯不符2. 性能问题大项目中格式化速度较慢内存占用较高需要优化策略3. 版本兼容性不同版本格式化结果可能不同升级需要谨慎团队版本统一困难选择建议使用 Prettier 的场景:多语言项目需要团队协作追求代码风格统一希望零配置快速上手考虑其他工具的场景:单一语言项目(如 Python 使用 Black)需要高度定制化个人项目特定框架的格式化需求最佳实践1. 工具组合Prettier + ESLint: 格式化 + 质量检查Prettier + Stylelint: CSS 格式化 + 检查Prettier + Husky: 自动化工作流2. 团队决策评估团队需求考虑项目特点进行工具试用制定使用规范3. 持续优化定期评估工具效果收集团队反馈调整配置策略关注工具更新通过合理选择和组合代码格式化工具,可以显著提高开发效率和代码质量。
阅读 0·2月21日 16:56

Prettier 与 ESLint 的区别是什么?如何协作使用?

Prettier 与 ESLint 的区别和协作Prettier 和 ESLint 是前端开发中常用的两个工具,它们有不同的职责定位,但可以很好地协作使用。主要区别Prettier(代码格式化工具)专注于代码格式化,统一代码风格不进行代码质量检查强制使用统一的代码风格,减少团队争议通过解析 AST 重新生成代码配置选项相对有限,避免过度配置ESLint(代码质量检查工具)专注于代码质量检查和潜在问题发现检查代码错误、最佳实践、代码风格提供大量的规则配置可以自定义规则和插件支持自动修复部分问题协作使用在实际项目中,通常会将 Prettier 和 ESLint 结合使用:安装依赖 npm install --save-dev prettier eslint eslint-config-prettier eslint-plugin-prettier配置 ESLint在 .eslintrc.js 中配置: { "extends": [ "eslint:recommended", "plugin:prettier/recommended" ] }配置 Prettier创建 .prettierrc 文件: { "semi": true, "singleQuote": true, "tabWidth": 2 }配置冲突解决使用 eslint-config-prettier 可以禁用所有与 Prettier 冲突的 ESLint 规则,避免重复配置和冲突。最佳实践在团队中统一使用 Prettier 进行代码格式化使用 ESLint 进行代码质量检查在 CI/CD 流程中同时运行两者在编辑器中配置自动格式化和保存时格式化通过合理配置,Prettier 和 ESLint 可以完美协作,既保证代码风格统一,又确保代码质量。
阅读 0·2月21日 16:56

Prettier 支持哪些配置文件格式?如何配置 Prettier?

Prettier 配置文件详解Prettier 支持多种配置文件格式,开发者可以根据项目需求选择合适的配置方式。配置文件类型.prettierrc - JSON 格式配置文件 { "semi": true, "singleQuote": true, "tabWidth": 2, "trailingComma": "es5" }.prettierrc.json - 显式 JSON 格式 { "printWidth": 80, "tabWidth": 2, "useTabs": false }.prettierrc.js - JavaScript 格式,支持动态配置 module.exports = { semi: true, singleQuote: true, tabWidth: 2, };.prettierrc.cjs - CommonJS 格式 module.exports = { semi: true, singleQuote: true, };prettier.config.js - 项目根目录的配置文件 export default { semi: true, singleQuote: true, };package.json - 在 package.json 中配置 { "prettier": { "semi": true, "singleQuote": true } }常用配置选项printWidth: 指定行宽,默认 80tabWidth: 指定缩进空格数,默认 2useTabs: 是否使用 tab 缩进,默认 falsesemi: 是否在语句末尾添加分号,默认 truesingleQuote: 是否使用单引号,默认 falsetrailingComma: 是否添加尾随逗号,可选 "es5"、"none"、"all"bracketSpacing: 对象字面量括号内是否添加空格,默认 truearrowParens: 箭头函数参数是否使用括号,可选 "always"、"avoid"配置优先级Prettier 会按照以下顺序查找配置文件:package.json 中的 prettier 字段.prettierrc (JSON/YAML).prettierrc.json.prettierrc.yaml.prettierrc.yml.prettierrc.js.prettierrc.cjsprettier.config.jsprettier.config.cjs忽略配置创建 .prettierignore 文件来指定不需要格式化的文件或目录:node_modulesdistbuild*.min.js合理配置 Prettier 可以让团队代码风格保持一致,提高代码可读性和维护性。
阅读 0·2月21日 16:56

Prettier 的缓存机制是如何工作的?如何使用缓存提高性能?

Prettier 的缓存机制详解Prettier 2.0+ 版本引入了内置缓存机制,可以显著提高重复格式化的性能,特别是在大型项目中。缓存机制原理Prettier 的缓存基于文件内容和配置的哈希值:首次格式化: 解析文件并格式化,将结果存储在缓存中后续格式化: 比较文件内容和配置的哈希值缓存命中: 如果哈希值相同,直接使用缓存结果缓存未命中: 重新格式化文件并更新缓存使用缓存基本用法:# 启用缓存格式化prettier --write --cache "**/*.js"# 指定缓存目录prettier --write --cache --cache-location .prettier-cache "**/*.js"缓存策略:# 基于内容的缓存(默认)prettier --write --cache --cache-strategy content "**/*.js"# 基于元数据的缓存prettier --write --cache --cache-strategy metadata "**/*.js"缓存配置选项1. cache-location指定缓存文件存储位置:# 默认位置prettier --write --cache "**/*.js"# 自定义位置prettier --write --cache --cache-location .my-cache "**/*.js"# 使用相对路径prettier --write --cache --cache-location node_modules/.cache/prettier "**/*.js"2. cache-strategy选择缓存策略:content: 基于文件内容(默认,更准确但稍慢)metadata: 基于文件元数据(更快但可能不准确)3. 清除缓存# 清除缓存并重新格式化prettier --write --cache --cache-strategy content "**/*.js"# 手动删除缓存目录rm -rf .prettier-cache缓存最佳实践1. CI/CD 环境# GitHub Actions- name: Format with cache run: | prettier --write --cache "**/*.js" # 缓存目录会被自动保存和恢复2. 本地开发# 在 package.json 中配置{ "scripts": { "format": "prettier --write --cache \"src/**/*.js\"", "format:check": "prettier --check --cache \"src/**/*.js\"" }}3. Git Hooks// .husky/pre-commit{ "lint-staged": { "*.{js,jsx,ts,tsx}": [ "prettier --write --cache" ] }}性能对比不使用缓存:# 首次格式化 1000 个文件time prettier --write "**/*.js"# 实际执行: ~5s使用缓存:# 首次格式化 1000 个文件time prettier --write --cache "**/*.js"# 实际执行: ~5s# 第二次格式化(无变化)time prettier --write --cache "**/*.js"# 实际执行: ~0.5s (10x 提升)缓存注意事项1. 配置变更修改 Prettier 配置会自动使缓存失效确保配置文件在版本控制中团队成员使用相同配置2. 文件变更文件内容变化会自动更新缓存删除文件会清理对应缓存重命名文件会重新生成缓存3. 缓存管理定期清理缓存目录在 CI 中缓存 .prettier-cache 目录监控缓存大小故障排查缓存不生效:# 检查缓存目录ls -la .prettier-cache# 清除缓存重新格式化rm -rf .prettier-cacheprettier --write --cache "**/*.js"缓存过大:# 检查缓存大小du -sh .prettier-cache# 清理旧缓存find .prettier-cache -type f -mtime +7 -delete通过合理使用 Prettier 缓存机制,可以显著提高格式化性能,特别是在大型项目中。
阅读 0·2月21日 16:56

如何管理 Prettier 的版本?有哪些升级策略?

Prettier 的版本管理和升级策略Prettier 的版本管理对于保持团队代码风格一致性和利用新功能非常重要。合理的版本管理策略可以避免格式化冲突和团队协作问题。版本锁定1. 在 package.json 中锁定版本{ "devDependencies": { "prettier": "^2.8.0" }}2. 使用精确版本号{ "devDependencies": { "prettier": "2.8.0" }}3. 使用 engines 字段{ "engines": { "node": ">=16.0.0", "npm": ">=8.0.0" }, "devDependencies": { "prettier": "^2.8.0" }}版本升级策略1. 小版本升级 (Patch)# 升级到最新的补丁版本npm update prettier# 或者使用精确版本npm install --save-dev prettier@2.8.12. 次版本升级 (Minor)# 升级到最新的次版本npm install --save-dev prettier@2.9.0# 检查变更日志npm view prettier versions3. 主版本升级 (Major)# 升级到新的主版本(谨慎操作)npm install --save-dev prettier@3.0.0# 查看升级指南# https://prettier.io/docs/en/next/install.html升级前的准备1. 检查变更日志# 查看版本变更npm view prettier versions --json# 查看特定版本的变更npm view prettier@2.8.02. 备份当前配置# 备份配置文件cp .prettierrc .prettierrc.backupcp .prettierignore .prettierignore.backup3. 创建测试分支# 创建升级测试分支git checkout -b upgrade/prettier-2.8.0# 安装新版本npm install --save-dev prettier@2.8.0升级验证1. 检查格式化差异# 查看格式化差异prettier --check "**/*.{js,jsx,ts,tsx,json,css,md}"# 查看具体差异prettier --list-different "**/*.{js,jsx,ts,tsx,json,css,md}"2. 测试格式化# 在测试文件上测试格式化prettier --write test/**/*.js# 比较格式化前后的差异git diff test/3. CI/CD 验证# 在 CI 中验证新版本- name: Test Prettier upgrade run: | npm install --save-dev prettier@2.8.0 npm run format:check回滚策略1. 快速回滚# 回滚到之前的版本npm install --save-dev prettier@2.7.1# 恢复配置文件cp .prettierrc.backup .prettierrc2. Git 回滚# 回滚 package.jsongit checkout HEAD -- package.json package-lock.json# 重新安装依赖npm ci3. 分支管理# 删除升级分支git branch -D upgrade/prettier-2.8.0# 切换回主分支git checkout main团队协作1. 版本统一在 package.json 中锁定版本使用 npm ci 确保依赖一致在 CI 中使用固定版本2. 文档更新在 README 中记录 Prettier 版本更新升级指南通知团队成员版本变更3. 沟通机制在团队会议中讨论升级计划在 PR 中说明版本变更原因提供升级支持最佳实践1. 定期评估每季度评估一次升级关注新功能和修复评估升级风险2. 渐进式升级先在个人项目中测试在小范围团队中试用逐步推广到整个团队3. 自动化检查在 CI 中检查版本一致性使用 Dependabot 自动更新设置版本更新通知4. 记录变更维护版本变更日志记录升级过程中的问题分享升级经验通过合理的版本管理和升级策略,可以确保团队使用一致的 Prettier 版本,避免格式化冲突,提高开发效率。
阅读 0·2月21日 16:56

Prettier 支持哪些插件?如何开发自定义 Prettier 插件?

Prettier 的插件系统和扩展机制Prettier 本身提供了丰富的语言支持,同时也支持通过插件系统扩展其功能,满足特定项目或语言的格式化需求。插件类型1. 语言解析器插件为 Prettier 添加对新语言的支持,例如:@prettier/plugin-php - PHP 语言支持@prettier/plugin-pug - Pug 模板语言支持@prettier/plugin-ruby - Ruby 语言支持@prettier/plugin-swift - Swift 语言支持2. 格式化增强插件扩展现有语言的格式化能力,例如:prettier-plugin-organize-imports - 自动组织 import 语句prettier-plugin-sort-json - 对 JSON 键进行排序prettier-plugin-packagejson - 格式化 package.json 文件插件安装和使用1. 安装插件# 安装 PHP 插件npm install --save-dev @prettier/plugin-php# 安装 import 组织插件npm install --save-dev prettier-plugin-organize-imports2. 配置插件在 .prettierrc 中配置:{ "plugins": [ "@prettier/plugin-php", "prettier-plugin-organize-imports" ]}3. 使用插件格式化# 格式化 PHP 文件prettier --write index.php# 格式化 JavaScript 文件(会自动组织 import)prettier --write index.js自定义插件开发1. 插件结构// my-prettier-plugin/index.jsmodule.exports = { languages: [ { name: "MyLanguage", parsers: ["my-parser"], extensions: [".mylang"], }, ], parsers: { "my-parser": { parse: (text, parsers, options) => { // 解析代码为 AST }, astFormat: "my-ast", }, }, printers: { "my-ast": { print: (path, options, print) => { // 将 AST 转换为格式化后的代码 }, }, },};2. 插件配置{ "plugins": ["./my-prettier-plugin"]}常用插件推荐1. 代码组织类prettier-plugin-organize-imports - 自动组织和排序 importprettier-plugin-sort-imports - 排序 import 语句2. 特定语言类@prettier/plugin-php - PHP 格式化@prettier/plugin-pug - Pug 模板格式化@prettier/plugin-ruby - Ruby 格式化3. 文件增强类prettier-plugin-packagejson - 优化 package.json 格式prettier-plugin-sort-json - 排序 JSON 键4. 框架特定类prettier-plugin-tailwindcss - Tailwind CSS 类名排序prettier-plugin-astro - Astro 框架支持插件最佳实践1. 选择合适的插件评估插件的维护状态和社区活跃度测试插件对项目代码的影响考虑插件与现有工具的兼容性2. 版本管理锁定插件版本避免意外变更定期更新插件以获取最新功能和修复记录插件版本变更3. 性能考虑避免安装过多插件影响性能使用缓存机制提高格式化速度在 CI 中测试插件性能影响4. 团队协作在文档中说明使用的插件确保团队成员安装相同的插件在 CI 中验证插件配置通过合理使用 Prettier 插件,可以扩展其功能,满足各种项目的格式化需求。
阅读 0·2月21日 16:56