Errors when using MomentJS in Angular Typescript library

后端 未结 3 565
执笔经年
执笔经年 2020-12-17 14:24

I\'m building an Angular (2+) component library using jvandemo/generator-angular2-library as a starter, which uses Rollup as a module builder. The component I am creating in

相关标签:
3条回答
  • 2020-12-17 14:44

    The error is very clear and specific

    Error: Cannot call a namespace ('moment') at error (/Users/chris/angular-library/node_modules/rollup/dist/rollup.js:185:14)

    This is per the ES Module Specification.

    That means the following is an invalid way to import moment, or anything you intend to call, because a module namespace object, such as that created by * as ns may not be called.

    import * as moment from 'moment';
    

    The correct form is the form that ngc is raising an error on

    import moment from 'moment';
    

    Firstly to make this work, you need to specify the --allowSyntheticDefaultImports flag.

    tsconfig.json

    {
      "compilerOptions": {
        "allowSyntheticDefaultImports": true
      }
    }
    

    Assuming that ngc will recognize the option, you still have an additional problem to work out.

    The flag above is for users of tools such as SystemJS or Webpack which perform the synthesis, allowing such code to typecheck.

    As of TypeScript 2.7, you can now specify the --esModuleInterop flag to have the language provide the synthesis as part of the transpilation process.

    {
      "compilerOptions": {
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true
      }
    }
    

    Note that if you are using a version of TypeScript prior to 2.7 and if you are compiling to CommonJS, AMD, or UMD modules (e.g. with --module commonjs) the correct import syntax is rather

    import moment = require('moment');
    

    The import = require syntax is a TypeScript specific construct, now largely unnecessary. It exists to acquire both the type and the value of the module exports of an AMD, CommonJS, or UMD module. The "and" is important because a const, var, or let = require invocation only creates a name in the value space not in the type space.

    0 讨论(0)
  • 2020-12-17 14:58

    To whoever finds this in 2018+, with Angular6 and current @angular/cli:

    Today I ran into this and found solution here.

    import * as moment_ from 'moment';
    const moment = moment_;
    

    Now the library compiles OK for me.

    0 讨论(0)
  • 2020-12-17 15:07

    In the sample directive I had no problem compiling when I used the following:

    import { Directive, ElementRef } from '@angular/core';
    import * as moment from '../node_modules/moment/moment';
    @Directive({
      selector: '[sampleDirective]'
    })
    export class SampleDirective {
    
      constructor(private el: ElementRef) {
        moment.isDate('test');
      }
    
    }
    

    The files are compiled from a build directory that is a sub-dir off the root. You do get a further warn about "this", mentioned here:

    https://github.com/rollup/rollup/issues/794

    I need to say in the gulfile that the library is external:

      external: [
        '@angular/core',
        '@angular/common',
        'moment'
      ],
    

    And from the github link, you should add a onwarn block to both rollup sections: That is section 'rollup:umd' and 'rollup:fesm'

    onwarn: function(warning) {
        // Skip certain warnings
    
        // should intercept ... but doesn't in some rollup versions
        if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
    
        // console.warn everything else
        console.warn( warning.message );
    },
    

    Does that get you any further?

    0 讨论(0)
提交回复
热议问题