Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

✏️ JavaScript Style Guide

License

NotificationsYou must be signed in to change notification settings

daisugiland/javascript-style-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There’s more than one way to do it, but sometimes consistency is not a bad thing either. (TIMTOWTDIBSCINABTE)
Now is better than never.
Although later is often better thanright now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.

* Borrowed from Python zen with slight modifications.[+]

Table of contents

Naming conventions

Folders and files

  • kebab-case for folders.

    Covers if folder will be extracted to its own package some day.[+]

  • camelCase orPascalCase for files.

    Has problems on commiting case-sensitive filename changes with Git.[+]

    ✔️ Good

    .└── src/    ├── product/    │   ├── application/    │   │   └── services/    │   │       └── SearchProductsService.js    │   ├── domain/    │   │   └── services/    │   │       └── SearchProductsBySKUService.js    │   └── infrastructure/    │       └── stores/    │           └── ProductAPIStore.js    └── app.js

    * Generated withhttps://tree.nathanfriend.io/.

  • A file that exports only one class, function, or constant should be named for that class, function or constant.

    ❌ Bad

    // file name: programstore.jsexportclassProgramStore{  ...}

    ✔️ Good

    // file name: ProgramStore.jsexportclassProgramStore{  ...}
  • Files whose exports multiple things, the file name should be kept short, meaningful and easily understandable to others.

  • Avoidindex as a file name.

    It does not reflect the content of the file.

    The file can’t live outside of the folder, because breaks the chain between folder name and file name.

    NodeJS has a special treatment forindex files, but other engines like Deno don’t.

    ❌ Bad

    .└── src/    └── program-filters/        ├── isNotOldFilter.js        ├── hasMonthlyDownloadsFilter.js        └── index.js

    ✔️ Good

    .└── src/    └── program-filters/        ├── isNotOldFilter.js        ├── hasMonthlyDownloadsFilter.js        └── programFilters.js
  • Avoid generic names for folders. Be precise.

    ❌ Bad

    .└── src/    ├── utils/    ├── config/    ├── vendors/    └── helpers/

    ✔️ Good

    .└── src/    ├── program-guards/    ├── auth/    └── logger/

🔝 back to top

Pluralization

  • Pluralize only collections.

    ❌ Bad

    classProgramsStore{constructor(){}}

    ✔️ Good

    classProgramStore{constructor(){}}

    ✔️ Good

    customers.forEach((customer)=>{  ...});
  • UsesingularPlural for a list of a single property.[+]

    ✔️ Good

    constprograms=[{id:1,},{id:2,}];constprogram=programs[0];constprogramId=1;constprogramIds=[1,2];
  • UsepluralOfSingular for a list of single item list.

    ✔️ Good

    constprogram={topics:['addons'],};consttopicsOfProgram=['addons'];
  • UsepluralOfPlural for a list of lists.

    ✔️ Good

    constprograms=[{topics:['addons'],},{topics:['skins'],}];consttopicsOfPrograms=['skins','addons'];

🔝 back to top

Variables

  • camelCase for variables.

    ❌ Bad

    constfirstname='Benadryl';constfirst_name='Benadryl';constFIRSTNAME='Benadryl';constFIRST_NAME='Benadryl';

    ✔️ Good

    constfirstName='Benadryl';

🔝 back to top

Acronyms

  • UPPERCASE for acronyms.

    Names are for readability, not to appease a computer algorithm.[+]

    ❌ Bad

    const{ XMLHttpRequest}=require('...');constxmlHttpRequest={ ...};functionrequestIpAddress(){  ...}functiondbmxmlParse(){  ...}

    ✔️ Good

    const{ XMLHTTPRequest}=require('...');constxmlHTTPRequest={ ...};functionrequestIPAddress(){  ...}functiondbmXMLParse(){  ...}

🔝 back to top

Abbreviations

  • camelCase for abbreviations.

    ❌ Bad

    constprogramID=0;// Id[entifier].constisEXEFile=true;// Exe[cutable].constandroidAPPName='Zoom';// App[lication].

    ✔️ Good

    constprogramId=0;// Id[entifier].constisExeFile=true;// Exe[cutable].constandroidAppName='Zoom';// App[lication].

🔝 back to top

Verbosity

  • Avoid use of abbreviations for naming—be verbose.

    ❌ Bad

    constaccBalInSaving=0;constdmgPerSec=100;

    ✔️ Good

    constaccountBalanceInSavings=0;constdamagePerSecond=100;

🔝 back to top

HashMaps

  • keyToValue orvalueByKey for HashMaps.

  • No rules for keys naming.

    ❌ Bad

    constmapStateCounty={CA:58,};constnumberOfCountiesIn={CA:58,};constcountyCountOf={CA:58,};

    ✔️ Good

    conststateToCountiesCount={CA:58,};constcountiesCountByState={CA:58,};

🔝 back to top

Constants

  • UPPERCASE for constants.

    Constants are string or integer literals, used as aliases for “hard-coded” values.

    ✔️ Good

    constSECONDS=60;constMINUTES=60;constHOURS=24;constDAY=SECONDS*MINUTES*HOURS;constDAYS_UNTIL_TOMORROW=1;

