9

I am trying to implement AOT and Rollup per https://angular.io/docs/ts/latest/cookbook/aot-compiler.html#!#tree-shaking

I run rollup per:"node_modules/.bin/rollup" -c scripts/rollup-config.js

and the result is a build.js file with just the entry file and nothing else. There are no errors and just one warning: "'default' is imported from external module 'rollup' but never used"

The "aot" folder does contain all the relevant compiled ngfactory files.

Following is the entry file:

import { platformBrowser }    from '@angular/platform-browser';
import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory';

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

The rollup-js.config:

import rollup      from 'rollup'
import nodeResolve from 'rollup-plugin-node-resolve'
import commonjs    from 'rollup-plugin-commonjs';
import uglify      from 'rollup-plugin-uglify'

export default {
    entry: 'scripts/app/main.js',
    dest: 'scripts/app/build.js', // output a single application bundle
    sourceMap: true,
    sourceMapFile: 'scripts/app/build.js.map',
    format: 'iife',
    onwarn: function(warning) {
        // Skip certain warnings

        // should intercept ... but doesn't in some rollup versions
        if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
        // intercepts in some rollup versions
        if ( warning.indexOf("The 'this' keyword is equivalent to 'undefined'") > -1 ) { return; }

        // console.warn everything else
        console.warn( warning.message );
    },
    plugins: [
        nodeResolve({jsnext: true, module: true}),
        commonjs({
            include: '../node_modules/rxjs/**'
        }),
        uglify()
    ]
}

and my systemjs just in case its relevant:

(function (global) {
    System.config({
        paths: {
            // paths serve as alias
            'npm:': 'libs/'
        },
        // map tells the System loader where to look for things
        map: {
            // our app is within the app folder
            app: 'approot',
            appjit: 'approot',
            // angular bundles
            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
            '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
            '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
            '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
            '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
            '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
            // other libraries
            'rxjs': 'npm:rxjs',
            'angular-in-memory-web-api': 'npm:angular-in-memory-web-api',
            'jquery': 'npm:jquery/dist/jquery.min.js',
            'moment': 'npm:moment/moment.js',
            'ng2-bootstrap/ng2-bootstrap': 'npm:ng2-bootstrap/bundles/ng2-bootstrap.umd.js',
            'ng2-select/ng2-select': 'npm:ng2-select/ng2-select.js',
            "ng2-popover": "libs/ng2-popover",
            'angular2-ui-switch': 'libs/angular2-ui-switch/dist/index.js',
            "angular2-text-mask": "libs/angular2-text-mask/dist",
            "text-mask-core": "libs/text-mask-core/"
        },
        // packages tells the System loader how to load when no filename and/or no extension
        packages: {
            app: {
                main: './app/main.js',
                defaultExtension: 'js'
            },
            appjit: {
                main: './app/main-jit.js',
                defaultExtension: 'js'
            },
            rxjs: {
                defaultExtension: 'js'
            },
            'angular-in-memory-web-api': {
                main: './index.js',
                defaultExtension: 'js'
            },
            'libs/ng2-select': {
                defaultExtension: 'js'
            },
            'libs/ng2-popover': {
                main: "index.js",
                defaultExtension: 'js'
            },
            'libs/angular2-text-mask/dist': {
                main: "angular2TextMask.js",
                defaultExtension: 'js'
            },
            'libs/text-mask-core/': {
                main: "textMaskCore.js",
                defaultExtension: 'js'
            },
            'libs/angular2-ui-switch': {
                main: "index.js",
                defaultExtension: 'js'
            }
        }
    });
})(this);

My folder structure is as follows:

  • [visual studio project]/scripts/aot
  • [visual studio project]/scripts/app
  • [visual studio project]/scripts/app/main.js
  • [visual studio project]/scripts/rollup-config.js
  • [visual studio project]/scripts/tsconfig-aot.json

My environment:

  • VS 2015
  • Angular: 2.4.0
  • Node: v5.5.0
  • Typescript: 2.0.10
  • rollup: 0.41.4
  • rollup-plugin-node-resolve: 2.0.0
  • rollup-plugin-commonjs: 7.0.0
  • rollup-plugin-uglify: 1.0.1
Aravind
  • 40,391
  • 16
  • 91
  • 110
Ques Tion
  • 3,365
  • 2
  • 11
  • 10
  • Is the issue solved? – eko Feb 17 '17 at 18:53
  • 1
    Sorry, it is not resolved. Company made me take a break from it, didn't have time to test out solutions given. – Ques Tion Mar 19 '17 at 19:47
  • Ah ok :/ I was also stuck with a similar issue.. Trying really hard to write "aot friendly" angular code :-) – eko Mar 19 '17 at 19:49
  • Ok, disregard my previous comment. For any external script that is not compiled with es2015, you can add them rollup's commonjs include array like so: commonjs({ include: ['../node_modules/rxjs/**', '../node_modules/angular2-text-mask/**' ] }), – Ques Tion Mar 19 '17 at 20:51

3 Answers3

6

In your [visual studio project]/scripts/aot folder, there should be a main.ts file, visual studio will compile it to main.js using tsconfig.json but not tsconfig-aot.json, check your main.js file, if it looks like

"use strict";
 var platform_browser_1 = require("@angular/platform-browser");
 var app_module_ngfactory_1 = require("./app.module.ngfactory");
 platform_browser_1.platformBrowser().bootstrapModuleFactory(app_module_ngfactory_1.AppModuleNgFactory);

you need to update in your tsconfig.json:

    {
     "module": "commonjs",
    }

to

   {
     "module": "es2015",
   }
ylu20
  • 126
  • 2
  • This solved this issue for me. I missed changing the module from "commonjs" to "es2015" in my tsconfig-aot.json when I followed the cookbook. – fooser Feb 08 '17 at 19:35
  • My main.js file is using the es2015 standard and still have the same error. – Ques Tion Mar 19 '17 at 19:46
  • I am going to mark this as the answer because it is somewhat related. Not just main.js but all external/internal files in AOT needs to be es2015 complaint. – Ques Tion Mar 19 '17 at 20:14
2

I also was following the official angular2 AOT guilde myself and due to lack of a simple working example I have created this github repository. I hope it helps you.

If you are a windows user, you should definitely be able to get it working in git-bash terminal (tested by me).

Evgeny Bobkin
  • 4,092
  • 2
  • 17
  • 21
1

For AOT to work, you'll need to ensure that you're generating es6 module loading syntax:

Rollup can only Tree Shake ES2015 modules which have import and export statements.

tsconfig.json:

{
    "compilerOptions" {
        "module": "es6",
         ...
     }
}
Michael Kang
  • 52,003
  • 16
  • 103
  • 135