I\'m trying to follow the official AoT guide for Angular 2, and I\'m using Moment.js in my application. Moment.js is on my packages.json file, and I\'m using versio
I have finally managed to get rid of both errors. Indeed to avoid:
Cannot call a namespace ('moment')
You need to use:
import moment from 'moment'
Then to avoid
"moment" has no default export
You have to add into your tsconfig.json (compilerOptions):
"allowSyntheticDefaultImports": true
EDIT 17/11/2016
I also had to add the following to my rollup-config.js file:
plugins: [
nodeResolve({jsnext: true, module: true}),
commonjs({
include: [
'node_modules/rxjs/**',
'node_modules/moment/**'
]
}
}),
uglify()
]
I was having the same problems described above.
import * as moment from 'moment';
- worked when developing and loading via systemjs, but not during rollup.
import moment from 'moment';
- worked in a rollup build but not during development.
To avoid having to change code depending on build type, I just added moment as a global and created a helper function that I import everywhere I need to use it instead of importing moment.
This means the same code works for both types of scenarios. It's not particularly pretty though, if there's a better way please let me/us know!
Here's the helper function, added to it's own file momentLoader.ts
import { default as mom } from 'moment';
export default function moment(args?: any): mom.Moment {
let m = window["moment"];
if (!m) {
console.error("moment does not exist globally.");
return undefined;
}
return m(args);
}
To use moment in other classes I just import the function and call it as if I'd imported moment directly:
import moment from '../../momentLoader';
let d = moment().utc("1995-12-25");
let m = moment("1995-12-25");
To get systemjs to load it as a global, I just followed these steps. http://momentjs.com/docs/#/use-it/system-js/
In my case the moment config for systemjs looks like this:
let meta = {
'lib:moment/moment.js': { format: 'global' }
};
System.config({
paths: paths,
map: map,
packages: packages,
meta: meta
});
System.import('lib:moment/moment.js');
For the rollup build you'll have to make sure moment.js is added to the page somewhere via a script tag, as it won't get included in the rollup build file unfortunately.
Had same problem with momentJs (2.24) usage in my Angular 5 (5.2.9) project (upgraded from Ng2) with Gulp and Rollup (0.58.0) for prod build.
As guys mentioned earlier here import * as moment from 'moment';
works only for deving (via SystemJS) with referring momentJs in packages list:
{
name: 'moment',
path: 'node_modules/moment/min/moment.min.js'
}
Other case is Rollup usage (Production build) - momentJs have its code as ES6 module (in moment/src), but it exports in different way (then usual export).
That's why import moment from 'moment';
works with Rollup's
include: [
'node_modules/rxjs/**',
]
and ES6 modules import.
Yes, to use ES6 wrapper (such as moment-es6
or so) is simple solution. But it always requires momentJs.
Same time there is one more simple solution for this issue - replace your import row from Dev to Prod.
For example, Gulp can use gulp-replace
at some step:
return gulp.src([
...
])
.pipe(replace('import * as moment from \'moment\';', 'import moment from \'moment\';'))
...;