How to create a npm package out of an AngularJS module

Introduction

When your project starts to grow sometimes it becames the moment when you need to split it in parts. In this tutorial we are going to cover how to create a new npm package from an AngulaJS module or project, so it can be re maintained independently or used by other projects.

We will setup AngularJS project with Grunt as a task runner. This guide will help you to setup an initial project that will only minify source code. Unit test and coverage will be left for a future tutorial.

It's required to have NPM installed in our system. we will not cover this on this tutorial, however you can check it how to install npm here.

Directory structure

When you finish this tutorial the project will be ready to ship a minified version in the dist directory. All source code will be store in the js directory (some people use src).

bower_components/
bower.json
dist/
    project-1.0.0.js
    project-1.0.0.min.js
.gitignore
Gruntfile.js
node_modules/
package.json
js/

Step 1: Starting a new package

Start an empty package with npm init, follow the wizard steps.

npm init

The wizard will create a package.json and an index.js file or call the entry point file as you like.

Step 3: Development Requirements

Install grunt-cli

sudo npm -g grunt-cli

When installing dependencies using --save-dev all installed packages will be save in the package.json file under the section development dependencies.

npm install --save-dev grunt-cli
npm install --save-dev grunt-contrib-less
npm install --save-dev grunt-contrib-cssmin
npm install --save-dev grunt-angular-templates
npm install --save-dev grunt-ng-annotate
npm install --save-dev grunt-contrib-uglify
npm install --save-dev load-grunt-tasks
npm install --save-dev grunt-contrib-concat

Step 2: Grunt setup

At the root root of your project create a file called Gruntfile.js with the following content:

'use strict';

module.exports = function (grunt) {
  grunt.loadNpmTasks('grunt-angular-templates');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-ng-annotate');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-serve');

  grunt.initConfig({
    pkg:grunt.file.readJSON('package.json'),
    serve: {
      options: {
        port: 9000
      }
    },
    cssmin : { // css minifier
      main : { // default target
        files : {
          // take css in temp, minify it, and save it into dist
          'dist/css.min.css' : ['css/main.css']
        }
      }
    },
    ngtemplates: {
      app: {
        options: {
          prefix: '/'
        }
      }
    },
    concat: {
      dist: {
        src: ['js/lib/*', 'js/before/*', 'js/**/*.js'],
        dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
      }
    },
    uglify : { // minifies your js files
      main : { // default task
        // again, many other options available
        options : {
          sourceMap : true, // we will generate a source map for uglified js
          sourceMapName : 'dist/<%= pkg.name %>-<%= pkg.version %>.min.map', // into this dir
          mangle: false
        },
        files : {
          // files to uglify and destination
          // we only have one file to uglify
          'dist/<%= pkg.name %>-<%= pkg.version %>.min.js': ['dist/<%= pkg.name %>-<%= pkg.version %>.js']
        }
      }
    }
  });

grunt.registerTask('build', ['cssmin', 'ngtemplates', 'concat', 'uglify']);

};

Step 3: Build minified js file

We need to launch the build task with grunt:

grunt build

We are ready!

Appendix

Terms

  • NPM (Node Package Manager) provides an easy way to distribute and share code between developers. if you want to know more about npm, check What is NPM?.