davidmk
davidmk

Reputation: 75

Angular 2 - Import external libraries for both JIT and AoT

I'm trying to configure my codebase to be able to do both JiT and AoT so that I can use JiT for local development and AoT for production. I've followed the angular documentation here and have successfully gotten both to work individually.

The problem that I'm facing is when I try to import external libraries, specifically moment-js.

For JiT, I'm using SystemJS, the configuration for which is

// systemjs.config.js

System.config({
    map: {
        // ...
        moment: '/node_modules/moment',
    },
    packages: {
        // ...
        moment: {
            defaultExtension: 'js'
        }
    }
});

And then to import in a component in typescript, I can just do

// some-component.component.ts

import * as moment from 'moment/moment';

This works just fine for local development.

When I try to AoT compile with rollup however, I get a Cannot call a namespace ('moment') compilation error. I solved that problem following this thread here, so after a couple changes to the rollup config, the import statement in the component should be

// some-component.component.ts

import moment from 'moment';

Which works great for AoT and rollup, but now SystemJS has a problem understanding that.

I can't seem to break out of the loop. I can get one to work, but not both at the same time. Is there any way to get SystemJS to understand the import statements required by rollup? I don't think its possible the other way around.

EDIT:

I did find a way to at least make it work, but it's not exactly ideal. Instead of importing it, I just declared it as any and then load in the library externally with a script tag. So now the component is

// some-component.component.ts

declare const moment: any;

As I said, this is not ideal since this doesn't allow me to bundle moment in with the AoT build, and it also forces typescript to interpret the 'moment' var as any so now it doesn't know about its type. So this still doesn't exactly answer my question, but this does at least work.

Upvotes: 1

Views: 822

Answers (2)

Trent
Trent

Reputation: 4306

For those who do not wish to add a custom rollup.js plugin, or are using a packaging tool like ng-packagr, consider replacing your import statement to the following solution:

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

This solution was originally provided by the following Github issue:
https://github.com/dherges/ng-packagr/issues/217#issuecomment-339460255

Upvotes: 0

Egor Burykin
Egor Burykin

Reputation: 211

Keep import:

import * as moment from 'moment';

And add plugin to rollup.js:

{
    name: 'replace moment imports',
    transform: code => ({
        code: code.replace(/import\s*\*\s*as\s*moment/g, 'import moment'),
        map: { mappings: '' }
    })
},

Upvotes: 1

Related Questions