🔝 back to top

Booleans

  • Use affirmative names.

  • Useis,are,have,has,can,should or any other prefix which indicates a yes or no as response.[+]

    ❌ Bad

    constisUsersLoggedIn=true;

    ✔️ Good

    constisEachUserLoggedIn=true;
  • Use affirmative names.

    ❌ Bad

    constisNotActive=true;if(!isNotActive){  ...}

    ✔️ Good

    constisActive=true;if(isActive){  ...}
  • Use convenient name when the boolean is optional with negative default value.[+]

    Avoid double negatives.

    Implicit default.

    ❌ Bad

    functioncreateWidget(isEnabled=true){  ...}

    ✔️ Good

    functioncreateWidget(isDisabled){  ...}

🔝 back to top

Contextualization

  • Do not add redundant context to variable names when the context is already provided by the containing object or class.[+]

    ❌ Bad

    constproduct={productId:"XXX-XXX",productName:"book",};product.userId;

    ✔️ Good

    constuser={id:"XXX-XXX",name:"book",};product.id;
  • Do not contextualize the naming of the provided arguments to the functions.

    Easier perform massive find or replace.

    ❌ Bad

    functionfindProgramById(id){  ...}constprogramId='XXXX-XXXX';findProgramById(programId);

    ✔️ Good

    functionfindProgramById(programId){  ...}constprogramId='XXXX-XXXX';findProgramById(programId);

    ❌ Bad

    functionfindProgramById({ id}){  ...}constprogramId='XXXX-XXXX';findProgramById({id:programId});

    ✔️ Good

    functionfindProgramById({ programId}){  ...}constprogramId='XXXX-XXXX';findProgramById({ programId});

🔝 back to top

Timestamps

  • UseverbAt.

    ✔️ Good

    constcreatedAt=newDate().toISOString();constupdatedAt=newDate().toISOString();

🔝 back to top

Functions

  • camelCase for functions.

  • Recommended useverbAdjectiveContextStructureHow pattern, where verb stick to action, adjective act as modifier for a context, and context is the object being interacted with. Adjective, context, structure and how are optionals.[+]

    ❌ Bad

    functionprogramGetActiveById(programId){  ...}

    ✔️ Good

    functionfindActiveProgramById(programId){  ...}
  • Skipget prefix when function is returning a boolean.

🔝 back to top

Vocabulary

PrefixDescription
toConvert object to another type.
plusReturns a copy object with the amount added.
minusReturns a copy object with the amount subtracted.
withReturn a copy with element target.
ofReturns an instance where the factory is primarily validating the input parameters, not converting them.
fromConverts the input parameters to an instance of the target object, which may involve losing information from the input.
parseParses the input string to produce an instance of the target class.
formatUses the specified formatter to format the values in the temporal object.
atCombines this object with another.
getReturn a part of the state of the object.
listReturn a collection of part of the state of the object.
createReturns a new instance on each invocation.
buildReturns a new instance where many separate pieces of information are combined in some way.
generateReturns a new instance where a calculation is used to produce a value from an input.

Partial borrowed from oracle documentation.[+]

🔝 back to top

Constructors

  • PascalCase for constructors.

    ✔️ Good

    classGoodGreeter{name;constructor(){this.name='hello';}}
  • Where appropriate, use a compound word for the naming. The second part of the derived name can be the name of the pattern.[+]

    ✔️ Good

    classGetItemBySlugUseCase{constructor(){}}
  • Infer context on naming class methods.

    ❌ Bad

    classProgramStore{getProgramById(programId){    ...}}

    ✔️ Good

    classProgramStore{getById(programId){    ...}}

🔝 back to top

Enumerations

  • PascalCase for enumerations and value names.[+]

  • Singular type name.

    Enumerations are used to represent a fixed number of possible values.

    ❌ Bad

    constcodes={notFound:'NotFound',badRequest:'BadRequest',};

    ✔️ Good

    constCode={NotFound:'NotFound',BadRequest:'BadRequest',};

🔝 back to top

Measures

  • Use measures as suffix.

    ❌ Bad

    constREQUEST_TIMEOUT=2000;constMIN_COMPRESSION=64;

    ✔️ Good

    constREQUEST_TIMEOUT_MS=2000;constMIN_COMPRESSION_BYTE=64;

🔝 back to top

Counts

  • Usecount as suffix to indicate quantity.[+]

    count is shorter thannumberOf.

    number is ambiguous. It could be a count, or an index, or some other number.

  • Useindex as suffix to indicate sequence number0..n.

    ❌ Bad

    constMAX_PROGRAMS=5;constPROGRAM_NUMBER=2;

    ✔️ Good

    constMAX_PROGRAM_COUNT=5;constPROGRAM_INDEX=2;

🔝 back to top

Public modules

  • Don’t use descriptive names for public modules.

    Descriptive names are anti-democratic.[+].

🔝 back to top

