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: