Check out myAngular article series with live demos and Facebook group Angular - Advanced Topics

Using MomentJs with Angular and the Closure compiler

Torgeir "Tor" Helgevold
- JavaScript Developer and Blogger
Published: Sat Apr 15 2017

In the following post I will show how to use momentJS in a closure compiled Angular application.

One of the challenges when bundling third party libraries using the Closure compiler is that the library might not be compatible with Closure (ADVANCED_OPTIMIZATIONS).

MomentJS is an example of a very popular library used by a lot of Angular applications.

In the following sample I will show how to integrate moment 2.13.0 with my Angular bundle.

Component

The first step is to import moment from my component.

import {Component, Injectable} from '@angular/core'; import 'moment'; declare var moment: any; @Component({ selector: 'basic', templateUrl: './basic.ng.html', }) @Injectable() export class Basic { ctxProp: string; constructor() { this.ctxProp = `Happy ${moment().format('dddd')}`; } }

Normally I would import moment as “import * as moment from 'moment'”, but this approach gave me a few issues with Closure.

Instead I had to do: import from 'moment'.

The downside to this is that I don't get to benefit from typings. Notice I am also declaring a global moment variable to refer to window.moment.

Now that moment is imported, I can start using it.

In my simple example I am just formatting a date using moment().format('dddd').

Externs

To protect the global moment variable I had to declare an extern. I defined my moment extern in a separate file like so:

/** @externs */ var moment;

Configuration

The final step is to define configuration to tell the Closure compiler how to compile the application. My configurations can be found below:

--compilation_level=ADVANCED_OPTIMIZATIONS --language_out=ES5 --js_output_file=dist/bundle.js --output_manifest=dist/manifest.MF --variable_renaming_report=dist/variable_renaming_report --property_renaming_report=dist/property_renaming_report --create_source_map=%outname%.map --warning_level=QUIET --dependency_mode=STRICT --rewrite_polyfills=false --js vendor/built/rxjs/**.js --js_module_root=vendor/built node_modules/@angular/core/@angular/core.js --js_module_root=node_modules/@angular/core node_modules/@angular/common/@angular/common.js --js_module_root=node_modules/@angular/common node_modules/@angular/platform-browser/@angular/platform-browser.js --js_module_root=node_modules/@angular/platform-browser --js built/**.js --entry_point=./built/bootstrap node_modules/moment/moment.js    node_modules/moment/package.json     --module_resolution=node vendor/moment_externs.js vendor/zone_externs.js vendor/angular_testability_externs.js

I have added my code to Github if you are interested in trying it yourself.

If you liked this article, share it with your friends on social media:

We also have a new Facebook group about advanced Angular topics.

I invite you to follow me on twitter