Asynchronous

  • Usesync suffix for synchronous function when you have asynchronous version of the same function.

    NodeJS implicit convention.[+]

  • Usewhen prefix for variables.[+]

    It sounds like the Promisethen method.

    It should mean ‘when this happens’.

    ✔️ Good

    asyncfunctionlistPrograms(){  ...}constwhenPrograms=listPrograms();constprograms=awaitwhenPrograms;

    ❌ Bad

    functionlistPrograms(){  ...}asyncfunctionlistProgramsAsync(){  ...}constwhenPrograms=listProgramsAsync();constprograms=awaitwhenPrograms;

    ✔️ Good

    functionlistProgramsSync(){  ...}asyncfunctionlistPrograms(){  ...}constwhenPrograms=listPrograms();constprograms=awaitwhenPrograms;

🔝 back to top

Generators

  • Usegen suffix when you have Generator version of the same function.

  • Useiter prefix for variables.[+]

    ❌ Bad

    function*listProgramsGen(){  ...}constiterPrograms=listProgramsGen();

    ✔️ Good

    function*listPrograms(){  ...}constiterPrograms=listPrograms();

    ✔️ Good

    asyncfunctionlistPrograms(){  ...}asyncfunction*listProgramsGen(){  ...}constiterPrograms=listProgramsGen();constprograms=[];forawait(letprogramofiterPrograms){programs.push(program);}

🔝 back to top

Formatting conventions

Curly braces

  • Delimit scope blocks with curly braces.[+]

  • Opening brace goes on the end of the current line, and the last brace in the new line.

    Known as egyptian brackets.[+]

    ❌ Bad

    if(true)doSomething();

    ✔️ Good

    if(true){doSomething();}

🔝 back to top

Block scopes

  • Space between block scopes.

    ❌ Bad

    if(true){doSomething();}if(true){doSomethingElse();}

    ✔️ Good

    if(true){doSomething();}if(true){doSomethingElse();}

🔝 back to top

Programming practices

  • Be consistent with existing code.

🔝 back to top

Exports

  • Use named exports.

    To avoid interoperational problems between ES Modules and CommonJS.[+]

    ❌ Bad

    exportdefaultclassMyClass{  ...}

    ✔️ Good

    exportclassMyClass{  ...}

🔝 back to top

Functions

  • Use function syntax for functions.

    In general function syntax is preferred, in particular for top level functions (to avoid TDZ issues,export const foo = () => {} function will not be available to be called unless the module where it came from has already been evaluated, otherwise you'll get the temporal dead zone error, happens with circular dependencies).[+]

  • Use arrow functions for callbacks.

    Arrow syntax should be limited to closures.

🔝 back to top

Decorations

  • Avoid use of annotations for decorations.

    Are executed at time of interpretation, that could create inconvenience when you are injecting dependencies which need be initialized at tame of class instance creation (e.g.: happens on resolving with auto-wire).

    ❌ Bad

    classMyClass{  @decorate()doStuff(){    ...}}

    ✔️ Good

    classMyClass{constructor(){this.doStuff=decorate(this.doStuff);}doStuff(){    ...}}

🔝 back to top

Interfaces

  • Use interfaces over aliases where possible.

    ❌ Bad

    typeFnAsync=(...args:any[])=>Promise<any>;

    ✔️ Good

    interfaceFnAsync{(...args:any[]):Promise<any>;}

🔝 back to top

Constructors

  • Use classes if you have more than one method and shared state.

    ❌ Bad

    classRedisClient{constructor(baseURL){    ...}create(){    ...}}constredisClient=newRedisClient(baseURL);constcacheClient=redisClient.create();

    ✔️ Good

    functioncreateRedisClientCreator(baseURL){returnfunctioncreateRedisClient(){    ...}}constcreateRedisClient=createRedisClientCreator(baseURL);constcacheClient=createRedisClient();

🔝 back to top

Monorepos

  • Every package should contain all the needed dependencies.

    Doing this allows us to cleanly decouple projects (packages) from one another, since you don't have to merge all their dependencies in one huge unmaintainable list.[+]

🔝 back to top

Comments

  • Comments are code smell, when comment describes what the code is doing.

    From a philosophical point of view, each line of code contains a technical debt for further support. Only the final functionality is the value. And if you can implement it without a single line (of commentary) at all, then everything is perfect. Otherwise, you should always have theWHY /WHY motive you added it for. Theoretically, this motive should be indicated in the commentary. TheWHAT question is usually resolved by meaningful of the identifiers of classes, functions and variables. The questionHOW should be clear from the code itself (also theoretically).[+][++]

🔝 back to top

Composition

  • Use composition over inheritance.

🔝 back to top

Goal

If we start from the fact that programming is a chain of taking decisions, the aim of this guide is to inspire you and facilitate to take such decisions.

Following guide is a set of different sources most of them conveniently linked.

🔝 back to top

Other projects

  • Daisugi is a minimalist functional middleware engine.
  • Kintsugi is a set of utilities to help build a fault tolerant services.
  • Kado is a minimal and unobtrusive inversion of control container.
  • Oza is a fast, opinionated, minimalist web framework for NodeJS.

🔝 back to top

License

MIT

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp