Skip to content

命名规范

项目已集成eslint检查语法和规则错误。同时code spell checker查询拼写错误。

VSCode已集成插件,所以在VSCode中会标出错误的地方。提交MR之前请修复标出的错误。

MR提交的标准:

  1. 没有eslint报错
  2. 没有code spell checker报错

URL命名

  1. 前后端的URL分用户端和管理端,

    后端管理端的API是/admin开头,用户端没有/admin:

    • 后端用户端: /api/v5/location-groups
    • 后端管理端: /api/v5/admin/location-groups

    前端管理端的页面是/admin开头,用户端/user:

    • 前端用户端: /user/location-groups
    • 前端管理端: /admin/location-groups
  2. URL的path采用name-name(snake)方式命名,多个单词用hyphen(-)隔开:

    ts
    @Get('/all-users')
    async findAllUsers() {
      ...
    }
  3. 路径的命名和目录结构保持一致:

    目录结构:
    - admin
      - users
        - AllUsers.tsx

    对应的URL: /api/v5/admin/users/all-users

目录结构

  - [前端目录结构](../../frontend/docs/project-structure.md)
  - [后端目录结构](../../server/docs/architecture.md)

  页面命名方式

  列表页面 [模块名]List.tsx
  详情页面 [模块名]Info.tsx
  表单页面 [模块名]FormModal.tsx

  模块名规范:<https://ao5vs9kqus.feishu.cn/wiki/MiNlwameziCYyKkdBiPctwHLnQg>

  目录结构

  ```
  - deliveries
    - components
      - DeliveryNameModal.tsx
      - DeliveryTag.tsx
    - deliveryCategories // 附属模块
      - components
        - DeliveryCategoryName.tsx
      - DeliveryCategoryList.tsx
      - DeliveryCategoryInfo.tsx
      - DeliveryCategoryFormModal.tsx
    - DeliveryList.tsx
    - DeliveryInfo.tsx
    - DeliveryFormModal.tsx
    - DeliveryPage.tsx // 入口
  ```

组件命名

  • 组件名称和文件名称一致
  • 一个文件只export一个组件
  • 所有的Modal都用NiceModal.create:
  • 参数采用props; 如props: EditUserModalProps 需要定义interface: interface EditUserModalProps { record?: UserBookEntity }

函数命名

  • camelCase

参数命名

  • camelCase

事件处理函数

  • onXXX

文件命名

  • 文件名采用camelCase命名:如locationGroup.ts
  • 唯一例外是React组件,采用PascalCase: 如KBSelectUser.tsx
  • index.ts, index.tsx 用于export,不要定义class或component。

Class命名

  • Typescript Class采用PascalCase命名,如
ts
class LocationGroup {
  ...
}
  • Class名称除大小写外与文件名一致

国际化命名

  • 命名采用'<模块>.<子模块>.<名称>'的方式: 如 'resource.statistics.title'。一般有子模块。也可以没有。采用英文'.'分隔。
  • 名称采用camelCase.
  • 模块名称和规定的常用名词一致。
  • 跨模块的通常的操作或名词,如'add','edit','delete','No data',直接国际化,不用加模块名称。其他情况需要加模块名称。
  • 国际化带参数: "预计今天{time}到达",需要传入参数。"新增{类型}",可共享同一个国际化字段 (trAdd)
  • 复数形式

参数命名

  • 参数采用camelCase
js
/* Bad */
const page_count = 5
const active = true
const ShouldUpdate = true

/* Good */
const pageCount = 5
const isActive = true
const shouldUpdate = true
  • 除Id外,不要采用缩写.

DO:

ts
const currentUser = ...
setCurrentUser(user1)

DON'T

