-
Clone https://github.com/Walkover-Web-Solution/Giddh-New-Angular4-App.git.
-
This project requires Node version 14+, install Node from here.
-
Go inside the cloned directory
Giddh-New-Angular4-App
in any terminal and run these following commands in the terminal to install dependency and start local serve. -
Run
npm i
for installation of dependencies. -
You need to add a
.env
file at the root of the project (similar to.env.example
already present at the root) which is used to store credentials related to Google, Razorpay. You can get the.env
file from any of the contributors of this project. -
Run
npm run start
to local serve the project.
Before contributing it is required that you should have a proper knowledge of Git. If you're unfamiliar with Git you should first visit the recommended Udacity Git course.
Giddh has 4 environments TEST
, STAGE
, BETA
and PROD
. Any feature/bug needs to be deployed first on TEST
env. for testing, once the feature/bug is ready for production it needs to be deployed on rest of the higher environments. Below is the flow that any new feature/bug needs to cover in order for it to be marked as complete:
feature/bug
--> giddh-2.0
--> beta-stage
--> beta-branch
--> production
Branch beta-stage
is considered to be the parent branch of all the new branches. This is the clean branch for development. Every contributor is required to check out their new branch from this branch only for both feature & bug.
Feature F1 deployment cycle:
- Checkout a new branch named
<card-id>-stage
(where<card-id>
needs to be replaced by Clickup card ID) frombeta-stage
. For eg:dtqvbd-stage
- Complete your development on branch
dtqvbd-stage
- Proceed to deployment of
dtqvbd-stage
togiddh-2.0
(TEST env.) - If conflicts occur follow below rules as per your scenario:
- If PR from
dtqvbd-stage
->giddh-2.0
has conflict -> Checkout a new branchdtqvbd-test
fromgiddh-2.0
and take a pull fromdtqvbd-stage
and resolve conflicts in branchdtqvbd-test
; raise PR fromdtqvbd-test
togiddh-2.0
- If PR from
dtqvbd-stage
->beta-stage
has conflict -> Take a pull frombeta-stage
to branchdtqvbd-stage
and resolve conflicts in it; raise PR fromdtqvbd-stage
->beta-stage
- If PR from
beta-stage
->beta-branch
has conflict -> Checkout a new branchdtqvbd-beta
frombeta-branch
and take a pull frombeta-stage
; raise PR fromdtqvbd-beta
tobeta-branch
- If PR from
beta-branch
->production
has conflict -> Checkout a new branchdtqvbd-prod
fromproduction
and take a pull frombeta-branch
; raise PR fromdtqvbd-prod
toproduction
- IN NO CASE YOUR BRANCH
dtqvbd-stage
SHOULD TAKE A PULL FROMgiddh-2.0
AND RESOLVING MERGE CONFLICTS DIRECTLY ON GITHUB IS STRICTLY PROHIBITED
- If PR from
- Once PR is merged, provide your feature/bug on TEST env. for testing to tester
- If issues are raised in testing: tester raises issue I1 for developer; F1 card is assigned back to the developer for issue fixing
- I1 issue should be fixed on
dtqvbd-stage
by developer: if branchdtqvbd-stage
has conflict withgiddh-2.0
-> follow Step 4.1 above - I1 is tested and F1 card is READY FOR PROD; raise PR from
dtqvbd-stage
->beta-stage
- Once
dtqvbd-stage
is merged tobeta-stage
, raise PR frombeta-stage
tobeta-branch
(follow Step 4 above in case of merge conflicts) - Once
beta-stage
is merged tobeta-branch
, raise PR frombeta-branch
toproduction
(follow Step 4 above in case of merge conflicts)
All of the changes must be present on a single branch <card-id>-stage
which will act as a single source of truth for that feature/bug for other branches
dtqvbd-stage
-> beta-stage
-> beta-branch
-> production
If you face any issues in the understanding of contributing guideline then please reach out to other contributors first than trying it out for yourself. If you have any suggestions for the improvement of this guideline then also you're welcome :)
For Giddh desktop builds, we support Windows and Mac platforms. For signing Windows build:
- You need to have the certificate in CER format. Usually, the certificates are available in CRT format. To convert from CRT to CER format follow below steps (use Windows system):
- Double-click on the yourwebsite.crt file to open it into the certificate display.
- Click on the Details tab, and then select the Copy to file button.
- Click Next in the certificate wizard.
- Choose Base-64 encoded X.509 (.CER), and then click on Next.
- Now, browse to store your file and type in the filename that you want to keep
- Finally, save the file.
- Once the CER format is obtained, convert this to PFX extension for it to be used in Electron builder variables. Command to run (use Windows system) for conversion:
openssl pkcs12 -export -in path/to/yourcertificate.cer -out desitnation/for/yourcertificate.pfx -nokeys
This command will ask for password, make sure you set a rememberable password.
- Once the .pfx certificate is obtained, we need to update the Github Action secret variable
CSC_LINK_WIN
with its downloadable link. Upload the file on Google Drive, and get the downloadable link by pasting the G-Drive link (public link) on direct link generator. The link obtained from here should be set inCSC_LINK_WIN
. - Set the variable
CSC_LINK_WIN_PASS
with the password that you've set in step 3.
This is a guide to Angular syntax, conventions, and application structure. This style guide presents preferred conventions to write scalable Angular Apps with syntax that is easy to read, understand, and navigate through.
NOTE: Most of it is inherited from Angular-Style Guide.
-
Use consistent names for all files/symbols is a must.
-
Name your files/symbols following the convention of feature.type.extension.
-
File names must be separated with dots and dashes.
-
Feature and Folder Name must describe the feature it is made for. It must be hyphenate/dash-case. For eg. if I had a Component named
StyleGuide
, my feature name would bestyle-guide
and the folder in which this file resides would also be namedstyle-guide
. -
File Type must tell about the contents of the file. It can be any of the following:
module
| component
| directive
| pipe
| service
| model
| class
| interface
| const
| config
| spec
| e2e-spec
- File Extension can be any of the following:
ts
| js
| css
| scss
| json
| map
| ico
| hbs
| rules
| md
-
End to End test case files should be named like
app.e2e-spec.ts
-
Class names must be in PascalCase/UpperCamelCase. So
app.component.ts
should have a file namedAppComponent
. -
Consts should be declared in UPPER_SNAKE_CASE. So a const that contains configuration for your project may be named FIREBASE_CONFIG for eg.
-
Interfaces must be declared in PascalCase/UpperCamelCase. Interface names should not be prepended with an I as TypeScript guidelines discourage the I prefix. If there's an interface for machine, then it should be named as
Machine
for instance. -
Observables should have a $ sign appended after their names so that they could be useful when scanning through code and looking for observable values. A variable named stopwatchValue that may contain an observable value may be named
stopwatchValue$
for instance. -
Property and method names should be in camelCase.
-
Don't use _ before private property or method names.
-
File Grouping - Create a folder for a feature when it has multiple accompanying files (
.ts
,.html
,.scss
and.spec
). Any entity or building block, that has multiple files for it, should reside in a folder of its own. For eg. if a Component namedStyleGuide
has a component class file(component), a template file(html), a style file(scss), and a test case file(spec), then all these 4 files must reside under the folder namedstyle-guide
. -
Create a folder for an entity/feature if it has more than one files associated with it.
-
Create folders named for the feature area they represent.
-
Always use Angular CLI for all the file creation. This helps create files with the best and recommended conventions possible.
-
Name the feature module symbol reflecting the name of the feature area, folder, and file; for example,
app/cart/cart.module.ts
definesCartModule
.
Apply the Single Responsibility Principle(SRP) to all components, services, and other symbols. This helps make the app cleaner, easier to read and maintain, and more testable. In order to do just that, keep the following points in mind:
-
Define just one thing per file. Thing here can either be class, style, tests, template etc. For eg. if a Component named StyleGuide needs to have a component class, a template file(html), some styles and tests, 4 different files should be created for each of the code type.
-
Files must not be more than 400 lines of code. If a file exceeds 400 lines, break it into two separate blocks, thus creating two separate files.
-
A file must have a single responsibility. If you need to bootstrap an Angular App, define a model object, create a component and load data from the server for eg., create 4 files: a
main.ts
file to bootstrap the App, adata.model.ts
file to define the model object, acomponent-name.component.ts
file for defining the component, and adata.service.ts
file to fetch data from the server. And it goes without saying that it will again follow the File Grouping rule. -
Platform and Bootstrapping logic should be a part of
main.ts
file. -
Application logic should reside in a Component or a Service.
Just like files, functions also follow the single responsibility princinple. Define small functions. A function should be no more than 75 lines.
-
Variable declarations that aren't reassigned must be declared as const.
-
Interfaces should be used for Data Models instead of classes.
-
Leave one empty line between third party imports and application imports.
-
Import lines must always be listed in alphabetical order.
-
Destructured symbols must be arranged alphabetically.
-
Import symbols from their closest locations instead of importing everything from their parent module.
-
All of the app's code goes in a folder named
src
. -
Keep related files near each other in an intuitive location. For eg. if you're building an e-commerce App, keep all files related to cart in a folder named cart.
-
Psychologists believe that humans start to struggle when the number of adjacent interesting things exceeds nine. So when a folder has ten or more files, it may be time to create subfolders. Create sub-folders when a folder reaches seven or more files.
-
Configure the IDE to hide distracting, irrelevant files such as generated
.js
and.js.map
files. -
Keep a flat folder structure as long as possible.
-
Try to be DRY (Don't Repeat Yourself). But avoid being so DRY that you sacrifice readability. For example, it's redundant to name a template
cart-view.component.html
because with the.html
extension, it is obviously a view. But if something is not obvious or departs from a convention, then spell it out.
-
Create an NgModule for each feature area.
-
All feature areas should be in their own folder, with their own NgModule.
-
Name the module the same as the folder it is placed in.
-
Create dedicated modules for cases like routing, using third party packages like Angular Material, Firebase etc.
-
Create a feature module named
SharedModule
in ashared
folder; for example,app/shared/shared.module.ts
definesSharedModule
. -
Declare components, directives, and pipes in a shared module when those items will be re-used and referenced by the components declared in other feature modules.
-
Use the name SharedModule when the contents of a shared module are referenced across the entire application.
-
Don't provide services in shared modules. Services are usually singletons that are provided once for the entire application or in a particular feature module. There are exceptions, however. A service that is stateless; that is, the consumers of the service aren't impacted by new instances can be declared in it.
-
Import all modules required by the assets in the
SharedModule
; for example,CommonModule
andFormsModule
. -
Don't specify app-wide singleton providers in a
SharedModule
. Intentional singletons are OK. Take care.
-
Collect numerous, auxiliary, single-use classes inside a core module to simplify the apparent structure of a feature module.
-
Call the application-wide core module,
CoreModule
. ImportingCoreModule
into the rootAppModule
reduces its complexity and emphasizes its role as orchestrator of the application as a whole. -
Create a feature module named
CoreModule
in acore
folder (e.g.app/core/core.module.ts
definesCoreModule
). -
Put a singleton service whose instance will be shared throughout the application in the
CoreModule
(e.g.ExceptionService
andLoggerService
). -
Import all modules required by the assets in the
CoreModule
(e.g.CommonModule
andFormsModule
). -
Gather application-wide, single use components in the
CoreModule
. Import it once (in theAppModule
) when the app starts and never import it anywhere else. (e.g.NavComponent
andSpinnerComponent
). -
Don't import the
CoreModule
anywhere except in theAppModule
. -
Export all symbols from the
CoreModule
that theAppModule
will import and make available for other feature modules to use. -
AppModule
is a little smaller because many app/root classes have moved to other modules.AppModule
is stable because you will add future components and providers to other modules, not this one.AppModule
delegates to imported modules rather than doing work.AppModule
is focused on its main task, orchestrating the app as a whole. -
Only the root
AppModule
should import theCoreModule
. Guard against reimporting ofCoreModule
and fail fast by adding guard logic. -
Put the contents of lazy loaded features in separate modules, in lazy loaded folders. A typical lazy loaded folder contains a routing component, its child components, and their related assets and modules.
-
Don't allow modules in sibling and parent folders to directly import a module in a lazy loaded feature. Directly importing and using a module will load it immediately when the intention is to load it on demand.
-
Give components an element selector, as opposed to attribute or class selectors.
-
Extract templates and styles into their own files especially when the content of the files is more than 3 lines.
-
Always name the template file
[component-name].component.html
, -
Always name the style file
[component-name].component.scss
-
Specify component-relative URLs, prefixed with
./
. -
Use the
@Input
and@Output
class decorators instead of theinputs
andoutputs
properties of the@Directive
and@Component
metadata. -
Place
@Input
or@Output
on the same line as the property it decorates. -
Don't use input and output aliases except when it serves an important purpose.
-
Put presentation logic in the component class, and not in the template.
-
Don't prefix output properties
-
Name events without the prefix
on
. -
Name event handler methods with the prefix
on
followed by the event name. -
Limit logic in a component to only that required for the view. All other logic should be delegated to services.
-
Component element selectors should be in dashed-case or kebab-case. They should always be in lowercase.
admin-users
for eg. -
Always use a custom prefix for a component selector. This can preferably be the module name itself. For example, the prefix
pb
represents Pizza Builder module and the prefixcart
represents cart module. For eg. the preview component inside a cart module would have a selector ofcart-preview
.
-
Place properties up top followed by methods.
-
Place private members after public members, alphabetized.
-
Use the
@Input
and@Output
class decorators instead of theinputs
andoutputs
properties of the@Directive
metadata. -
Use an alias only when the directive name is also an input property, and the directive name doesn't describe the property.
-
Use attribute directives when you have presentation logic without a template.
-
Use the
@HostListener
and@HostBinding
to thehost
property of the@Directive
and@Component
decorators. -
Use Renderer2 instead of ElementRef's NativeElement for DOM Manipulations.
-
Always use lowerCamelCase for naming the selectors of directives.
-
Just like components, always use a custom prefix for the selector of directives. For eg. the form-validate directive in the cart module will have a selector of
cartFormValidate
.
-
Delegate complex component logic to services
-
Move reusable logic to services and keep components simple and focused on their intended purpose.
-
Use services as singletons within the same injector. Use them for sharing data and functionality.
-
Create services with a single responsibility that is encapsulated by its context.
-
Create a new service once the service begins to exceed that singular purpose.
-
Provide a service with the app root injector in the
@Injectable
decorator of the service. -
When two different components need different instances of a service provide the service at the component level.
-
Use the
@Injectable
class decorator instead of the @Inject parameter decorator when using types as tokens for the dependencies of a service. -
Logic for making data operations and interacting with data must reside inside a service.
-
Make data services responsible for XHR calls, local storage, stashing in memory, or any other data operations.
Implement the lifecycle hook interfaces. Don't just use methods without implementing the Lifecycle Hook Interfaces.