e . l o g ( ' A ' ) ; c o n s o l e . l o g ( ' B ' ) ; s e t T i m e o u t ( ( ) = > { c o n s o l e . l o g ( ' C ' ) ; } , 1 0 0 0 ) ; s e t T i m e o u t ( ( ) = > { c o n s o l e . l o g ( ' D ' ) ; } ) ; c o n s o l e . l o g ( ' E ' ) ;
v a r f s = r e q u i r e ( ' f s ' ) ; f o r ( v a r i = 0 ; i < f i l e s . l e n g t h ; i + + ) { / / C a l l i n g s y n c h r o n o u s f u n c t i o n d a t a = f s . r e a d F i l e S y n c ( f i l e s [ i ] ) ; c o n s o l e . l o g ( ' C o n t e n t s = ' , d a t a ) ; } Consider using async alternatives instead. f s . r e a d F i l e ( f i l e n a m e , ' u t f 8 ' , ( e r r , d a t a ) = > { / / D o s o m e t h i n g h e r e } ) ;
r e ( ) & i m p o r t calls belong to the top; not in the middle of code. a p p . g e t ( " / a p i / s o m e t h i n g " , f u n c t i o n ( r e q , r e s ) { v a r d a t a s t o r e = r e q u i r e ( " m y D a t a S t o r e D e p " ) ( s o m e C o n f i g ) ; d a t a s t o r e . g e t ( r e q . q u e r y . s o m e K e y ) . . . } ) ; Why? Because they're synchronous and blocking.
awesome for IO bound tasks. But what about CPU intensive works? Delegate them to queues or worker processes dedicated to do those work. PS: Avoid thinking of multithreading as a workaround.
could lead to callback hell. g e t D a t a ( f u n c t i o n ( x ) { g e t M o r e D a t a ( x , f u n c t i o n ( y ) { g e t M o r e D a t a ( y , f u n c t i o n ( z ) { g e t E v e n t M o r e D a t a ( z , f u n c t i o n ( ) { / / A n d e v e n m o r e . . . } ) ; } ) ; } ) ; } ) ;
x p o r t f u n c t i o n g e t P r o j e c t s B y C o m p a n i e s ( a u t h , c o m p a n y I d s ) l e t p r o m i s e s = c o m p a n y I d s . m a p ( c o m p a n y I d = > g e t P r o j e c t s B y C o m p a n y ( a u t h , c o m p a n y I d ) ) ; r e t u r n P r o m i s e . a l l ( p r o m i s e s ) . t h e n ( f o r m a t R e s u l t s ) ; } f u n c t i o n g e t P r o j e c t s B y C o m p a n y ( t o k e n , c o m p a n y I d ) { l e t u r l = ` / p r o j e c t s ? c o m p a n y _ i d = $ { c o m p a n y I d } ` ; r e t u r n r p ( { m e t h o d : ' G E T ' , u r l : B A S E _ U R I + u r l } ) ; } f u n c t i o n f o r m a t R e s u l t s ( d a t a ) { r e t u r n d a t a . r e d u c e ( ( p r e v , c u r ) = > p r e v . c o n c a t ( c u r ) , [ ] ) ; }
i t And the ES7 adds a better syntatic sugar to the language using a s y n c / a w a i t . i m p o r t r p f r o m ' r e q u e s t p r o m i s e ' ; a s y n c f u n c t i o n r e q u e s t A l l ( u r l s ) { l e t r e s u l t = a w a i t P r o m i s e . a l l ( u r l s . m a p ( u r l = > r p ( u r l ) ) ) ; r e t u r n r e s u l t ; } c o n s t u r l s = [ ' h t t p s : / / w w w . g o o g l e . c o m ' , ' h t t p s : / / w w w . a p p l e . c o m ' , ' h t t p s : / / w w w . y a h o o . c o m ' ] ; l e t s i t e s = r e q u e s t A l l ( u r l s ) ;
s for your tasks You might not task runners like g u l p all the time. Mostly n p m s c r i p t s would suffice. " s c r i p t s " : { " s t a r t " : " n o d e m o n e x e c b a b e l n o d e s r c / i n d e x . j s " , " s t a r t : s y s t e m d " : " s y s t e m c t l s t a r t o n t a r g e t m o d e l a p i . s e r v i c " l i n t " : " e s l i n t . " , " c l e a n " : " r m r a f d i s t / " , " b u i l d " : " r u n s c l e a n b a b e l " , " r e s t a r t " : " s y s t e m c t l r e s t a r t o n t a r g e t m o d e l a p i . s e r v i c e " " s t o p " : " s y s t e m c t l s t o p o n t a r g e t m o d e l a p i . s e r v i c e " , " l o g s " : " j o u r n a l c t l f u o n t a r g e t m o d e l a p i . s e r v i c e " , " b a b e l " : " b a b e l s r c / d d i s t / " } , $ n p m s t a r t # o r y a r n s t a r t
b i n / e n v b a s h # G e t t h e b r a n c h n a m e f r o m t h e e n v i r o n m e n t , d e f a u l t s t o ' d e v ' i f [ z " $ B R A N C H " ] ; t h e n B R A N C H = " d e v " f i # C h e c k o u t t o t h e s p e c i f i e d b r a n c h g i t f e t c h g i t c h e c k o u t " $ B R A N C H " # P u l l t h e l a t e s t c h a n g e s g i t p u l l o r i g i n " $ B R A N C H " # B u i l d t h e a p p l i c a t i o n n p m r u n b u i l d ; s y s t e m c t l r e s t a r t " $ S E R V I C E " . . .
p t s Create your complex scripts in separate files and register n p m s c r i p t s for them. You may use s h , p y t h o n , j s etc anything to write your scripts. " s c r i p t s " : { " d e p l o y " : " . / s c r i p t s / d e p l o y . s h " " , " b u i l d " : " . / s c r i p t s / b u i l d . p y " , " a b c " : " . / s c r i p t s / a b c . j s " } Now run your script $ n p m r u n d e p l o y You might want to use packages like shelljs for these.
t your javascript code with something like e s l i n t . And ensure the linter doesn't throw any errors before you commit. p a r s e r : ' b a b e l e s l i n t ' e n v : e s 6 : t r u e n o d e : t r u e p a r s e r O p t i o n s : e c m a V e r s i o n : 6 , s o u r c e T y p e : ' m o d u l e ' e c m a F e a t u r e s : m o d u l e s : t r u e
s r c / your source files s e r v e r / server side code a p p / clientside app code (if in the same repository) d i s t / or b u i l d / compiled files from the source (in case you use ES6+, typescript, coffeescriptetc). And, should be added to g i t i g n o r e . p u b l i c / in case you have files to be served publicly. r e s o u r c e s / other miscellaneous projects resources or files
this: s r c / s e r v e r / c o n f i g / c o n t r o l l e r s / s e r v i c e s m i d d l e w a r e s m o d e l s / v i e w s / i n d e x . j s a p p / i n d e x . j s d i s t / p u b l i c / b u i l d / i n d e x . h t m l r e s o u r c e s / s c r i p t s / d a t a /
all your config params. / / c o n f i g . j s m o d u l e . e x p o r t s = { b u c k e t P o l i c y : p r o c e s s . e n v . B U C K E T _ P O L I C Y | | ' t r a n s i e n t ' n i o s : { b a s e U r i : p r o c e s s . e n v . N I O S _ B A S E _ U R I , . . . } , p r o c o r e : { c l i e n t S e c r e t : p r o c e s s . e n v . P R O C O R E _ C L I E N T _ S E C R E T , r e d i r e c t U r i : p r o c e s s . e n v . P R O C O R E _ R E D I R E C T _ U R I , . . . } , . . . } ;
g n o r e d files or use environment variables. NEVER store your deploy specific credentials eg: database login, Google OAuth credentials, S3 client secret etc. in your codebase. Firstly, it's not secure. Secondly, they might be different for each deployment. And, it makes deploying really difficult.
deploy specific configurations & credentials. N O D E _ E N V = d e v e l o p m e n t D B _ U S E R N A M E = k a b i r D B _ P A S S W O R D = k a b i r . . . Now in your application you can do m o d u l e . e x p o r t s = { e n v : p r o c e s s . e n v . N O D E _ E N V , d a t a b a s e : { n a m e : p r o c e s s . e n v . D B _ N A M E , u s e r n a m e : p r o c e s s . e n v . D B _ U S E R N A M E , . . . } . . . } ;
m a n $ y a r n a d d f o r e m a n d e v Now you may put your environment variables in a g i t i g n o r e d . e n v file. And f o r e m a n would load them into p r o c e s s . e n v if you run your application using n f s t a r t . (development only) $ n f s t a r t [ O K A Y ] L o a d e d E N V . e n v F i l e a s K E Y = V A L U E F o r m a t 1 0 : 4 4 : 1 3 P M w e b . 1 | > n o d e j s s a m p l e a p p @ 0 . 0 . 1 s t a r t / h o m e / k a b 1 0 : 4 4 : 1 3 P M w e b . 1 | > n o d e m o n e x e c b a b e l n o d e s r c / i n d e x . j s 1 0 : 4 4 : 1 3 P M w e b . 1 | [ n o d e m o n ] 1 . 1 1 . 0 1 0 : 4 4 : 1 3 P M w e b . 1 | [ n o d e m o n ] t o r e s t a r t a t a n y t i m e , e n t e r ` 1 0 : 4 4 : 1 3 P M w e b . 1 | [ n o d e m o n ] w a t c h i n g : * . * 1 0 : 4 4 : 1 3 P M w e b . 1 | [ n o d e m o n ] s t a r t i n g ` b a b e l n o d e s r c / i n d e x . 1 0 : 4 4 : 1 4 P M w e b . 1 | i n f o : L i s t e n i n g o n p o r t 3 0 0 0
c o r s f r o m ' c o r s ' ; i m p o r t e x p r e s s f r o m ' e x p r e s s ' ; i m p o r t m o r g a n f r o m ' m o r g a n ' ; i m p o r t P r o m i s e f r o m ' b l u e b i r d ' ; i m p o r t c o n f i g f r o m ' . / c o n f i g / c o n f i g ' ; i m p o r t r o u t e s f r o m ' . / r o u t e s ' ; i m p o r t { s t a r t } f r o m ' . / s e r v i c e / s e r v e r ' ; i m p o r t { e n s u r e E v e r y t h i n g G o o d } f r o m ' . / s e r v i c e / e n s u r e ' ; l e t a p p = e x p r e s s ( ) ; c o n s t P O R T = p r o c e s s . e n v . P O R T | | 8 0 0 0 ; a p p . u s e ( m o r g a n ( c o n f i g . m o r g o n F o r m a t ( a p p . g e t ( ' e n v ' ) ) ) ) ; a p p . u s e ( c o r s ( ) ; a p p . u s e ( ' / a p i ' , r o u t e s ) ; . . .
the ES2015 features but not all of them. But we can still use ES6+ features in our code using transpilers like b a b e l $ y a r n a d d d e v b a b e l c l i b a b e l p r e s e t e s 2 0 1 5
for NodeJS projects e x p r e s s c o r s m o r g a n b l u e b i r d r e q u e s t r e q u e s t p r o m i s e l o d a s h m o m e n t b o d y p a r s e r w i n s t o n m u l t e r
improve your development experience b a b e l c l i e s l i n t n o d e m o n f o r e m a n n p m r u n a l l s h e l l j s p m 2 d e v t o o l n o d e i n s p e c t o r