Using Rollup for Angular 2's AoT compiler and importing Moment.js

后端 未结 9 1557
天涯浪人
天涯浪人 2020-12-24 13:34

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

相关标签:
9条回答
  • 2020-12-24 14:00

    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()
    ]
    
    0 讨论(0)
  • 2020-12-24 14:06

    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.

    0 讨论(0)
  • 2020-12-24 14:09

    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\';'))
         ...;
    
    0 讨论(0)
提交回复
热议问题