We, at Cloudways, constantly try to add more features to our growing number of services. As such, we are enabling NodeJS as a service. Users now have access to the Node Package Manager (NPM).
Getting Started
Before proceeding further, we think it is important that the readers understand some common terms:
NodeJS
NodeJS is a server-side JS environment for web apps. For those who want to start writing server-side code using JS instead of PHP, Python, and Ruby, this is great news.
NodeJS Package Manager (NPM)
NPM is the dependency management tool that comes with NodeJS. NPM is to NodeJS what pip is to Python or ruby-gems is to Ruby. It makes it easy to download and manage NodeJS modules, removing a lot of hassle for the users.
Bower
Bower is another dependency management tool used to manage front-end (HTML/JS/CSS) packages/dependencies. It could be downloaded through NPM.
Grunt
Grunt is a JS task runner tool used for, among other things, linting, unit testing, and compiling JS.
AngularJS
AngularJS is an MVC framework for the frontend (HTML/JS). AngularJS extends HTML tag attributes with Directives. The best description of Angular JS is given on its website that says that Angular is “what HTML would have been, had it been designed for building web-apps”.
Note that AngularJS has nothing to do with NodeJS. One could make a fully functioning web app using AngularJS and PHP/Python/Ruby on the server-side.
So let’s get started.
Launch a New Project
Go ahead and launch a Cloudways server with a simple PHP stack application. SSH into the server with the master credentials and cd into the project’s public_html directory.
Run the following commands to verify that NodeJS and NPM are indeed installed.
nodejs -v npm -v
Now, let’s build a basic posts app, where anyone can come and write a post. The posts will not be saved anywhere because the app will focus on the frontend exclusively.
Create post_controller.js
var post = angular.module('PostApp', []); post.controller('PostController', function() { var pc = this; pc.post_list = ['Hello World', 'Testing']; //Class variable pc.addPost = function(){ pc.post_list.push(pc.post_text) pc.post_text = "" }; });
This app is created in AngularJS and this is the controller for the app. Using the angular module, we create an app, from which we create a controller ( that is a class as well). Please note that I have declared one function and one variable (var pc = this; this is the handle which is used to access the class itself.).
These functions and variables could be directly called from the HTML code:
- The post_list variable stores all the posts. I will bind it to an HTML element later on so that any changes to this list will result in instantaneous results in the UI.
- addPost function reads the post from the post_text (which will be passed from the HTML form) and appends it to the post_list
Update index.html
<!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> <script src="angular/post_controller.js"></script> </head> <body> <div ng-app="PostApp"> <div ng-controller="PostController as pc"> <form ng-submit="pc.addPost()"> <input type="text" ng-model="pc.post_text" size="30" placeholder="New post..."> <input class="btn-primary" type="submit" value="add"> </form> <p> Total posts: {{ pc.post_list.length }} </p> <li class="animated flash" ng-repeat="post in pc.post_list"> <p>{{ post }}</p> </li> </div> </div> </body> </html>
- ng-app=”PostApp”: I declared the app inside a div using this attribute.
- ng-controller=”PostController as pc”: This declares the Controller and assigns it an alias for easy access.
- ng-submit=”pc.addPost(): This is a trigger. When the form is submitted, the addPost function defined in the js file will be called. This call will append the post to the post_list variable.
- ng-model=”pc.post_text”: This variable maps the input box’s text with the post_text variable in the addPost function, defined in the js file.
- {{ pc.post_list.length }}: The “post_list” variable is being directly read by PostController class and calculate the length to display.
- ng-repeat=”post in pc.post_list”: This directive will loop through each of the posts in the post_list variable so that I can display them using the just created post
- {{ post }}: Variable provided by the loop discussed above.
The basic app is now complete. Let us test it out.
At this point, I will initialize NPM and NodeJS in the project’s directory.
NPM
Make sure you are in the <app_name>/public_html and run the following:
npm init npm install --save bower npm list
- The first command initializes NPM in the project. This creates a JSON, which will hold a list of all the dependencies.
- The second command installs bower. The –save switch adds the bower package to the JSON file created with the first command
- The third command lists the currently installed dependencies. This list should be similar to the packages list inside the JSON file.
The idea is that anyone who runs the project could simply get things going by running:
> npm install
This will install all of the dependencies listed in the package.json file.
Bower
At this point, you will have access to the bower binary inside the node_modules directory. Run the following commands.
> node_modules/bower/bin/bower bower init > node_modules/bower/bin/bower bower install bootstrap --save > node_modules/bower/bin/bower bower install animate.css --save > node_modules/bower/bin/bower list bower check-new Checking for new versions of the project dependencies... posts public_html ├── animate.css#3.5.2 └─┬ bootstrap#3.3.7 (latest is 4.0.0-alpha.3) └── jquery#3.1.0
- The first command initializes bower in the directory just as with “npm”. A “JSON” file will be created which will hold bower dependencies.
- The second and third commands install 2 dependencies which we’ll use to spice up our app. The “–save” switch tells bower to store these dependencies in the “JSON” file.
- Bootstrap: Used to show custom themes for the UI
- CSS: Basic animation classes
- The final commands list the currently installed dependencies.
As with npm, the “bower.json” file will be used by others to automatically install dependencies from your project using:
> bower install
Add the following lines inside the head tags in index.html:
<link rel="stylesheet" type="text/css" href="bower_components/animate.css/animate.css"> <link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap-theme.min.css"> <script src="bower_components/jquery/dist/jquery.min.js"></script> <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
Also, replace:
<li ng-repeat="post in pc.post_list">
with:
<li class="animated flash" ng-repeat="post in pc.post_list">
Reload the page, and add a few posts. The changes should be evident (newly added posts will flash for a couple of seconds, and the submit button will be blue). This was not impressive, but the point was to show how easy it is to install and manage dependencies using bower and NPM. For a big project, NPM and bower are invaluable.
Possible Workflow Strategy
- Commit JSON and package.json using your preferred SCM.
- Ignore bower_components and node_modules
- After cloning a project, users should run npm install and later bower install
Existing PHP Projects
Launch a new PHP Cloudways app and clone your project into your <app_name>/public_html using either the SFTP access or via the Git Deployment feature that Cloudways offers.
Finally, cd into your project’s public_html directory and just run,
<app_name>/public_html> npm install
If your project has a package.json file, all dependencies will be automatically installed. If the project also has a bower.json file, then additionally, run the following command to see if the bower was installed through NPM.
<app_name>/public_html> npm list
If it was, go ahead and install bower dependencies.
<app_name>/public_html> node_modules/bower/bin/bower install
Finally, you may need to recheck your includes and confirm the paths to the dependencies.
That’s it, you’re good to go.
Q: Should I install NPM for every single project?
A: You don’t have to do “npm install” every time you want to compile. You only need to do this when changing your project’s dependencies. NPM is essentially a node package manager. Installing different packages and resolving their different dependencies helps.
Q: Why is NPM installation not working?
A: The problem may be with installing the package in your global npm. While all things work just fine with running a local project with its dependencies, there may be a problem with global package installation that might not be installed or that terminal bash command can’t access the installed package.
Q: How to fix the NPM installation error?
A: Some strange issues can be resolved by simply running npm cache clean and trying again. If you are having trouble with npm install, use the -verbose option to see more details.
Q: What is the full form of NPM?
A: Npm, short for Node Package Manager, is two things: first of all, it is an open-source repository. Js projects; second, it is a command-line utility to interact with the repository that supports package installation, version management, and dependency administration.
If you need to add to the discussion or have a question, please leave a comment below.
Shahzeb Ahmed
Shahzeb is a Digital Marketer with a Software Engineering background, works as a Community Manager — PHP Community at Cloudways. He is growth ambitious and aims to learn & share information about PHP & Laravel Development through practice and experimentation. He loves to travel and explore new ideas whenever he finds time. Get in touch with him at [email protected]