ts
const curUser = ...
setCurUser(user`)

命名方式

Naming things is hard. Please adhere to the conventions here.

使用英文

Use English language when naming your variables and functions.

js
/* Bad */
const primerNombre = 'Gustavo'
const amigos = ['Kate', 'John']

/* Good */
const firstName = 'Gustavo'
const friends = ['Kate', 'John']

简单直接的命名

A name must be short, intuitive and descriptive:

  • Short. A name must not take long to type and, therefore, remember;
  • Intuitive. A name must read naturally, as close to the common speech as possible;
  • Descriptive. A name must reflect what it does/possesses in the most efficient way.
js
/* Bad */
const a = 5 // "a" could mean anything
const isPaginatable = a > 10 // "Paginatable" sounds extremely unnatural
const shouldPaginatize = a > 10 // Made up verbs are so much fun!

/* Good */
const postCount = 5
const hasPagination = postCount > 10
const shouldPaginate = postCount > 10 // alternatively

避免重复

A name should not duplicate the context in which it is defined. Always remove the context from a name if that doesn't decrease its readability.

js
class UserService {
  /* BAD: Method name duplicates the context (which is "User") */
  getUserSettings(event) {
    // ...
  }

  /* GOOD: Reads nicely as `userService.getSettings()` */
  getSettings(event) {
    // ...
  }
}

结果导向

A name should reflect the expected result.

jsx
/* Bad */
const isEnabled = itemCount > 3
if (!isEnabled) {
  // ...
}

/* Good */
const isDisabled = itemCount <= 3
if (isDisabled) {
  // ...
}

命名方法

命名函数的原则:动词 + 模块 + 子模块

命名函数的原则:

前缀? + 动词 (A) + 模块 (HC) + 子模块? (LC)

Take a look at how this pattern may be applied in the table below.

名字前缀动词(A)模块 (HC)子模块 (LC)
getUsergetUser
getUserMessagesgetUserMessages
shouldDisplayMessageshouldDisplayMessage
isPaymentEnabledisEnabledPayment

动词

The verb part of your function name. The most important part responsible for describing what the function does.

get

Accesses data immediately (i.e. shorthand getter of internal data).

js
function getUserFullName() {
  return this.firstName + ' ' + this.lastName
}

See also compose.

set

Sets a variable in a declarative way, with value A to value B.

js
let fruits = 0

function setFruits(nextFruits) {
  fruits = nextFruits
}

setFruits(5)
console.log(fruits) // 5

reset

Sets a variable back to its initial value or state.

js
const initialFruits = 5
let fruits = initialFruits
setFruits(10)
console.log(fruits) // 10

function resetFruits() {
  fruits = initialFruits
}

resetFruits()
console.log(fruits) // 5

fetch

Request for some data, which takes some indeterminate time (i.e. database request).

js
function getUsers() {
  return this.userRepository
    .createQueryBuilder()
    .where('user.isActive = :isActive', { isActive: true })
    .getMany()
}

remove

Removes something from somewhere.

For example, if you have a collection of selected filters on a search page, removing one of them from the collection is removeFilter, not deleteFilter (and this is how you would naturally say it in English as well):

js
function removeFilter(filters, filterName) {
  return filters.filter((name) => name !== filterName)
}

const selectedFilters = ['price', 'availability', 'size']
removeFilter(selectedFilters, 'price')

See also delete.

delete

Completely erases something from the realms of existence.

Imagine you are a content editor, and there is that notorious post you wish to get rid of. Once you clicked a shiny "Delete post" button, the CMS performed a deletePost action, not removePost.

js
function deleteUser(id) {
  return this.userRepository.delete(id)
}

See also remove.

compose

Creates new data from the existing one. Mostly applicable to strings, objects, or functions.

js
function composePageUrl(pageName, pageId) {
  return pageName.toLowerCase() + '-' + pageId
}

See also get.


模块

A domain that a function operates on.

A function is often an action on something. It is important to state what its operable domain is, or at least an expected data type.

js
/* A pure function operating with primitives */
function filter(list, predicate) {
  return list.filter(predicate)
}

/* Function operating exactly on posts */
function getRecentPosts(posts) {
  return filter(posts, (post) => post.date === Date.now())
}

Some language-specific assumptions may allow omitting the context. For example, in JavaScript, it's common that filter operates on Array. Adding explicit filterArray would be unnecessary.

--

前缀

Prefix enhances the meaning of a variable. It is rarely used in function names.

is

Describes a characteristic or state of the current context (usually boolean).

js
const color = 'blue'
const isBlue = color === 'blue' // characteristic
const isPresent = true // state

if (isBlue && isPresent) {
  console.log('Blue is present!')
}

has

Describes whether the current context possesses a certain value or state (usually boolean).

js
/* Bad */
const isProductsExist = productsCount > 0
const areProductsPresent = productsCount > 0

/* Good */
const hasProducts = productsCount > 0

should

Reflects a positive conditional statement (usually boolean) coupled with a certain action.

js
function shouldUpdateUrl(url, expectedUrl) {
  return url !== expectedUrl
}

min/max

Represents a minimum or maximum value. Used when describing boundaries or limits.

js
/**
 * Renders a random amount of posts within
 * the given min/max boundaries.
 */
function renderPosts(posts, minPosts, maxPosts) {
  return posts.slice(0, randomBetween(minPosts, maxPosts))
}

单复数

js
/* Bad */
const friends = 'Bob'
const friend = ['Bob', 'Tony', 'Tanya']

/* Good */
const friend = 'Bob'
const friends = ['Bob', 'Tony', 'Tanya']

Last updated: