typescript - angular-cli 25.5 Modulová kompilácia zlyhala


Problém

Po aktualizácii angular-cli z verzie 22.1 na 25.5 (inštaláciou angular-cli@latest) a z Angular 2.2.3 na 2.3.1 som dostal tento problém:

ERROR in ./src/app/app.module.ts
Module build failed: TypeError: Cannot read property 'text' of undefined
    at IdentifierObject.TokenOrIdentifierObject.getText (~/projects/MyProject/node_modules/typescript/lib/typescript.js:53644:56)
    at ~/projects/MyProject/node_modules/@ngtools/webpack/src/loader.js:83:72
    at Array.some (native)
    at ~/projects/MyProject/node_modules/@ngtools/webpack/src/loader.js:83:32
    at Array.filter (native)
    at _removeModuleId (~/projects/MyProject/node_modules/@ngtools/webpack/src/loader.js:82:10)
    at ~/projects/MyProject/node_modules/@ngtools/webpack/src/loader.js:167:48
 @ ./src/main.ts 5:0-45
 @ multi main

Ale nedokážem prísť na to, aký je problém, main.ts vyzerá normálne:

import './polyfills.ts';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { AppModule } from './app/app.module';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);

Existujú ďalšie dva súbory, ktoré tiež zlyhávajú s presne rovnakou chybovou správou ako vyššie, prvý environment.ts bez ničím zvláštnym a druhý podmodul, ktorý zlyhal s doplnením:

 @ ./src async
 @ ./~/@angular/core/src/linker/system_js_ng_module_factory_loader.js
 @ ./~/@angular/core/src/linker.js
 @ ./~/@angular/core/src/core.js
 @ ./~/@angular/core/index.js
 @ ./src/main.ts
 @ multi main

Zdrojový kód NodeModules

Odkazovaný typescript.js:53644:56 vyzerá takto:

[53643] TokenOrIdentifierObject.prototype.getText = function (sourceFile) {
[53644]     return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
[53645] };

a loader.js:83:72 & 83:32 odkazuje na webpack a tento úryvok kódu:

[078] exports.removeModuleIdOnlyForTesting = removeModuleIdOnlyForTesting;
[...] function _removeModuleId(refactor) {
[...]   var sourceFile = refactor.sourceFile;
[...]   refactor.findAstNodes(sourceFile, ts.SyntaxKind.ObjectLiteralExpression, true)
[...]       .filter(function (node) {
[083]       return node.properties.some(function (prop) { return prop.name.getText() == 'moduleId'; });
[...]   })
[...]       .forEach(function (node) {
[...]       var moduleIdProp = node.properties.filter(function (prop, idx) {
[...]           return prop.name.getText() == 'moduleId';
[...]       })[0];
[...]       // get the trailing comma
[...]       var moduleIdCommaProp = moduleIdProp.parent.getChildAt(1).getChildren()[1];
[...]       refactor.removeNodes(moduleIdProp, moduleIdCommaProp);
[...]   });
[093] }

a loader.js:167:48

[148] // Super simple TS transpiler loader for testing / isolated usage. does not type check!
[...] function ngcLoader(source) {
[...]   this.cacheable();
[...]   var cb = this.async();
[...]   var sourceFileName = this.resourcePath;
[...]   var plugin = this._compilation._ngToolsWebpackPluginInstance;
[...]   // We must verify that AotPlugin is an instance of the right class.
[...]   if (plugin && plugin instanceof plugin_1.AotPlugin) {
[...]       var refactor_2 = new refactor_1.TypeScriptFileRefactor(sourceFileName, plugin.compilerHost, plugin.program);
[...]       Promise.resolve()
[...]           .then(function () {
[...]           if (!plugin.skipCodeGeneration) {
[...]               return Promise.resolve()
[...]                   .then(function () { return _removeDecorators(refactor_2); })
[...]                   .then(function () { return _replaceBootstrap(plugin, refactor_2); });
[...]           }
[...]           else {
[...]               return Promise.resolve()
[...]                   .then(function () { return _replaceResources(refactor_2); })
[167]                   .then(function () { return _removeModuleId(refactor_2); });
[...]           }
[169]       })
[...]  ...

Otázka

Mal niekto rovnaký problém alebo dokáže zistiť, prečo webpack(?) zlyháva - alebo mi dokáže vysvetliť, čo sa kompilátor snaží urobiť a prečo zlyháva?

Upraviť

angular-cli.json:

{
  "project": {
    "version": "1.0.0-beta.25.5",
    "name": "myproject"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "mobile": false,
      "styles": [
        "assets/css/main.css"
      ],
      "scripts": [
        "assets/lib/stomp.min.js"
      ],
      "environments": {
        "source": "environments/environment.ts",
        "dev":    "environments/environment.ts",
        "live": "environments/environment.live.ts"
      }
    }
  ],
  "addons": [],
  "packages": [],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "css",
    "prefixInterfaces": false,
    "inline": {
      "style": false,
      "template": false
    },
    "spec": {
      "class": false,
      "component": true,
      "directive": true,
      "module": false,
      "pipe": true,
      "service": true
    }
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "",
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "es6",
      "dom"
    ],
    "mapRoot": "./",
    "module": "es6",
    "moduleResolution": "node",
    "outDir": "../dist/out-tsc",
    "sourceMap": true,
    "target": "es5",
    "typeRoots": [
      "../node_modules/@types"
    ]
  },
  "files": [
    "typings/index.d.ts"
  ]
}

Odpoveď č. 1

Aktualizácia:

Ako poznamenal @stewdebaker: angular-cli: 1.0.0-beta.26 bol teraz vydaný a zdá sa, že tento problém rieši.

Ako spomenul @stewdebaker, existuje podobná otázka Chyba pri kompilácii vo fronte pre Angular2 s použitím angular-cli - riešením tam bolo jednoducho vrátiť sa na angular-cli: 1.0.0-beta.21.

Pozrite si tiež https://github.com/angular/angular-cli/issues/4072 pre viac informácií o probléme v sledovači problémov angular-cli.

Nepodarilo sa mi opraviť môj projekt a taktiež som sa nedokázal vrátiť na moju predchádzajúcu verziu angular-cli 1.0.0-beta.22-1 (a nevidel som ostatné otázky na Stack Overflow, inak by som pravdepodobne skúšal vrátiť na 1.0.0-beta.21).

Z nejakého dôvodu pred aktualizáciou na 1.0.0-beta.25.5 príkaz ng serve fungoval, ale po návrate na 1.0.0-beta.22-1 by sa stále zobrazovali tie isté chyby ako po aktualizácii.

Časovo náročné riešenie

Tak som sa rozhodol vytvoriť nový projekt Angular2 pomocou angular-cli a prestavať celý projekt s použitím CLI, pričom som kopíroval kód zo starého úložiska a opravoval chyby.

Chyby, na ktoré som narazil, boli menšie problémy (myslím, že sú výsledkom zmeneného súboru tslint.json kvôli aktualizovanému angular-cli), ale v projekte sa nič veľké nezmenilo a teraz funguje.

Zdrojové súbory spomenuté v chybových hláseniach:

  • app.module.ts
  • tsconfig.json
  • angular-cli.json

nezmenilo sa vôbec nič, ale angular-cli je opäť použiteľný, ng serve teraz beží bez toho, aby sa vyskytnuté chyby.

Nemyslím si, že toto je ideálne riešenie (ani downgrade na 1.0.0-beta.21) - ale to je jediné, čo som mohol nájsť.