jvandemo / generator-angular2-library

Yeoman generator to create an Angular library
MIT License
752 stars 122 forks source link

How can MomentJS be used with this generator (to play nicely with Rollup)? #224

Closed IckleChris closed 7 years ago

IckleChris commented 7 years ago

Hey, do you (or any other users) know how to get MomentJS to work with this library? Following this process;

  1. Run the generator to get a fresh installation
  2. Install MomentJS (npm install --save moment)
  3. Import moment into the sample component (import * as moment from 'moment';)
  4. Add a test usage (e.g. initialising a property date = moment().format('YYYY'); and update the template to reference it

When doing so and running npm run build the following occurs;

...
[19:00:29] Starting 'ngc'...
[19:00:30] Finished 'ngc' after 1.72 s
[19:00:30] Starting 'rollup:fesm'...
'moment' is imported by build/sample.component.js, but could not be resolved – treating it as an external dependency

events.js:182
      throw er; // Unhandled 'error' event
      ^
Error: Cannot call a namespace ('moment')
    at error (/Users/chris/projects/angular2-library-moment-test/node_modules/rollup/dist/rollup.js:185:14)

I've tried adding the "allowSyntheticDefaultImports": true rule as described in #221 however that has not helped.

For reference, I also have a question open on Stack Overflow (https://stackoverflow.com/questions/46876541/errors-when-using-momentjs-in-angular-typescript-library/46877308?noredirect=1#comment80701528_46877308).

Thanks!

IckleChris commented 7 years ago

The reporter of issue #223 was a commenter in the stack overflow post above (who has since removed his answer) so that is likely a duplicate of this report.

dgroh commented 7 years ago

Same issue here, cannot use moment even after setting allowSyntheticDefaultImports

IckleChris commented 7 years ago

I've managed to sort of solve this, although the issue I was having seems to have disappeared.

In my component that uses moment I use the import moment from 'moment'; syntax, and I have updated /tsconfig.json to include;

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

As before, and this works for me during a build.

When consuming the library in my test angular-cli project however it threw up External module ''moment'' has no default export errors in any case that used moment as a type (it seemed to be fine where it was just used, e.g. moment().format(). Updating the generated type files (dist/**/*.d.ts) to use import * as moment from 'moment' (which causes errors during build) then worked in the consuming library.

I've added a gulp task to replace those references automatically during a build and I can now build and consume the library in another app, so I guess that resolves my issue.

That task for reference;

gulp.task('replace:momentImports', function(){
  gulp.src(`${distFolder}/**/*.d.ts`)
      .pipe(replace("import moment from 'moment'", "import * as moment from 'moment'"))
      .pipe(gulp.dest(distFolder));
});
jvandemo commented 7 years ago

@IckleChris Thank you for sharing, Chris, much appreciated! 🏆

xtoff commented 7 years ago

I have another way of doing this.. In my actual project that imports that generator project I define moment.js in my angular-cli.json

    "apps": [
        {
            ...
            "scripts": [
            ...
                "../node_modules/moment/moment.js"
            ]
        }
    ]

In my generator project I have a peer dependency to "moment" in the package.json. And in the class that uses moment.js I declare moment via this statement to make typescript happy :) declare var moment: any;