├── .DS_Store
├── .gitignore
├── LICENSE.md
├── README.md
├── css-in-javascript
└── README.md
├── css-sass
└── README.md
├── javascript
└── README.md
├── linters
├── .eslintrc
├── .jshintrc
├── .markdownlint.json
└── SublimeLinter
│ └── SublimeLinter.sublime-settings
├── package.json
├── react
└── README.md
├── typescript
└── README.md
├── unit-test
└── README.md
└── yarn.lock
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DTStack/Code-Style-Guide/c41ad84c72702a8f8f5c57bb4d41d3969eb50c8b/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2012 Airbnb
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Code Style Guide
2 |
3 | > Our project is based on the [airbnb](https://github.com/airbnb/javascript) and [TypeScript style guide](https://ts.dev/style/#identifiers) project fork to adapt the specification for the Dtstack Frontend Team.
4 | > Compared to the original, it integrates the Dtstack Frontend Team specification, adds the latest JS and React features, and unit testing.
5 | > We plan to sort out a set of corresponding link rules according to the specifications in the future and integrate them into our projects for actual production and development.
6 |
7 | ## Code Style guide directory
8 |
9 | - [React](react/README.md)
10 | - [CSS-in-JavaScript](css-in-javascript/README.md)
11 | - [CSS & Sass](css-sass/README.md)
12 | - [Javascript](javascript/README.md)
13 | - [Typescript](typescript/README.md)
14 | - [Unit-Test](unit-test/README.md)
15 |
16 | ## Why do need a code style guide
17 |
18 | Because software is often written by different people throughout its life cycle. If everyone follows the specification, everyone's code style will be consistent.
19 |
20 | ## What can a code style guide do?
21 |
22 | - Disciplined code promotes teamwork
23 | - Regular code can reduce bug handling
24 | - Regular code can reduce maintenance costs
25 | - Normative code facilitates code review
26 | - Getting into the habit of code specification helps programmers grow
27 |
28 | ## Thank you
29 | Thanks for helping us as we sort through the code specification:
30 |
31 | - [TypeScript style guide](https://ts.dev/style/#identifiers)
32 | - [airbnb](https://github.com/airbnb/javascript)
--------------------------------------------------------------------------------
/css-in-javascript/README.md:
--------------------------------------------------------------------------------
1 | # CSS-in-JavaScript Style Guide
2 |
3 | *A mostly reasonable approach to CSS-in-JavaScript*
4 |
5 | ## Table of Contents
6 |
7 | 1. [Naming](#naming)
8 | 1. [Ordering](#ordering)
9 | 1. [Nesting](#nesting)
10 | 1. [Inline](#inline)
11 |
12 | ## Naming
13 |
14 | - Use camelCase for object keys (i.e. "selectors").
15 |
16 | > Why? We access these keys as properties on the `styles` object in the component, so it is most convenient to use camelCase.
17 |
18 | ```js
19 | // bad
20 | {
21 | 'bermuda-triangle': {
22 | display: 'none',
23 | },
24 | }
25 |
26 | // good
27 | {
28 | bermudaTriangle: {
29 | display: 'none',
30 | },
31 | }
32 | ```
33 |
34 | - Use an underscore for modifiers to other styles.
35 |
36 | > Why? Similar to BEM, this naming convention makes it clear that the styles are intended to modify the element preceded by the underscore. Underscores do not need to be quoted, so they are preferred over other characters, such as dashes.
37 |
38 | ```js
39 | // bad
40 | {
41 | bruceBanner: {
42 | color: 'pink',
43 | transition: 'color 10s',
44 | },
45 |
46 | bruceBannerTheHulk: {
47 | color: 'green',
48 | },
49 | }
50 |
51 | // good
52 | {
53 | bruceBanner: {
54 | color: 'pink',
55 | transition: 'color 10s',
56 | },
57 |
58 | bruceBanner_theHulk: {
59 | color: 'green',
60 | },
61 | }
62 | ```
63 |
64 | - Use `selectorName_fallback` for sets of fallback styles.
65 |
66 | > Why? Similar to modifiers, keeping the naming consistent helps reveal the relationship of these styles to the styles that override them in more adequate browsers.
67 |
68 | ```js
69 | // bad
70 | {
71 | muscles: {
72 | display: 'flex',
73 | },
74 |
75 | muscles_sadBears: {
76 | width: '100%',
77 | },
78 | }
79 |
80 | // good
81 | {
82 | muscles: {
83 | display: 'flex',
84 | },
85 |
86 | muscles_fallback: {
87 | width: '100%',
88 | },
89 | }
90 | ```
91 |
92 | - Use a separate selector for sets of fallback styles.
93 |
94 | > Why? Keeping fallback styles contained in a separate object clarifies their purpose, which improves readability.
95 |
96 | ```js
97 | // bad
98 | {
99 | muscles: {
100 | display: 'flex',
101 | },
102 |
103 | left: {
104 | flexGrow: 1,
105 | display: 'inline-block',
106 | },
107 |
108 | right: {
109 | display: 'inline-block',
110 | },
111 | }
112 |
113 | // good
114 | {
115 | muscles: {
116 | display: 'flex',
117 | },
118 |
119 | left: {
120 | flexGrow: 1,
121 | },
122 |
123 | left_fallback: {
124 | display: 'inline-block',
125 | },
126 |
127 | right_fallback: {
128 | display: 'inline-block',
129 | },
130 | }
131 | ```
132 |
133 | - Use device-agnostic names (e.g. "small", "medium", and "large") to name media query breakpoints.
134 |
135 | > Why? Commonly used names like "phone", "tablet", and "desktop" do not match the characteristics of the devices in the real world. Using these names sets the wrong expectations.
136 |
137 | ```js
138 | // bad
139 | const breakpoints = {
140 | mobile: '@media (max-width: 639px)',
141 | tablet: '@media (max-width: 1047px)',
142 | desktop: '@media (min-width: 1048px)',
143 | };
144 |
145 | // good
146 | const breakpoints = {
147 | small: '@media (max-width: 639px)',
148 | medium: '@media (max-width: 1047px)',
149 | large: '@media (min-width: 1048px)',
150 | };
151 | ```
152 |
153 | **[⬆ back to top](#table-of-contents)**
154 |
155 | ## Ordering
156 |
157 | - Define styles after the component.
158 |
159 | > Why? We use a higher-order component to theme our styles, which is naturally used after the component definition. Passing the styles object directly to this function reduces indirection.
160 |
161 | ```jsx
162 | // bad
163 | const styles = {
164 | container: {
165 | display: 'inline-block',
166 | },
167 | };
168 |
169 | function MyComponent({ styles }) {
170 | return (
171 |
172 | Never doubt that a small group of thoughtful, committed citizens can
173 | change the world. Indeed, it’s the only thing that ever has.
174 |
184 | Never doubt that a small group of thoughtful, committed citizens can
185 | change the world. Indeed, it’s the only thing that ever has.
186 |
187 | );
188 | }
189 |
190 | export default withStyles(() => ({
191 | container: {
192 | display: 'inline-block',
193 | },
194 | }))(MyComponent);
195 | ```
196 |
197 | **[⬆ back to top](#table-of-contents)**
198 |
199 | ## Nesting
200 |
201 | - Leave a blank line between adjacent blocks at the same indentation level.
202 |
203 | > Why? The whitespace improves readability and reduces the likelihood of merge conflicts.
204 |
205 | ```js
206 | // bad
207 | {
208 | bigBang: {
209 | display: 'inline-block',
210 | '::before': {
211 | content: "''",
212 | },
213 | },
214 | universe: {
215 | border: 'none',
216 | },
217 | }
218 |
219 | // good
220 | {
221 | bigBang: {
222 | display: 'inline-block',
223 |
224 | '::before': {
225 | content: "''",
226 | },
227 | },
228 |
229 | universe: {
230 | border: 'none',
231 | },
232 | }
233 | ```
234 |
235 | **[⬆ back to top](#table-of-contents)**
236 |
237 | ## Inline
238 |
239 | - Use inline styles for styles that have a high cardinality (e.g. uses the value of a prop) and not for styles that have a low cardinality.
240 |
241 | > Why? Generating themed stylesheets can be expensive, so they are best for discrete sets of styles.
242 |
243 | ```jsx
244 | // bad
245 | export default function MyComponent({ spacing }) {
246 | return (
247 |
248 | );
249 | }
250 |
251 | // good
252 | function MyComponent({ styles, spacing }) {
253 | return (
254 |
255 | );
256 | }
257 | export default withStyles(() => ({
258 | periodic: {
259 | display: 'table',
260 | },
261 | }))(MyComponent);
262 | ```
263 |
264 | **[⬆ back to top](#table-of-contents)**
265 |
--------------------------------------------------------------------------------
/css-sass/README.md:
--------------------------------------------------------------------------------
1 | # CSS / Sass Styleguide
2 |
3 | *A mostly reasonable approach to CSS and Sass*
4 |
5 | ## Table of Contents
6 |
7 | 1. [Terminology](#terminology)
8 | - [Rule Declaration](#rule-declaration)
9 | - [Selectors](#selectors)
10 | - [Properties](#properties)
11 | 1. [CSS](#css)
12 | - [Formatting](#formatting)
13 | - [Comments](#comments)
14 | - [OOCSS and BEM](#oocss-and-bem)
15 | - [ID Selectors](#id-selectors)
16 | - [JavaScript hooks](#javascript-hooks)
17 | - [Border](#border)
18 | 1. [Sass](#sass)
19 | - [Syntax](#syntax)
20 | - [Ordering](#ordering-of-property-declarations)
21 | - [Variables](#variables)
22 | - [Mixins](#mixins)
23 | - [Extend directive](#extend-directive)
24 | - [Nested selectors](#nested-selectors)
25 | 1. [Translation](#translation)
26 | 1. [License](#license)
27 |
28 | ## Terminology
29 |
30 | ### Rule declaration
31 |
32 | A “rule declaration” is the name given to a selector (or a group of selectors) with an accompanying group of properties. Here's an example:
33 |
34 | ```css
35 | .listing {
36 | font-size: 18px;
37 | line-height: 1.2;
38 | }
39 | ```
40 |
41 | ### Selectors
42 |
43 | In a rule declaration, “selectors” are the bits that determine which elements in the DOM tree will be styled by the defined properties. Selectors can match HTML elements, as well as an element's class, ID, or any of its attributes. Here are some examples of selectors:
44 |
45 | ```css
46 | .my-element-class {
47 | /* ... */
48 | }
49 |
50 | [aria-hidden] {
51 | /* ... */
52 | }
53 | ```
54 |
55 | ### Properties
56 |
57 | Finally, properties are what give the selected elements of a rule declaration their style. Properties are key-value pairs, and a rule declaration can contain one or more property declarations. Property declarations look like this:
58 |
59 | ```css
60 | /* some selector */ {
61 | color: #333;
62 | background: #f1f1f1;
63 | }
64 | ```
65 |
66 | **[⬆ back to top](#table-of-contents)**
67 |
68 | ## CSS
69 |
70 | ### Formatting
71 |
72 | - Use soft tabs (2 spaces) for indentation.
73 | - Prefer dashes over camelCasing in class names.
74 | - Underscores and PascalCasing are okay if you are using BEM (see [OOCSS and BEM](#oocss-and-bem) below).
75 | - Do not use ID selectors.
76 | - When using multiple selectors in a rule declaration, give each selector its own line.
77 | - Put a space before the opening brace `{` in rule declarations.
78 | - In properties, put a space after, but not before, the `:` character.
79 | - Put closing braces `}` of rule declarations on a new line.
80 | - Put blank lines between rule declarations.
81 |
82 | **Bad**
83 |
84 | ```css
85 | .avatar{
86 | border-radius:50%;
87 | border:2px solid #fff;}
88 | .no, .nope, .not_good {
89 | // ...
90 | }
91 | #lol-no {
92 | // ...
93 | }
94 | ```
95 |
96 | **Good**
97 |
98 | ```css
99 | .avatar {
100 | border-radius: 50%;
101 | border: 2px solid #fff;
102 | }
103 |
104 | .one,
105 | .selector,
106 | .per-line {
107 | // ...
108 | }
109 | ```
110 |
111 | ### Comments
112 |
113 | - Prefer line comments (`//` in Sass-land) to block comments.
114 | - Prefer comments on their own line. Avoid end-of-line comments.
115 | - Write detailed comments for code that isn't self-documenting:
116 | - Uses of z-index
117 | - Compatibility or browser-specific hacks
118 |
119 | ### OOCSS and BEM
120 |
121 | We encourage some combination of OOCSS and BEM for these reasons:
122 |
123 | - It helps create clear, strict relationships between CSS and HTML
124 | - It helps us create reusable, composable components
125 | - It allows for less nesting and lower specificity
126 | - It helps in building scalable stylesheets
127 |
128 | **OOCSS**, or “Object Oriented CSS”, is an approach for writing CSS that encourages you to think about your stylesheets as a collection of “objects”: reusable, repeatable snippets that can be used independently throughout a website.
129 |
130 | - Nicole Sullivan's [OOCSS wiki](https://github.com/stubbornella/oocss/wiki)
131 | - Smashing Magazine's [Introduction to OOCSS](http://www.smashingmagazine.com/2011/12/12/an-introduction-to-object-oriented-css-oocss/)
132 |
133 | **BEM**, or “Block-Element-Modifier”, is a _naming convention_ for classes in HTML and CSS. It was originally developed by Yandex with large codebases and scalability in mind, and can serve as a solid set of guidelines for implementing OOCSS.
134 |
135 | - CSS Trick's [BEM 101](https://css-tricks.com/bem-101/)
136 | - Harry Roberts' [introduction to BEM](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/)
137 |
138 | **Example**
139 |
140 | ```jsx
141 | // ListingCard.jsx
142 | function ListingCard() {
143 | return (
144 |
145 |
Adorable 2BR in the sunny Mission
146 |
147 |
Vestibulum id ligula porta felis euismod semper.
148 |
149 |
150 | );
151 | }
152 | ```
153 |
154 | ```css
155 | /* ListingCard.css */
156 | .listing-card { }
157 | .listing-card-featured { }
158 | .listing-card_title { }
159 | .listing-card_content { }
160 | ```
161 |
162 | - `.listing-card` is the “block” and represents the higher-level component
163 | - `.listing-card_title` is an “element” and represents a descendant of `.listing-card` that helps compose the block as a whole.
164 | - `.listing-card-featured` is a “modifier” and represents a different state or variation on the `.listing-card` block.
165 |
166 | ### ID selectors
167 |
168 | While it is possible to select elements by ID in CSS, it should generally be considered an anti-pattern. ID selectors introduce an unnecessarily high level of [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) to your rule declarations, and they are not reusable.
169 |
170 | For more on this subject, read [CSS Wizardry's article](http://csswizardry.com/2014/07/hacks-for-dealing-with-specificity/) on dealing with specificity.
171 |
172 | ### JavaScript hooks
173 |
174 | Avoid binding to the same class in both your CSS and JavaScript. Conflating the two often leads to, at a minimum, time wasted during refactoring when a developer must cross-reference each class they are changing, and at its worst, developers being afraid to make changes for fear of breaking functionality.
175 |
176 | We recommend creating JavaScript-specific classes to bind to, prefixed with `.js-`:
177 |
178 | ```html
179 |
180 | ```
181 |
182 | ### Border
183 |
184 | Use `0` instead of `none` to specify that a style has no border.
185 |
186 | **Bad**
187 |
188 | ```css
189 | .foo {
190 | border: none;
191 | }
192 | ```
193 |
194 | **Good**
195 |
196 | ```css
197 | .foo {
198 | border: 0;
199 | }
200 | ```
201 |
202 | **[⬆ back to top](#table-of-contents)**
203 |
204 | ## Sass
205 |
206 | ### Syntax
207 |
208 | - Use the `.scss` syntax, never the original `.sass` syntax
209 | - Order your regular CSS and `@include` declarations logically (see below)
210 |
211 | ### Ordering of property declarations
212 |
213 | 1. Property declarations
214 |
215 | List all standard property declarations, anything that isn't an `@include` or a nested selector.
216 |
217 | ```scss
218 | .btn-green {
219 | background: green;
220 | font-weight: bold;
221 | // ...
222 | }
223 | ```
224 |
225 | 1. `@include` declarations
226 |
227 | Grouping `@include`s at the end makes it easier to read the entire selector.
228 |
229 | ```scss
230 | .btn-green {
231 | background: green;
232 | font-weight: bold;
233 | @include transition(background 0.5s ease);
234 | // ...
235 | }
236 | ```
237 |
238 | 1. Nested selectors
239 |
240 | Nested selectors, _if necessary_, go last, and nothing goes after them. Add whitespace between your rule declarations and nested selectors, as well as between adjacent nested selectors. Apply the same guidelines as above to your nested selectors.
241 |
242 | ```scss
243 | .btn {
244 | background: green;
245 | font-weight: bold;
246 | @include transition(background 0.5s ease);
247 |
248 | .icon {
249 | margin-right: 10px;
250 | }
251 | }
252 | ```
253 |
254 | ### Variables
255 |
256 | Prefer dash-cased variable names (e.g. `$my-variable`) over camelCased or snake_cased variable names. It is acceptable to prefix variable names that are intended to be used only within the same file with an underscore (e.g. `$_my-variable`).
257 |
258 | ### Mixins
259 |
260 | Mixins should be used to DRY up your code, add clarity, or abstract complexity--in much the same way as well-named functions. Mixins that accept no arguments can be useful for this, but note that if you are not compressing your payload (e.g. gzip), this may contribute to unnecessary code duplication in the resulting styles.
261 |
262 | ### Extend directive
263 |
264 | `@extend` should be avoided because it has unintuitive and potentially dangerous behavior, especially when used with nested selectors. Even extending top-level placeholder selectors can cause problems if the order of selectors ends up changing later (e.g. if they are in other files and the order the files are loaded shifts). Gzipping should handle most of the savings you would have gained by using `@extend`, and you can DRY up your stylesheets nicely with mixins.
265 |
266 | ### Nested selectors
267 |
268 | **Do not nest selectors more than three levels deep!**
269 |
270 | ```scss
271 | .page-container {
272 | .content {
273 | .profile {
274 | // STOP!
275 | }
276 | }
277 | }
278 | ```
279 |
280 | When selectors become this long, you're likely writing CSS that is:
281 |
282 | - Strongly coupled to the HTML (fragile) *—OR—*
283 | - Overly specific (powerful) *—OR—*
284 | - Not reusable
285 |
286 | Again: **never nest ID selectors!**
287 |
288 | If you must use an ID selector in the first place (and you should really try not to), they should never be nested. If you find yourself doing this, you need to revisit your markup, or figure out why such strong specificity is needed. If you are writing well formed HTML and CSS, you should **never** need to do this.
289 |
290 | **[⬆ back to top](#table-of-contents)**
291 |
--------------------------------------------------------------------------------
/linters/.eslintrc:
--------------------------------------------------------------------------------
1 | // Use this file as a starting point for your project's .eslintrc.
2 | // Copy this file, and add rule overrides as needed.
3 | {
4 | "extends": "airbnb"
5 | }
6 |
--------------------------------------------------------------------------------
/linters/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | /*
3 | * ENVIRONMENTS
4 | * =================
5 | */
6 |
7 | // Define globals exposed by modern browsers.
8 | "browser": true,
9 |
10 | // Define globals exposed by jQuery.
11 | "jquery": true,
12 |
13 | // Define globals exposed by Node.js.
14 | "node": true,
15 |
16 | // Allow ES6.
17 | "esversion": 6,
18 |
19 | /*
20 | * ENFORCING OPTIONS
21 | * =================
22 | */
23 |
24 | // Force all variable names to use either camelCase style or UPPER_CASE
25 | // with underscores.
26 | "camelcase": true,
27 |
28 | // Prohibit use of == and != in favor of === and !==.
29 | "eqeqeq": true,
30 |
31 | // Enforce tab width of 2 spaces.
32 | "indent": 2,
33 |
34 | // Prohibit use of a variable before it is defined.
35 | "latedef": true,
36 |
37 | // Enforce line length to 100 characters
38 | "maxlen": 100,
39 |
40 | // Require capitalized names for constructor functions.
41 | "newcap": true,
42 |
43 | // Enforce use of single quotation marks for strings.
44 | "quotmark": "single",
45 |
46 | // Enforce placing 'use strict' at the top function scope
47 | "strict": true,
48 |
49 | // Prohibit use of explicitly undeclared variables.
50 | "undef": true,
51 |
52 | // Warn when variables are defined but never used.
53 | "unused": true,
54 |
55 | /*
56 | * RELAXING OPTIONS
57 | * =================
58 | */
59 |
60 | // Suppress warnings about == null comparisons.
61 | "eqnull": true
62 | }
63 |
--------------------------------------------------------------------------------
/linters/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "comment": "Be explicit by listing every available rule. https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md",
3 | "comment": "Note that there will be numeric gaps, not every MD number is implemented in markdownlint.",
4 |
5 | "comment": "MD001: Header levels should only increment by one level at a time.",
6 | "header-increment": true,
7 |
8 | "comment": "MD002: First header should be a top level header.",
9 | "first-header-h1": true,
10 |
11 | "comment": "MD003: Header style: start with hashes.",
12 | "header-style": {
13 | "style": "atx"
14 | },
15 |
16 | "comment": "MD004: Unordered list style",
17 | "ul-style": {
18 | "style": "dash"
19 | },
20 |
21 | "comment": "MD005: Consistent indentation for list items at the same level.",
22 | "list-indent": true,
23 |
24 | "comment": "MD006: Consider starting bulleted lists at the beginning of the line.",
25 | "ul-start-left": false,
26 |
27 | "comment": "MD007: Unordered list indentation: 2 spaces.",
28 | "ul-indent": {
29 | "indent": 2,
30 | "start_indented": true
31 | },
32 |
33 | "comment": "MD009: Disallow trailing spaces!",
34 | "no-trailing-spaces": {
35 | "br_spaces": 0,
36 | "comment": "Empty lines inside list items should not be indented.",
37 | "list_item_empty_lines": false
38 | },
39 |
40 | "comment": "MD010: No hard tabs, not even in code blocks.",
41 | "no-hard-tabs": {
42 | "code_blocks": true
43 | },
44 |
45 | "comment": "MD011: Prevent reversed link syntax",
46 | "no-reversed-links": true,
47 |
48 | "comment": "MD012: Disallow multiple consecutive blank lines.",
49 | "no-multiple-blanks": {
50 | "maximum": 1
51 | },
52 |
53 | "comment": "MD013: Line length",
54 | "line-length": false,
55 |
56 | "comment": "MD014: Disallow use of dollar signs($) before commands without showing output.",
57 | "commands-show-output": true,
58 |
59 | "comment": "MD018: Disallow space after hash on atx style header.",
60 | "no-missing-space-atx": true,
61 |
62 | "comment": "MD019: Disallow multiple spaces after hash on atx style header.",
63 | "no-multiple-space-atx": true,
64 |
65 | "comment": "MD020: No space should be inside hashes on closed atx style header.",
66 | "no-missing-space-closed-atx": true,
67 |
68 | "comment": "MD021: Disallow multiple spaces inside hashes on closed atx style header.",
69 | "no-multiple-space-closed-atx": true,
70 |
71 | "comment": "MD022: Headers should be surrounded by blank lines.",
72 | "comment": "Some headers have preceding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
73 | "blanks-around-headers": false,
74 |
75 | "comment": "MD023: Headers must start at the beginning of the line.",
76 | "header-start-left": true,
77 |
78 | "comment": "MD024: Disallow multiple headers with the same content.",
79 | "no-duplicate-header": true,
80 |
81 | "comment": "MD025: Disallow multiple top level headers in the same document.",
82 | "comment": "Gotta have a matching closing brace at the end.",
83 | "single-h1": false,
84 |
85 | "comment": "MD026: Disallow trailing punctuation in header.",
86 | "comment": "You must have a semicolon after the ending closing brace.",
87 | "no-trailing-punctuation": {
88 | "punctuation" : ".,:!?"
89 | },
90 | "comment": "MD027: Dissalow multiple spaces after blockquote symbol",
91 | "no-multiple-space-blockquote": true,
92 |
93 | "comment": "MD028: Blank line inside blockquote",
94 | "comment": "Some 'Why?' and 'Why not?' blocks are separated by a blank line",
95 | "no-blanks-blockquote": false,
96 |
97 | "comment": "MD029: Ordered list item prefix",
98 | "ol-prefix": {
99 | "style": "one"
100 | },
101 |
102 | "comment": "MD030: Spaces after list markers",
103 | "list-marker-space": {
104 | "ul_single": 1,
105 | "ol_single": 1,
106 | "ul_multi": 1,
107 | "ol_multi": 1
108 | },
109 |
110 | "comment": "MD031: Fenced code blocks should be surrounded by blank lines",
111 | "blanks-around-fences": true,
112 |
113 | "comment": "MD032: Lists should be surrounded by blank lines",
114 | "comment": "Some lists have preceding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
115 | "blanks-around-lists": false,
116 |
117 | "comment": "MD033: Disallow inline HTML",
118 | "comment": "HTML is needed for explicit anchors",
119 | "no-inline-html": false,
120 |
121 | "comment": "MD034: No bare URLs should be used",
122 | "no-bare-urls": true,
123 |
124 | "comment": "MD035: Horizontal rule style",
125 | "hr-style": {
126 | "style": "consistent"
127 | },
128 |
129 | "comment": "MD036: Do not use emphasis instead of a header.",
130 | "no-emphasis-as-header": false,
131 |
132 | "comment": "MD037: Disallow spaces inside emphasis markers.",
133 | "no-space-in-emphasis": true,
134 |
135 | "comment": "MD038: Disallow spaces inside code span elements.",
136 | "no-space-in-code": true,
137 |
138 | "comment": "MD039: Disallow spaces inside link text.",
139 | "no-space-in-links": true,
140 |
141 | "comment": "MD040: Fenced code blocks should have a language specified.",
142 | "fenced-code-language": true,
143 |
144 | "comment": "MD041: First line in file should be a top level header.",
145 | "first-line-h1": true,
146 |
147 | "comment": "MD042: No empty links",
148 | "no-empty-links": true,
149 |
150 | "comment": "MD043: Required header structure.",
151 | "required-headers": false,
152 |
153 | "comment": "MD044: Proper names should have the correct capitalization.",
154 | "proper-names": false
155 | }
156 |
--------------------------------------------------------------------------------
/linters/SublimeLinter/SublimeLinter.sublime-settings:
--------------------------------------------------------------------------------
1 | /**
2 | * Airbnb JSHint settings for use with SublimeLinter and Sublime Text 2.
3 | *
4 | * 1. Install SublimeLinter at https://github.com/SublimeLinter/SublimeLinter
5 | * 2. Open user preferences for the SublimeLinter package in Sublime Text 2
6 | * * For Mac OS X go to _Sublime Text 2_ > _Preferences_ > _Package Settings_ > _SublimeLinter_ > _Settings - User_
7 | * 3. Paste the contents of this file into your settings file
8 | * 4. Save the settings file
9 | *
10 | * @version 0.3.0
11 | * @see https://github.com/SublimeLinter/SublimeLinter
12 | * @see http://www.jshint.com/docs/
13 | */
14 | {
15 | "jshint_options":
16 | {
17 | /*
18 | * ENVIRONMENTS
19 | * =================
20 | */
21 |
22 | // Define globals exposed by modern browsers.
23 | "browser": true,
24 |
25 | // Define globals exposed by jQuery.
26 | "jquery": true,
27 |
28 | // Define globals exposed by Node.js.
29 | "node": true,
30 |
31 | /*
32 | * ENFORCING OPTIONS
33 | * =================
34 | */
35 |
36 | // Force all variable names to use either camelCase style or UPPER_CASE
37 | // with underscores.
38 | "camelcase": true,
39 |
40 | // Prohibit use of == and != in favor of === and !==.
41 | "eqeqeq": true,
42 |
43 | // Suppress warnings about == null comparisons.
44 | "eqnull": true,
45 |
46 | // Enforce tab width of 2 spaces.
47 | "indent": 2,
48 |
49 | // Prohibit use of a variable before it is defined.
50 | "latedef": true,
51 |
52 | // Require capitalized names for constructor functions.
53 | "newcap": true,
54 |
55 | // Enforce use of single quotation marks for strings.
56 | "quotmark": "single",
57 |
58 | // Prohibit trailing whitespace.
59 | "trailing": true,
60 |
61 | // Prohibit use of explicitly undeclared variables.
62 | "undef": true,
63 |
64 | // Warn when variables are defined but never used.
65 | "unused": true,
66 |
67 | // Enforce line length to 80 characters
68 | "maxlen": 80,
69 |
70 | // Enforce placing 'use strict' at the top function scope
71 | "strict": true
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Code-Style-Guide",
3 | "version": "1.0.0",
4 | "description": "A mostly reasonable approach to React JavaScript Typescript Sass UnitTest ...",
5 | "scripts": {
6 | "preinstall": "npm run install:config && npm run install:config:base",
7 | "postinstall": "rm -rf node_modules/markdownlint-cli/node_modules/markdownlint",
8 | "install:config": "cd packages/eslint-config-airbnb && npm prune && npm install",
9 | "install:config:base": "cd packages/eslint-config-airbnb-base && npm prune && npm install",
10 | "lint": "markdownlint --config linters/.markdownlint.json README.md */README.md",
11 | "pretest": "npm run --silent lint",
12 | "test": "npm run --silent test:config && npm run --silent test:config:base",
13 | "test:config": "cd packages/eslint-config-airbnb; npm test",
14 | "test:config:base": "cd packages/eslint-config-airbnb-base; npm test",
15 | "pretravis": "npm run --silent lint",
16 | "travis": "npm run --silent travis:config && npm run --silent travis:config:base",
17 | "travis:config": "cd packages/eslint-config-airbnb; npm run travis",
18 | "travis:config:base": "cd packages/eslint-config-airbnb-base; npm run travis"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/DTStack/Code-Style-Guide.git"
23 | },
24 | "keywords": [
25 | "style guide",
26 | "lint",
27 | "es6",
28 | "es2015",
29 | "es2016",
30 | "es2017",
31 | "es2018",
32 | "react",
33 | "jsx"
34 | ],
35 | "author": "mumiao@dtstack.com",
36 | "license": "MIT",
37 | "bugs": {
38 | "url": "https://github.com/DTStack/Code-Style-Guide/issues"
39 | },
40 | "homepage": "https://github.com/DTStack/Code-Style-Guide",
41 | "devDependencies": {
42 | "markdownlint": "^0.24.0",
43 | "markdownlint-cli": "^0.29.0"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/react/README.md:
--------------------------------------------------------------------------------
1 | # React/JSX Style Guide
2 |
3 | *A mostly reasonable approach to React and JSX*
4 |
5 | This style guide is mostly based on the standards that are currently prevalent in JavaScript, although some conventions (i.e async/await or static class fields) may still be included or prohibited on a case-by-case basis. Currently, anything prior to stage 3 is not included nor recommended in this guide.
6 |
7 | ## Table of Contents
8 |
9 | 1. [Basic Rules](#basic-rules)
10 | 1. [Class vs `React.createClass` vs stateless](#class-vs-reactcreateclass-vs-stateless)
11 | 1. [Mixins](#mixins)
12 | 1. [Naming](#naming)
13 | 1. [Declaration](#declaration)
14 | 1. [Alignment](#alignment)
15 | 1. [Quotes](#quotes)
16 | 1. [Spacing](#spacing)
17 | 1. [Props](#props)
18 | 1. [Refs](#refs)
19 | 1. [Parentheses](#parentheses)
20 | 1. [Tags](#tags)
21 | 1. [Methods](#methods)
22 | 1. [Hooks](#hooks)
23 | 1. [Ordering](#ordering)
24 | 1. [`isMounted`](#ismounted)
25 |
26 | ## Basic Rules
27 |
28 | - Only include one React component per file.
29 | - However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless).
30 | - Always use JSX syntax.
31 | - Do not use `React.createElement` unless you’re initializing the app from a file that is not JSX.
32 | - [`react/forbid-prop-types`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md) will allow `arrays` and `objects` only if it is explicitly noted what `array` and `object` contains, using `arrayOf`, `objectOf`, or `shape`.
33 |
34 | ## Class vs `React.createClass` vs stateless
35 |
36 | - If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass`. eslint: [`react/prefer-es6-class`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md)
37 |
38 | ```jsx
39 | // bad
40 | const Listing = React.createClass({
41 | // ...
42 | render() {
43 | return
;
52 | }
53 | }
54 | ```
55 |
56 | And if you don’t have state or refs, prefer normal functions (not arrow functions) over classes:
57 |
58 | ```jsx
59 | // bad
60 | class Listing extends React.Component {
61 | render() {
62 | return
{this.props.hello}
;
63 | }
64 | }
65 |
66 | // bad (relying on function name inference is discouraged)
67 | const Listing = ({ hello }) => (
68 |
{hello}
69 | );
70 |
71 | // good
72 | function Listing({ hello }) {
73 | return
{hello}
;
74 | }
75 | ```
76 |
77 | ## Mixins
78 |
79 | - [Do not use mixins](https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html).
80 |
81 | > Why? Mixins introduce implicit dependencies, cause name clashes, and cause snowballing complexity. Most use cases for mixins can be accomplished in better ways via components, higher-order components, or utility modules.
82 |
83 | ## Naming
84 |
85 | - **Extensions**: Use `.jsx` extension for React components. eslint: [`react/jsx-filename-extension`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md)
86 | - **Filename**: Use camelCase for filenames. E.g., `reservationCard.jsx`. React filenames: [`filename-rule`](https://dtstack.yuque.com/rd-center/sm6war/fhg5vx)
87 | - **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md).
88 |
89 | ```jsx
90 | // bad
91 | import reservationCard from './ReservationCard';
92 |
93 | // good
94 | import ReservationCard from './ReservationCard';
95 |
96 | // bad
97 | const ReservationItem = ;
98 |
99 | // good
100 | const reservationItem = ;
101 | ```
102 |
103 | - **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name:
104 |
105 | ```jsx
106 | // bad
107 | import Footer from './Footer/Footer';
108 |
109 | // bad
110 | import Footer from './Footer/index';
111 |
112 | // good
113 | import Footer from './Footer';
114 | ```
115 |
116 | - **Higher-order Component Naming**: Use a composite of the higher-order component’s name and the passed-in component’s name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`.
117 |
118 | > Why? A component’s `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening.
119 |
120 | ```jsx
121 | // bad
122 | export default function withFoo(WrappedComponent) {
123 | return function WithFoo(props) {
124 | return ;
125 | }
126 | }
127 |
128 | // good
129 | export default function withFoo(WrappedComponent) {
130 | function WithFoo(props) {
131 | return ;
132 | }
133 |
134 | const wrappedComponentName = WrappedComponent.displayName
135 | || WrappedComponent.name
136 | || 'Component';
137 |
138 | WithFoo.displayName = `withFoo(${wrappedComponentName})`;
139 | return WithFoo;
140 | }
141 | ```
142 |
143 | - **Props Naming**: Avoid using DOM component prop names for different purposes.
144 |
145 | > Why? People expect props like `style` and `className` to mean one specific thing. Varying this API for a subset of your app makes the code less readable and less maintainable, and may cause bugs.
146 |
147 | ```jsx
148 | // bad
149 |
150 |
151 | // bad
152 |
153 |
154 | // good
155 |
156 | ```
157 |
158 | ## Declaration
159 |
160 | - Do not use `displayName` for naming components. Instead, name the component by reference.
161 |
162 | ```jsx
163 | // bad
164 | export default React.createClass({
165 | displayName: 'ReservationCard',
166 | // stuff goes here
167 | });
168 |
169 | // good
170 | export default class ReservationCard extends React.Component {
171 | }
172 | ```
173 |
174 | ## Alignment
175 |
176 | - Follow these alignment styles for JSX syntax. eslint: [`react/jsx-closing-bracket-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) [`react/jsx-closing-tag-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md)
177 |
178 | ```jsx
179 | // bad
180 |
182 |
183 | // good
184 |
188 |
189 | // if props fit in one line then keep it on the same line
190 |
191 |
192 | // children get indented normally
193 |
197 |
198 |
199 |
200 | // bad
201 | {showButton &&
202 |
203 | }
204 |
205 | // bad
206 | {
207 | showButton &&
208 |
209 | }
210 |
211 | // good
212 | {showButton && (
213 |
214 | )}
215 |
216 | // good
217 | {showButton && }
218 |
219 | // good
220 | {someReallyLongConditional
221 | && anotherLongConditional
222 | && (
223 |
227 | )
228 | }
229 |
230 | // good
231 | {someConditional ? (
232 |
233 | ) : (
234 |
238 | )}
239 | ```
240 |
241 | ## Quotes
242 |
243 | - Always use double quotes (`"`) for JSX attributes, but single quotes (`'`) for all other JS. eslint: [`jsx-quotes`](https://eslint.org/docs/rules/jsx-quotes)
244 |
245 | > Why? Regular HTML attributes also typically use double quotes instead of single, so JSX attributes mirror this convention.
246 |
247 | ```jsx
248 | // bad
249 |
250 |
251 | // good
252 |
253 |
254 | // bad
255 |
256 |
257 | // good
258 |
259 | ```
260 |
261 | ## Spacing
262 |
263 | - Always include a single space in your self-closing tag. eslint: [`no-multi-spaces`](https://eslint.org/docs/rules/no-multi-spaces), [`react/jsx-tag-spacing`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md)
264 |
265 | ```jsx
266 | // bad
267 |
268 |
269 | // very bad
270 |
271 |
272 | // bad
273 |
275 |
276 | // good
277 |
278 | ```
279 |
280 | - Do not pad JSX curly braces with spaces. eslint: [`react/jsx-curly-spacing`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md)
281 |
282 | ```jsx
283 | // bad
284 |
285 |
286 | // good
287 |
288 | ```
289 |
290 | ## Props
291 |
292 | - Always use camelCase for prop names.
293 |
294 | ```jsx
295 | // bad
296 |
300 |
301 | // good
302 |
307 | ```
308 |
309 | - Omit the value of the prop when it is explicitly `true`. eslint: [`react/jsx-boolean-value`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md)
310 |
311 | ```jsx
312 | // bad
313 |
316 |
317 | // good
318 |
321 |
322 | // good
323 |
324 | ```
325 |
326 | - Always include an `alt` prop on `` tags. If the image is presentational, `alt` can be an empty string or the `` must have `role="presentation"`. eslint: [`jsx-a11y/alt-text`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md)
327 |
328 | ```jsx
329 | // bad
330 |
331 |
332 | // good
333 |
334 |
335 | // good
336 |
337 |
338 | // good
339 |
340 | ```
341 |
342 | - Do not use words like "image", "photo", or "picture" in `` `alt` props. eslint: [`jsx-a11y/img-redundant-alt`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md)
343 |
344 | > Why? Screenreaders already announce `img` elements as images, so there is no need to include this information in the alt text.
345 |
346 | ```jsx
347 | // bad
348 |
349 |
350 | // good
351 |
352 | ```
353 |
354 | - Avoid using an array index as `key` prop, prefer a stable ID. eslint: [`react/no-array-index-key`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md)
355 |
356 | > Why? Not using a stable ID [is an anti-pattern](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318) because it can negatively impact performance and cause issues with component state.
357 |
358 | We don’t recommend using indexes for keys if the order of items may change.
359 |
360 | ```jsx
361 | // bad
362 | {todos.map((todo, index) =>
363 |
367 | )}
368 |
369 | // good
370 | {todos.map(todo => (
371 |
375 | ))}
376 | ```
377 |
378 | - Use spread props sparingly.
379 | > Why? Otherwise you’re more likely to pass unnecessary props down to components. And for React v15.6.1 and older, you could [pass invalid HTML attributes to the DOM](https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html).
380 |
381 | Exceptions:
382 |
383 | - HOCs that proxy down props and hoist propTypes
384 |
385 | ```jsx
386 | function HOC(WrappedComponent) {
387 | return class Proxy extends React.Component {
388 | Proxy.propTypes = {
389 | text: PropTypes.string,
390 | isLoading: PropTypes.bool
391 | };
392 |
393 | render() {
394 | return
395 | }
396 | }
397 | }
398 | ```
399 |
400 | - Spreading objects with known, explicit props.
401 |
402 | ```jsx
403 | export default function Foo {
404 | const props = {
405 | text: '',
406 | isPublished: false
407 | }
408 |
409 | return ();
410 | }
411 | ```
412 |
413 | ```jsx
414 | // bad
415 | render() {
416 | const { irrelevantProp, ...restProps } = this.props;
417 | return
418 | }
419 |
420 | // good
421 | render() {
422 | const { irrelevantProp, ...restProps } = this.props;
423 | return
424 | }
425 | ```
426 |
427 | ## Refs
428 |
429 | - Always use ref callbacks in Class Component. eslint: [`react/no-string-refs`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md)
430 |
431 | ```jsx
432 | // bad
433 |
436 |
437 | // good
438 | { this.myRef = ref; }}
440 | />
441 | ```
442 |
443 | ## Parentheses
444 |
445 | - Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/jsx-wrap-multilines`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md)
446 |
447 | ```jsx
448 | // bad
449 | render() {
450 | return
451 |
452 | ;
453 | }
454 |
455 | // good
456 | render() {
457 | return (
458 |
459 |
460 |
461 | );
462 | }
463 |
464 | // good, when single line
465 | render() {
466 | const body =
hello
;
467 | return {body};
468 | }
469 | ```
470 |
471 | ## Tags
472 |
473 | - Always self-close tags that have no children. eslint: [`react/self-closing-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md)
474 |
475 | ```jsx
476 | // bad
477 |
478 |
479 | // good
480 |
481 | ```
482 |
483 | - If your component has multiline properties, close its tag on a new line. eslint: [`react/jsx-closing-bracket-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md)
484 |
485 | ```jsx
486 | // bad
487 |
490 |
491 | // good
492 |
496 | ```
497 |
498 | ## Methods
499 |
500 | - Use arrow functions to close over local variables. It is handy when you need to pass additional data to an event handler. Although, make sure they [do not massively hurt performance](https://www.bignerdranch.com/blog/choosing-the-best-approach-for-react-event-handlers/), in particular when passed to custom components that might be PureComponents, because they will trigger a possibly needless rerender every time.
501 |
502 | ```jsx
503 | function ItemList(props) {
504 | return (
505 |