如何配置Prettier让React组件中Hook按指定规则排序?
问题描述
我正在使用VSCode,当前的prettier.config.js配置如下:
// prettier.config.js module.exports = { plugins: [require("prettier-plugin-tailwindcss")], printWidth: 80, tabWidth: 4, trailingComma: "all", singleQuote: true, semi: true, importOrder: ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"], importOrderSeparation: true, importOrderSortSpecifiers: true, };
我的React组件代码片段如下:
... import TextField from '@mui/material/TextField'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import * as yup from 'yup'; function ItemLinkScreen(props) { const router = useRouter(); const { 'space-slug': spaceSlug, 'section-slug': sectionSlug } = router.query; const { mutate } = useSpace(spaceSlug); const [url, setUrl] = useState(null); const [framelyResponse, setFramelyResponse] = useState(null); const [framelyError, setFramelyError] = useState(null); const [dialogOpened, setDialogOpened] = useState(false); const schema = yup.object({ name: yup.string().min(3).max(255).required(), }); const { register, reset, formState: { errors }, setFocus, handleSubmit, control, } = useForm({ resolver: yupResolver(schema) }); const [apiErrors, setApiErrors] = useState([]); const onSubmit = async (data) => { }; useEffect(() => { setFocus('name'); }, [dialogOpened]); return ( ); } export default ItemLinkScreen;
当前组件里useState分散在代码中间,我希望通过Prettier配置实现以下代码排序规则:
useRouter置于组件最顶部- 所有
useState集中在组件开头 useEffect放在return语句之前
请问该如何配置Prettier满足需求?
解决方案
要实现自定义的React Hooks排序,需要用到@trivago/prettier-plugin-sort-imports插件(该插件与你当前使用的prettier-plugin-tailwindcss兼容,但需调整插件顺序),并添加自定义的hooks排序规则。
步骤1:安装依赖
在项目中安装@trivago/prettier-plugin-sort-imports:
npm install @trivago/prettier-plugin-sort-imports --save-dev # 或 yarn add @trivago/prettier-plugin-sort-imports --dev
步骤2:修改Prettier配置
更新prettier.config.js,添加hooks排序相关配置,同时注意插件顺序(prettier-plugin-tailwindcss要放在最后):
// prettier.config.js module.exports = { plugins: [ require("@trivago/prettier-plugin-sort-imports"), require("prettier-plugin-tailwindcss"), ], printWidth: 80, tabWidth: 4, trailingComma: "all", singleQuote: true, semi: true, // 保留原有导入排序配置 importOrder: ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"], importOrderSeparation: true, importOrderSortSpecifiers: true, // 添加自定义hooks与变量排序规则 customOrder: [ // 第一组:useRouter声明 "^const router = useRouter\\(\\)$", // 第二组:所有useState声明 "^const \\[.*\\] = useState\\(.*\\)$", // 第三组:其他自定义/第三方hooks(如useSpace、useForm) "^const .* = use.*\\(.*\\)$", // 第四组:普通变量定义(如schema) "^const .* = .*$", // 第五组:函数定义(如onSubmit) "^const .* = async? \\(.*\\) =>$", "^function .*\\(.*\\)$", // 第六组:useEffect声明(放在return前) "^useEffect\\(.*\\)$", ], customOrderSeparation: true, };
配置说明
customOrder:通过正则表达式定义变量和hooks的排序优先级,完全匹配你需要的结构顺序customOrderSeparation:开启后,每组规则之间会自动添加空行,让代码结构更清晰- 插件顺序:
@trivago/prettier-plugin-sort-imports必须放在prettier-plugin-tailwindcss之前,避免样式类排序出现异常
效果验证
配置完成后,保存组件代码时,Prettier会自动将代码调整为目标结构:
function ItemLinkScreen(props) { // 最顶部:useRouter const router = useRouter(); const { 'space-slug': spaceSlug, 'section-slug': sectionSlug } = router.query; // 集中的useState const [url, setUrl] = useState(null); const [framelyResponse, setFramelyResponse] = useState(null); const [framelyError, setFramelyError] = useState(null); const [dialogOpened, setDialogOpened] = useState(false); const [apiErrors, setApiErrors] = useState([]); // 其他hooks const { mutate } = useSpace(spaceSlug); const { register, reset, formState: { errors }, setFocus, handleSubmit, control, } = useForm({ resolver: yupResolver(schema) }); // 普通变量 const schema = yup.object({ name: yup.string().min(3).max(255).required(), }); // 函数定义 const onSubmit = async (data) => { }; // useEffect放在return之前 useEffect(() => { setFocus('name'); }, [dialogOpened]); return ( ); }
内容的提问来源于stack exchange,提问作者Ali Gajani
相关产品推荐
相关产品推荐

