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.