Created by Github action --------- Co-authored-by: Crowdin Bot <support+bot@crowdin.com> Co-authored-by: github-actions <github-actions@twenty.com>
296 lines
9.4 KiB
Plaintext
296 lines
9.4 KiB
Plaintext
---
|
|
title: מדריך סגנון
|
|
image: /images/user-guide/notes/notes_header.png
|
|
---
|
|
|
|
<Frame>
|
|
<img src="/images/user-guide/notes/notes_header.png" alt="Header" />
|
|
</Frame>
|
|
|
|
מסמך זה כולל את הכללים שיש לעקוב אחריהם בעת כתיבת קוד.
|
|
|
|
המטרה כאן היא לקבל בסיס קוד עקבי, שקל לקרוא ומקל על תחזוקה.
|
|
|
|
For this, it's better to be a bit more verbose than to be too concise.
|
|
|
|
תמיד זכרו שאנשים קוראים קוד יותר מכפי שהם כותבים אותו, במיוחד בפרויקט קוד פתוח, שבו כל אחד יכול לתרום.
|
|
|
|
יש הרבה כללים שאינם מוגדרים כאן אך נבדקים אוטומטית על ידי כלים לניתוח קוד.
|
|
|
|
## ריאקט
|
|
|
|
### השתמשו ברכיבים פונקציונליים
|
|
|
|
תמיד השתמשו ברכיבי TSX פונקציונליים.
|
|
|
|
אל תשתמשו בייבוא ברירת מחדל עם `const`, כי זה קשה לקריאה וקשה לייבוא עם השלמת קוד.
|
|
|
|
```tsx
|
|
// ❌ Bad, harder to read, harder to import with code completion
|
|
const MyComponent = () => {
|
|
return <div>Hello World</div>;
|
|
};
|
|
|
|
export default MyComponent;
|
|
|
|
// ✅ Good, easy to read, easy to import with code completion
|
|
export function MyComponent() {
|
|
return <div>Hello World</div>;
|
|
};
|
|
```
|
|
|
|
### תכונות
|
|
|
|
צרו את סוג הפרופס וקראו לו `(ComponentName)Props` אם אין צורך לייצא אותו.
|
|
|
|
Use props destructuring.
|
|
|
|
```tsx
|
|
// ❌ Bad, no type
|
|
export const MyComponent = (props) => <div>Hello {props.name}</div>;
|
|
|
|
// ✅ Good, type
|
|
type MyComponentProps = {
|
|
name: string;
|
|
};
|
|
|
|
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
|
|
```
|
|
|
|
#### הימנעו משימוש ב-`React.FC` או ב-`React.FunctionComponent` כדי להגדיר סוגי פרופס
|
|
|
|
```tsx
|
|
/* ❌ - Bad, defines the component type annotations with `FC`
|
|
* - With `React.FC`, the component implicitly accepts a `children` prop
|
|
* even if it's not defined in the prop type. This might not always be
|
|
* desirable, especially if the component doesn't intend to render
|
|
* children.
|
|
*/
|
|
const EmailField: React.FC<{
|
|
value: string;
|
|
}> = ({ value }) => <TextInput value={value} disabled fullWidth />;
|
|
```
|
|
|
|
```tsx
|
|
/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the
|
|
* component's props
|
|
* - This method doesn't automatically include the children prop. If
|
|
* you want to include it, you have to specify it in OwnProps.
|
|
*/
|
|
type EmailFieldProps = {
|
|
value: string;
|
|
};
|
|
|
|
const EmailField = ({ value }: EmailFieldProps) => (
|
|
<TextInput value={value} disabled fullWidth />
|
|
);
|
|
```
|
|
|
|
#### אין פרופסי הפצה משתנים ב-GSX Elements
|
|
|
|
Avoid using single variable prop spreading in JSX elements, like `{...props}`. הפרקטיקה הזו בדרך כלל יכולה לגרום לקוד פחות קורא ויותר קשה לתחזוקה כי לא ברור איזה פרופס הרכיב מקבל.
|
|
|
|
```tsx
|
|
/* ❌ - Bad, spreads a single variable prop into the underlying component
|
|
*/
|
|
const MyComponent = (props: OwnProps) => {
|
|
return <OtherComponent {...props} />;
|
|
}
|
|
```
|
|
|
|
```tsx
|
|
/* ✅ - Good, Explicitly lists all props
|
|
* - Enhances readability and maintainability
|
|
*/
|
|
const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
|
|
return <OtherComponent {...{ prop1, prop2, prop3 }} />;
|
|
};
|
|
```
|
|
|
|
סיבה:
|
|
|
|
- במבט חטוף, ברור יותר אילו פרופסים מועברים בקוד, מה שמקל על הבנה ותחזוקה.
|
|
- זה עוזר למנוע צימוד הדוק בין רכיבים באמצעות הפרופים שלהם.
|
|
- כלי ניתוח קוד מקלים על זיהוי פרופסים מאוייתים לא נכון או שאינם בשימוש כאשר מפרטים פרופסים בצורה ברורה.
|
|
|
|
## JavaScript
|
|
|
|
### השתמשו במפעיל הערכה נול `??`
|
|
|
|
```tsx
|
|
// ❌ Bad, can return 'default' even if value is 0 or ''
|
|
const value = process.env.MY_VALUE || 'default';
|
|
|
|
// ✅ Good, will return 'default' only if value is null or undefined
|
|
const value = process.env.MY_VALUE ?? 'default';
|
|
```
|
|
|
|
### השתמשו בבדיקת ״?״
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
onClick && onClick();
|
|
|
|
// ✅ Good
|
|
onClick?.();
|
|
```
|
|
|
|
## TypeScript
|
|
|
|
### השתמשו ב-`type` במקום `interface`
|
|
|
|
תמיד השתמשו ב-`type` במקום `interface`, כי הם כמעט תמיד חופפים, ו-`type` גמיש יותר.
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
interface MyInterface {
|
|
name: string;
|
|
}
|
|
|
|
// ✅ Good
|
|
type MyType = {
|
|
name: string;
|
|
};
|
|
```
|
|
|
|
### השתמשו במקורות מחרוזות במקום enums
|
|
|
|
[מחרוזות מותאמות](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) הן הדרכים המודפות לטיפול בערכים דמויי-Enum ב-TypeScript. הן קלות להרחבה עם Pick ו-Omit, ונותנות חווית מפתחים טובה יותר, במיוחד עם השלמת קוד.
|
|
|
|
ניתן לראות מדוע TypeScript ממליץ לא להשתמש ב-enums [כאן](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums).
|
|
|
|
```tsx
|
|
// ❌ Bad, utilizes an enum
|
|
enum Color {
|
|
Red = "red",
|
|
Green = "green",
|
|
Blue = "blue",
|
|
}
|
|
|
|
let color = Color.Red;
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good, utilizes a string literal
|
|
|
|
let color: "red" | "green" | "blue" = "red";
|
|
```
|
|
|
|
#### GraphQL וספריות פנימיות
|
|
|
|
יש להשתמש ב-enums שמיוצרים על ידי GraphQL codegen.
|
|
|
|
גם כדאי להשתמש ב-enum כאשר משתמשים בספריה פנימית, כדי שהספריה לא תצטרך לחשוף סוג מחרוזת מותאמת שלא קשור ל-API הפנימי.
|
|
|
|
דוגמא:
|
|
|
|
```TSX
|
|
const {
|
|
setHotkeyScopeAndMemorizePreviousScope,
|
|
goBackToPreviousHotkeyScope,
|
|
} = usePreviousHotkeyScope();
|
|
|
|
setHotkeyScopeAndMemorizePreviousScope(
|
|
RelationPickerHotkeyScope.RelationPicker,
|
|
);
|
|
```
|
|
|
|
## סטיילינג
|
|
|
|
### השתמשו ב-StyledComponents
|
|
|
|
עצבו את הרכיבים עם [styled-components](https://emotion.sh/docs/styled).
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
<div className="my-class">Hello World</div>
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good
|
|
const StyledTitle = styled.div`
|
|
color: red;
|
|
`;
|
|
```
|
|
|
|
קדמו רכיבים מעוצבים עם "Styled" כדי להבדילם מ"רכיבים אמיתיים".
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
const Title = styled.div`
|
|
color: red;
|
|
`;
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good
|
|
const StyledTitle = styled.div`
|
|
color: red;
|
|
`;
|
|
```
|
|
|
|
### מערכות נושא
|
|
|
|
שימוש בנושא לצורך עיצוב רכיבים הוא הגישה המועדפת.
|
|
|
|
#### יחידות מידה
|
|
|
|
הימנעו משימוש בערכי `px` או `rem` ישירות בתוך רכיבים מעוצבים. הערכים הנדרשים כבר מוגדרים בדרך כלל בנושא, ולכן מומלץ להשתמש בנושא לכך.
|
|
|
|
#### צבעים
|
|
|
|
הימנעו מהכנסת צבעים חדשים, במקום זאת השתמשו בפלטה קיימת מתוך הנושא. אם יש מצב שהפלטה לא מתאימה, יש להשאיר תגובה כדי שהצוות יוכל לתקן.
|
|
|
|
```tsx
|
|
// ❌ Bad, directly specifies style values without utilizing the theme
|
|
const StyledButton = styled.button`
|
|
color: #333333;
|
|
font-size: 1rem;
|
|
font-weight: 400;
|
|
margin-left: 4px;
|
|
border-radius: 50px;
|
|
`;
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good, utilizes the theme
|
|
const StyledButton = styled.button`
|
|
color: ${({ theme }) => theme.font.color.primary};
|
|
font-size: ${({ theme }) => theme.font.size.md};
|
|
font-weight: ${({ theme }) => theme.font.weight.regular};
|
|
margin-left: ${({ theme }) => theme.spacing(1)};
|
|
border-radius: ${({ theme }) => theme.border.rounded};
|
|
`;
|
|
```
|
|
|
|
## אכיפת ייבואים ללא סוגים
|
|
|
|
הימנעו מייבוא סוגים. כדי לאכוף סטנדרט זה, חוק ESLint בודק ומדווח על ייבוא סוגים כלשהו. זה מסייע לשמור על עקביות וקריאות בקוד ה-TypeScript.
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
|
|
// ❌ Bad
|
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
|
|
// ✅ Good
|
|
import { Meta, StoryObj } from '@storybook/react';
|
|
```
|
|
|
|
### למה לא לעשות ייבוא סוג
|
|
|
|
- **עקביות**: על ידי הימנעות מייבוא סוגים ושימוש בגישה אחת גם לייבוא סוגים וגם לייבוא ערכים, בסיס הקוד נותר עקבי בסגנון גישה למודולים.
|
|
|
|
- **קריאות**: ייבוא ללא סוג משפר את קריאות הקוד בכך שהוא מבהיר מתי מייבאים ערכים או סוגים. This reduces ambiguity and makes it easier to understand the purpose of imported symbols.
|
|
|
|
- **תחזוקה**: זה משפר את תחזוקת בסיס הקוד משום שזה מאפשר למפתחים לזהות ולאתר ייבוא סוגים בלבד בעת בדיקה או שינוי קוד.
|
|
|
|
### חוק ESLint
|
|
|
|
An ESLint rule, `@typescript-eslint/consistent-type-imports`, enforces the no-type import standard. חוק זה ייצור שגיאות או אזהרות על כל חריגות מייבוא סוגים.
|
|
|
|
שים לב שחוק זה עוסק בעיקר במקרים נדירים של ייבוא סוגים לא מכוון. TypeScript itself discourages this practice, as mentioned in the [TypeScript 3.8 release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). In most situations, you should not need to use type-only imports.
|
|
|
|
To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow.
|