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

面试题手册

Nginx 如何实现缓存?如何配置缓存策略?

Nginx 如何实现缓存?如何配置缓存策略?Nginx 提供了强大的缓存功能,可以缓存后端服务器的响应,减轻后端负载,提高响应速度。Nginx 支持代理缓存和 FastCGI 缓存等多种缓存方式。代理缓存配置:http { # 定义缓存路径和参数 proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=proxy_cache:10m max_size=1g inactive=60m use_temp_path=off; server { listen 80; server_name example.com; location / { proxy_cache proxy_cache; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_bypass $http_cache_control; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }}缓存参数说明:proxycachepath:定义缓存存储路径和参数levels:缓存目录层级结构keys_zone:共享内存区域名称和大小max_size:缓存最大大小inactive:缓存项不活动时间use_temp_path:是否使用临时路径proxy_cache:指定使用的缓存区域proxycachevalid:设置不同状态码的缓存时间200 302 10m:200 和 302 状态码缓存 10 分钟404 1m:404 状态码缓存 1 分钟proxycachekey:定义缓存键proxycachebypass:绕过缓存的条件FastCGI 缓存配置:http { fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi_cache:10m max_size=1g inactive=60m; server { listen 80; server_name example.com; location ~ \.php$ { fastcgi_cache fastcgi_cache; fastcgi_cache_valid 200 60m; fastcgi_cache_methods GET HEAD; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; add_header X-Cache-Status $upstream_cache_status; fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; } }}缓存清除:Nginx 开源版本不支持主动缓存清除,可以通过以下方式实现:设置缓存过期时间:通过 proxy_cache_valid 控制使用第三方模块:如 ngxcachepurge手动删除缓存文件:根据缓存键删除对应文件缓存策略配置:# 根据请求方法缓存proxy_cache_methods GET HEAD;# 根据响应头缓存proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;# 缓存最小请求次数proxy_cache_min_uses 2;# 缓存锁定,防止缓存风暴proxy_cache_lock on;proxy_cache_lock_timeout 5s;# 缓存背景更新proxy_cache_background_update on;proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;动态缓存控制:# 根据条件决定是否缓存map $request_uri $skip_cache { default 0; ~*/admin/ 1; ~*/api/ 1;}# 根据响应头决定是否缓存map $upstream_http_cache_control $skip_cache { ~*no-cache 1; ~*private 1; default 0;}静态文件缓存:location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off;}缓存状态监控:add_header X-Cache-Status $upstream_cache_status;# 缓存状态值:# MISS - 未命中缓存# BYPASS - 绕过缓存# EXPIRED - 缓存过期# STALE - 使用过期缓存# UPDATING - 缓存更新中# HIT - 命中缓存缓存优化建议:合理设置缓存时间,平衡新鲜度和性能使用缓存键包含必要参数,避免缓存冲突对动态内容禁用缓存定期清理过期缓存监控缓存命中率,调整缓存策略使用缓存锁定防止缓存风暴对静态资源使用浏览器缓存完整配置示例:http { # 代理缓存 proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=proxy_cache:100m max_size=10g inactive=60m use_temp_path=off; # FastCGI 缓存 fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi_cache:100m max_size=10g inactive=60m; # 缓存跳过条件 map $request_uri $skip_cache { default 0; ~*/admin/ 1; ~*/api/ 1; ~*/user/ 1; } server { listen 80; server_name example.com; # 静态文件 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } # 动态内容代理 location / { proxy_cache proxy_cache; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_bypass $skip_cache; proxy_no_cache $skip_cache; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; } # PHP 文件 location ~ \.php$ { fastcgi_cache fastcgi_cache; fastcgi_cache_valid 200 60m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; add_header X-Cache-Status $upstream_cache_status; fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; } }}
阅读 0·2月21日 16:57

如何在 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

Nginx 的 location 指令如何匹配?优先级是什么?

Nginx 的 location 指令如何匹配?优先级是什么?Nginx 的 location 指令用于匹配请求的 URI,并定义如何处理这些请求。理解 location 的匹配规则和优先级对于正确配置 Nginx 至关重要。Location 匹配规则:1. 精确匹配(=)使用 = 进行精确匹配,如果匹配成功,立即停止搜索并使用该 location。location = /exact { # 精确匹配 /exact}2. 前缀匹配(无修饰符)不使用任何修饰符,按前缀匹配,匹配成功后继续搜索更精确的匹配。location /prefix { # 匹配以 /prefix 开头的 URI}3. 正则匹配(~ 和 ~*)~:区分大小写的正则匹配~*:不区分大小写的正则匹配location ~ \.php$ { # 匹配以 .php 结尾的 URI(区分大小写)}location ~* \.(jpg|jpeg|png|gif)$ { # 匹配图片文件(不区分大小写)}4. 前缀匹配(^~)使用 ^~ 进行前缀匹配,如果匹配成功,立即停止搜索,不再检查正则表达式。location ^~ /static/ { # 匹配以 /static/ 开头的 URI,不再检查正则}匹配优先级(从高到低):精确匹配(=):优先级最高前缀匹配(^~):如果匹配成功,停止搜索正则匹配(~ 和 ~*):按配置顺序依次检查前缀匹配(无修饰符):优先级最低匹配示例:server { listen 80; server_name example.com; # 1. 精确匹配 location = / { return 200 "Exact match /"; } # 2. ^~ 前缀匹配 location ^~ /images/ { return 200 "Prefix match ^~ /images/"; } # 3. 正则匹配(区分大小写) location ~ \.php$ { return 200 "Regex match .php"; } # 4. 正则匹配(不区分大小写) location ~* \.(jpg|jpeg|png|gif)$ { return 200 "Regex match images"; } # 5. 普通前缀匹配 location / { return 200 "Prefix match /"; }}实际匹配结果:请求 / → 精确匹配 location = /请求 /images/logo.jpg → location ^~ /images/(停止搜索,不匹配正则)请求 /test.php → location ~ \.php$请求 /photo.JPG → location ~* \.(jpg|jpeg|png|gif)$(不区分大小写)请求 /other → location /嵌套 Location:location /api/ { # 外层 location proxy_pass http://backend; location /api/v1/ { # 内层 location,继承外层配置 proxy_pass http://backend_v1; }}使用建议:将精确匹配放在最前面将正则匹配放在中间将普通前缀匹配放在最后使用 ^~ 避免不必要的正则匹配合理使用正则匹配,避免过度使用影响性能性能考虑:精确匹配和 ^~ 匹配性能最好正则匹配需要编译和执行,性能相对较低避免使用复杂的正则表达式正则匹配按配置顺序执行,将常用匹配放在前面实际应用场景:# 静态文件缓存location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable";}# PHP 文件处理location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; include fastcgi_params;}# API 请求代理location /api/ { proxy_pass http://api_backend;}# 管理后台location ^~ /admin/ { auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://admin_backend;}
阅读 0·2月21日 16:56

Nginx 如何配置虚拟主机?有哪些配置方式?

Nginx 如何配置虚拟主机?有哪些配置方式?Nginx 虚拟主机(Virtual Host)允许在同一台服务器上运行多个网站,通过不同的域名、端口或 IP 地址来区分不同的站点。基于域名的虚拟主机:server { listen 80; server_name example.com www.example.com; root /var/www/example.com; index index.html index.php; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; location / { try_files $uri $uri/ =404; }}server { listen 80; server_name test.com www.test.com; root /var/www/test.com; index index.html index.php; access_log /var/log/nginx/test.com.access.log; error_log /var/log/nginx/test.com.error.log; location / { try_files $uri $uri/ =404; }}基于端口的虚拟主机:server { listen 80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 8080; server_name example.com; root /var/www/example.com/admin; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 8443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; root /var/www/example.com/secure; index index.html; location / { try_files $uri $uri/ =404; }}基于 IP 地址的虚拟主机:server { listen 192.168.1.100:80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 192.168.1.101:80; server_name example.com; root /var/www/example.com/mirror; index index.html; location / { try_files $uri $uri/ =404; }}通配符域名:# 匹配所有子域名server { listen 80; server_name *.example.com; root /var/www/subdomains; index index.html; location / { # 使用子域名作为目录名 set $subdomain $host; if ($subdomain ~* ^(.*)\.example\.com$) { set $subdomain $1; } root /var/www/subdomains/$subdomain; }}# 匹配所有域名(默认虚拟主机)server { listen 80 default_server; server_name _; root /var/www/default; index index.html; location / { return 404; }}正则表达式域名:server { listen 80; server_name ~^(?<subdomain>.+)\.example\.com$; root /var/www/example.com/$subdomain; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 80; server_name ~^(?<user>.+)\.users\.example\.com$; root /var/www/users/$user; index index.html; location / { try_files $uri $uri/ =404; }}HTTPS 虚拟主机:server { listen 80; server_name example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri;}server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}多域名共享配置:# 定义共享配置map $host $root_path { example.com /var/www/example.com; test.com /var/www/test.com; default /var/www/default;}server { listen 80; server_name example.com test.com; root $root_path; index index.html; location / { try_files $uri $uri/ =404; }}反向代理虚拟主机:upstream backend1 { server 192.168.1.100:8080; server 192.168.1.101:8080;}upstream backend2 { server 192.168.1.200:8080; server 192.168.1.201:8080;}server { listen 80; server_name api.example.com; location / { proxy_pass http://backend1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}server { listen 80; server_name admin.example.com; location / { proxy_pass http://backend2; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}PHP 虚拟主机:server { listen 80; server_name example.com; root /var/www/example.com; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }}静态站点虚拟主机:server { listen 80; server_name static.example.com; root /var/www/static; index index.html; # 启用 Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; # 静态资源缓存 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } location / { try_files $uri $uri/ =404; }}虚拟主机配置文件分离:# /etc/nginx/nginx.confhttp { include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;}# /etc/nginx/sites-available/example.comserver { listen 80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}# 创建符号链接启用站点# ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com虚拟主机最佳实践:配置文件分离:每个虚拟主机使用独立的配置文件命名规范:使用域名作为配置文件名日志分离:每个虚拟主机使用独立的日志文件默认主机:配置 default_server 处理未知请求SSL 配置:所有生产环境使用 HTTPS错误页面:为每个虚拟主机配置自定义错误页面安全头:添加安全相关的 HTTP 头性能优化:启用 Gzip 压缩和缓存完整虚拟主机配置示例:# /etc/nginx/sites-available/example.comserver { listen 80; server_name example.com www.example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri;}server { listen 443 ssl http2; server_name example.com www.example.com; # SSL 配置 ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 根目录 root /var/www/example.com; index index.php index.html; # 日志 access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; # 安全头 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; # 静态资源 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # PHP 处理 location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # 主路由 location / { try_files $uri $uri/ /index.php?$query_string; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; }}
阅读 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