Search code examples
angulartsconfigrollupjsangular-compiler-cliangular-compiler

Angular-compiler outputs script that contain undefined this


I'm working on a small npm package for Angular, which is basically one directive that enables dragging/moving on the element you put it on. I did manage to publish it yesterday (even thought it took a while as it was the first time I published angular package to npm). I used ngc for compiling the Angular's code. Rollup for bundling and unglify for minifying.

Now, I wanted to fix the few bugs that I found. I fixed them, ran the compiler, ran rollup, etc. But rollup kept showing me that @angular/core is not defined, so it's treating it as an external dependency and - the issue that I have problem with solving - that this is undefined in both my files (https://github.com/rollup/rollup/wiki/Troubleshooting#this-is-undefined). Anyways, module was built and I was able to publish it and use it. Problem is that when I try to ng build --prod --aot the app containing the package it yells:

ERROR in Unexpected value 
    'DragOnlyModule in .../ng-dragonly-demo/node_modules/ng-dragonly/index.d.ts' 
imported by the module 
    'AppModule in .../ng-dragonly-demo/src/app/app.module.ts'. 
Please add a @NgModule annotation.  

I guess that's happening because of the warnings I wrote above. So I tried to fix them, but with no success. I was able to, at least, fix the @angular/core warning by adding exports: ['@angular/core'] into the rollup.config.js file, but this is undefined is still there. I also realized that my compiled file is different then the one I had yesterday.

Compiled file before few commits, etc.:

import { NgModule } from "@angular/core";
import { DragOnlyDirective } from "./dragonly.directive";
var DragOnlyModule = (function () {
    function DragOnlyModule() {
    }
    DragOnlyModule.decorators = [
        { type: NgModule, args: [{
                declarations: [DragOnlyDirective],
                exports: [DragOnlyDirective]
            },] },
    ];
    /** @nocollapse */
    DragOnlyModule.ctorParameters = function () { return []; };
    return DragOnlyModule;
}());
export { DragOnlyModule };
//# sourceMappingURL=dragonly.module.js.map

Compiled file today:

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { NgModule } from "@angular/core";
import { DragOnlyDirective } from "./dragonly.directive";
var DragOnlyModule = (function () {
    function DragOnlyModule() {
    }
    DragOnlyModule = __decorate([
        NgModule({
            declarations: [DragOnlyDirective],
            exports: [DragOnlyDirective]
        })
    ], DragOnlyModule);
    return DragOnlyModule;
}());
export { DragOnlyModule };
//# sourceMappingURL=dragonly.module.js.map

It looks like decorators are created differently and I really have o idea if I had changed anything inside the tsconfig.json file or any other configuration file.

The steps I'm doing to build up my module are:

  1. node_modules/.bin/ngc -p tsconfig.json
  2. node_modules/.bin/rollup -c
  3. node_modules/.bin/uglify ... (that's a long one)

My file structure is:

app
 |
 - src/
    - dragonly.directive.ts
    - dragonly.module.ts
 - index.ts
 - package.json
 - tsconfig.json
 - rollup.config.js

... and I'm compiling the output into the dist/ directory in app's root.

package.json

{
  ...
  "main": "dragonly.bundle.js",
  "module": "dragonly.module.js",
  "jsnext:main": "dragonly.module.js",
  "types": "dragonly.module.d.ts",
  ...
  "devDependencies": {
    "@angular/compiler": "^4.3.3",
    "@angular/compiler-cli": "^4.3.3",
    "@angular/core": "^4.3.3",
    "rollup": "^0.45.2",
    "rollup-plugin-commonjs": "^8.1.0",
    "rollup-plugin-node-resolve": "^3.0.0",
    "typescript": "^2.4.2",
    "uglify-js": "^3.0.27",
    "uglifyjs": "^2.4.11"
  },
  "dependencies": {
    "@angular/compiler-cli": "^4.3.3",
    "@angular/platform-server": "^4.3.3"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "lib": [
      "es2015",
      "dom"
    ],
    "rootDir": ".",
    "baseUrl": ".",
    "target": "es5",
    "sourceMap": true,
    "outDir": "./dist",
    "module": "es2015",
    "declaration": true,
    "skipLibCheck": true,
    "inlineSources": true,
    "stripInternal": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "typeRoots": [
      "./node_modules/@types/"
    ],
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "suppressImplicitAnyIndexErrors": true,
    "paths": {
      "@angular/core": ["node_modules/@angular/core"]
    }
  },
  "files": [
    "index.ts"
  ],
  "angularCompilerOptions": {
    "skipMetadataEmit": true      }
}

rollup.config.js

export default {
    entry: 'dist/index.js',
    dest: 'dist/bundles/dragonly.umd.js',
    sourceMap: false,
    format: 'umd',
    moduleName: 'ng.dragonly',
    external: ['@angular/core'],    
    globals: {
        '@angular/core': 'ng.core',
    }
}

If anyone read that all and knows what could be causing the problem I'd really appreciate it. Thank you.


Solution

  • The problem was I have been missing "skipTemplateCodegen": true option of in tsconfig.json.

    Final version of the file looks like (tsconfig.json):

    ...
    "angularCompilerOptions": {
        "skipTemplateCodegen": true,
        "skipMetadataEmit": true
    }
    

    This was also the reason my code looked different.