🐫PascalCase 文件命名的缺点
PascalCase – 大驼峰命名,过去一直是比较主流的文件命名风格,组件函数命名为PascalCase,为了保持统一往往将组件的文件也命名为PascalCase,同理,class类也会命名为PascalCase,这是一个很简单直白的逻辑 – 即任何模块名为大写开头的其文件名也大写开头。
如果我们去Google搜索一下关键词 react file name convention
,几乎清一色的采用PascalCase,如下链接
www.joshwcomeau.com/react/file-…
但是接下来我要讨论的是这种文件命名的问题
🐫PascalCase, 🐪camel-case 混用导致不一致
PascalCase 大驼峰, CamelCase小驼峰,🍡KebabCase 烤肉串
这是一个很常见的示例,如头图一样
- 组件: Button.jsx
- class类: UserModel.js
- util方法函数: random.js
- api接口函数: getUser.js
- 一些配置文件: pnpm-lock.yaml
如上,我们从中看到了至少3种命名风格,Pascal + Camel + Kebab,这样会导致视觉一致性问题,在阅读时并不轻松,起名字时还要先想想模块是组件 还是类 还是方法函数。
git 文件大小写不明感问题
如果你不小心将 Button.jsx
改成了 button.jsx
,此时你的系统文件名和git库中的文件名就不一致了,应该很多同学遇到类似的困扰。
当然也有不优雅的解决办法,配置git config设置忽略大小写为false
git config core.ignorecase false
不优雅的原因: stackoverflow.com/questions/5…
优雅的解决办法应该是
git mv button.jsx _button.jsx
git mv _button.jsx Button.jsx
(我怎么写着写着跑题了?) 没关系,额外送点私货没关系😝。回归正题,出现文件大小写错误的根源是人的犯错,只要有大小写混用的情况就一定难以避免,所以如果我们统一规范文件名不能大写开头就能很大程度避免了。
大写锁定键坏了!
如果你的大写锁定键坏了,很显然,你想用Pascal命名都用不了,不仅如此,组件模块的名称也无法大写命名,export function button...
,eslint会报错,react debug会报错
开个玩笑而已。。
热门开源项目是怎么命名的?
Nextjs
nextjs源码中 全部采用了Kebab烤肉串命名风格。
NextUI
nextui同样全部采用了Kebab烤肉串命名风格。
Tailwindcss
烤肉串
bulletproof-react
烤肉串
shadcn-ui
烤肉串
nestjs
烤肉串
🍡Kebab烤肉串风格好在哪里
上面的例子我不是故意挑kebab风格的项目来举例的,react vue依然采用的Pascal风格,或许对于老项目(建立较早)考虑到成本没有迁移到kebab的必要,但是新兴的项目可以看到是清一色的kebab。
那么kebab的风格好在哪里呢?我从bulletproof-react中找到了答案
这可以帮助您保持代码库的一致性并更易于导航。 确实,烤肉串的易读性更好,也更方便对文件的视觉索引,在vscode中cmd+p搜索文件能更有利于首字母模糊查找。
便于在配置文件中匹配规则。例如,在eslintrc中,我们经常需要配置files
字段,来让匹配的文件lint,如果是烤肉串命名,我们能更轻松的匹配文件 files: ['src/**/*-route.jsx']
。babelrc, jestconfig,tsconfig,viteconfig等等同样受益。
与模块区分后方便symbol检索。全局搜索Symbol时,能清晰的区分模块名和文件名
制定规范
文件名与模块名风格无关
让模块名遵从js或ts语法或框架本身,让文件名与模块名无关 (注意是风格无关)
user-model.js
class User {
username = ''
age = ''
role = ''
};
export function createAdminUser(username, age) {
return new User(username, age, 'admin')
};
上面示例中,有一个User
类,导出了createAdminUser
工厂方法。如果使用Pascal命名风格UserModel.js
似乎不太合适,因为虽然内容是和User
用户模型强相关但实际导出的模块却是工厂函数。使用烤肉串之后不再纠结,即使未来我们将User
也导出,命名也符合规范。
button-group.jsx
同理
export function useButtonGroup() {
...
};
export function ButtonGroup() {
...
};
文件名小写,单词以-
隔开,允许中间名
components
└── button-group
├── button-group.jsx
├── button-group.constants.js
└── button-group.stories.js
components
└── button-group
├── button-group.jsx
├── hooks
│ └── use-button-group.js
├── utils
│ └── format-button-group.js
└── stories
└── ...
.gitignore
.prettier.config.js
.prettierrc
.prettierignore
commit-lint.config.js
.commitlintrc
.eslintrc
eslint.config.mjs
pnpm-workspace.yaml
docker-compose.yaml
注意,不要照抄作业,以上示例只是表达风格规范,具体目录&组件的划分和语义范围请根据各自实际情况自由发挥。
什么时候应该使用中间名?
当一个文件包含多个功能时,使用中间名可以清晰地区分不同功能模块。例如:
user.service.js
:表示一个用户的服务模块。user.route.js
用户的路由模块。可以简单的理解为 我们把一个庞大的 user.js
文件按模块的方式 拆成了多个文件,和vue sfc类似,但并不要求一个文件只能导出一个模块。
命名空间冲突:当引入多个库或组件时,中间名可以避免命名冲突。例如:
jquery.min.js
什么时候不应该使用中间名?
简单文件:
对于非常简单的文件,包含单个函数或变量的文件,例如sum.js
可以省略中间名。
不一致的命名风格:
项目中应保持一致的命名风格, 并提前预设好常用的中间名,避免随意添加中间名。例如 app.hualihushao.js
是不允许的。
目录名同样小写,单词以-
隔开,没有中间名
features/
└── xitu-juejin/
允许草稿文件 __draft.js
__
两个下划线开头的文件表示为草稿文件,不被任何其他文件或模块引用,一般为临时文件或者作废的旧版文件,不参与编译。允许草稿文件自由命名。
__app.draft.js
__app.v0.1.js
__app-v0.1-deprecated.js
__DEPRECATED_app.js
或参考Angular风格 (9.15补充)
感谢评论区 @CrimsonHu 分享
Angular在风格偏好方面制定的非常规范,项目结构、文件命名、模块命名、commit提交等规范应有尽有,并且辐射到各个框架的偏好中,如果懒得自己制定规范的同学可以直接参考Angular风格。
示例截图
使用eslint强制校验文件名
现在我们要求所有文件名都应是烤肉串之后,就能够定义eslint来校验文件名了,这样永久避免git文件名大小写错误。
安装 eslint-plugin-check-file
pnpm add eslint-plugin-check-file -D
配置 eslint.config.mjs
export default [
...,
{
plugins: {
"check-file": checkFile,
},
rules: {
"check-file/filename-naming-convention": [
"error",
{ "**/!(__)*": "KEBAB_CASE" },
{ ignoreMiddleExtensions: true },
],
"check-file/folder-naming-convention": [
"error",
{ "**/!(__tests__)": "KEBAB_CASE" },
],
},
},
]
规则说明详见 github.com/dukeluo/esl…
上述配置将所有文件名强制要求KEBAB_CASE(“__”开头的除外),将目录名也强制KEBAB_CASE(“__tests__”除外)。不要照抄作业,根据理解可以自己定义需要匹配校验的文件
答应我,从此以后 All in Kebab,好吗?
pnpm add ts-node
package-lock.json
primary-button.jsx
primary-button.test.jsx
random.js
get-one-user.js
find-users.js
data-model.js
app.constants.js
.flex-box { display: flex; }
global-style.css
www.some-web.com/users/1-2/user-info
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21213,转载请注明出处。
评论0