├── .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 |
175 | ); 176 | } 177 | 178 | export default withStyles(() => styles)(MyComponent); 179 | 180 | // good 181 | function MyComponent({ styles }) { 182 | return ( 183 |
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 | 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
{this.state.hello}
; 44 | } 45 | }); 46 | 47 | // good 48 | class Listing extends React.Component { 49 | // ... 50 | render() { 51 | return
{this.state.hello}
; 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 |