Initially, the entry barrier into the world of Angular development was pretty high because of the need to learn and manually configure multiple tools. Even to get started with a simple application, you need to know and use the TypeScript language, the TypeScript compiler, ES6 modules, SystemJS, npm, and a development web server. To work on a real-world project, you also need to learn how to test and bundle your app.
To jumpstart the development process, the Angular team created a tool called Angular CLI (see https://github.com/angular/angular-cli), which is a command-line tool that covers all the stages of the Angular application lifecycle, from scaffolding and generating an initial app to generating boilerplate for your components, modules, services, and so on. The generated code also includes pre-configured files for unit tests and bundling with Webpack.
All this is good but a project generated by Angular CLI has a lot of dependencies that have to be downloaded and installed in the node_modules directory of your project. What’s “a lot”? Let’s use the Unix tree command to see how many files and directories exist in a project freshly generated by Angular CLI. Enter the following command in the root directory of such project:
You’ll see a nicely formatted tree structure of all packages installed in the node_modules directory ai a summary line at the end, which will look like this:
6233 directories, 38656 files
This is what I mean by a lot. Actually all is relative. It clearly a lot if you compare with the content of node_modules of a jQuery project:
7 directories, 13 files
On the hand, the rumor has it that React Native installs 120K files. The software becomes more complicated every year and we have to deal with it. Anyway, Angular CLI has already created the project with all packages installed. Now, let’s delete the node_module dir in the project and reinstall it with npm install. On my laptop it takes at least 90 seconds. Can this time be improved? Yes, if you’ll use Yarn – an alternative to npm client.
Yarn is a new package manager that can be used instead of npm package manager. The plan is to use npm one last time to install Yarn, and then npm is not needed. Here’s the command to install Yarn globally:
npm install yarn -g
Now let’s run Yarn from within the root dir of our project:
This command reads (an equivalent of npm install) the list dependencies from your package.json file and installs all of them either from npmjs.org or from local cache. It takes anywhere from about one minute on the first run to install those 38K files. on the consecutive runs (after deleting node_modules) it takes 30 seconds. This is three times faster than npm! Pretty impressive.
To create a new Angular CLI project called sampleProj you can run the following command:
ng new sampleProj
The above command will generate the boilerplate code of the project in the directory sampleProj with package.json and will immediately run npm install there. On my MacBook Pro it takes at least 90 seconds. Now that we are fans of yarn, we’d like to integrate it in the initial project generation. This could be done in three steps:
1. Instruct Angular CLI to not run npm install:
ng new --skip-install sampleProj
If you use Mac or Unix-based OS, you can combine the above three steps as follows:
ng new --skip-install sampleProj && cd $_ && yarn
The bash parameter $_ refers to the last argument of the previous command, which is sampleProj in our case. Running the above command completes in 30 seconds, which is a lot better than 90, isn’t it?
For a regular non-CLI Angular project Yarn needs about 19 seconds on the first run and 12 seconds or less thereafter. On your computer, the results may be different.
Being more performant is not the only advantage of using Yarn over npm, and you can read more about Yarn’s architecture and benefits in Yarn blog. At the time of this writing, Yarn is still at its early stages, but you can start using it today.
Angular CLI allows you to set Yarn as your default package manager so Angular CLI will use it during generation of new projects:
ng set --global packageManager=yarn
I recorded the video showing how to do this.
UPDATE: In this blog I explain how to use Yarn for the offline project generation.