'import' and 'export' may appear only with 'sourceType: module'

After starting a new project and adding a reference to angular2-moment, I’m getting this error:

/Users/corydingels/projects/other/wyb/testapp/node_modules/angular2-moment/TimeAgoPipe.ts:3
import {Pipe, ChangeDetectorRef, PipeTransform, OnDestroy} from 'angular2/core';
^
ParseError: 'import' and 'export' may appear only with 'sourceType: module'

To reproduce:

% ionic start --v2 --ts -t sidemenu testapp
% cd testapp
% npm i --save angular2-moment
// Edit getting-started.ts by adding import line and "pipes: .." line
import {CalendarPipe} from 'angular2-moment';
@Page({
  templateUrl: 'build/pages/getting-started/getting-started.html',
  pipes: [CalendarPipe]
})
% ionic serve

Note that I’m getting the same error when trying to add angular2-jwt.

My ionic info:

Cordova CLI: 6.1.0 (cordova-lib@undefined)
Ionic Version: 2.0.0-beta.3
Ionic CLI Version: 2.0.0-beta.23
Ionic App Lib Version: 2.0.0-beta.13
ios-deploy version: 1.8.5 
ios-sim version: 5.0.8 
OS: Mac OS X El Capitan
Node Version: v5.8.0
Xcode version: Xcode 7.2 Build version 7C68 
1 Like

If nothing else works, you’re free to use these homebrew pipes for moment:

import {Pipe, PipeTransform} from 'angular2/core';
import * as moment from 'moment';

@Pipe({
    name: 'moment',
    pure: false,
})
export class MomentPipe implements PipeTransform {
    transform(d:Date | moment.Moment, args?:any[]):string {
        let rv = moment(d).format(args[0]);
        return rv;
    }
}

@Pipe({
    name: 'timeago',
    pure: false,
})
export class TimeagoPipe implements PipeTransform {
    transform(d:Date | moment.Moment):string {
        let rv = moment(d).fromNow();
        return rv;
    }
}

$ typings i moment should get you the typings for moment so the import works.

1 Like

I am also having this issue and was wondering whether there is a known solution. I’ve looked at the google results for the error (which are almost all related to Babel and Babelify) and it seems like the problem arises because the file (in this case angular2-moment/index.ts) is not getting transpiled, because it is in node_modules.

There should be a way to modify the Browserify settings so that the file does get transpiled, right?

@estyshoshana - I ended up bringing in local versions of the files I needed. So I now have these files: app/vendor/angular2-moment/moment.js and app/vendor/angular2-moment/CalendarPipe.ts. Both of these were pulled directly from files in /node_modules.

My import changed to: import {CalendarPipe} from '../../vendor/angular2-moment/CalendarPipe';

This isn’t ideal, obviously. But being that everything is in beta I’ve run in to a number of things where it doesn’t “just work” like I would anticipate. In this case I decided a hacky workaround was better than giving up a few hours (or more!) to make things work with the npm module.

Making the following change in the gulpfile seemed to do the trick:

return buildBrowserify({ watch: true, src: ['./app/app.ts', 
    './typings/main.d.ts', './node_modules/angular2-moment/index.ts']});

The first two are the default value for src and I didn’t want to risk overwriting and thereby breaking everything else.

Hope this helps!

had exactly same problem with angular2-firebase. For reference - modifying in same way but s/angular2-moment/angular2-firebase/ helped as well.

How I resolved the issue:
Just add: extensions: [’.js’, ‘.ts’] to the browserifyOptions
thus:

var defaultOptions = {
  watch: false,
  src: ['./app/app.ts', './typings/main.d.ts'],
  outputPath: 'www/build/js/',
  outputFile: 'app.bundle.js',
  browserifyOptions: {
    cache: {},
    packageCache: {},
    debug: true,
    extensions: ['.js', '.ts']
  },
  watchifyOptions: {},
  tsifyOptions: {},
  onError: function(err){ console.error(err.toString()); },
  onLog: function(log){
    console.log((log = log.split(' '), log[0] = pretty(log[0]), log.join(' ')));
  }
}

Thanks.

2 Likes

helped me also with some angular2 module. I hope its added permanently

Hi, is there any way to pass it through ionic gulp?