angular / angular

Deliver web apps with confidence 🚀
https://angular.dev
MIT License
96.37k stars 25.57k forks source link

ERROR in Illegal state: symbol without members expected when using AOT in 4.3.0 #18170

Closed aleris closed 6 years ago

aleris commented 7 years ago

I'm submitting a...


[x] Regression
[ ] Bug report 
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request

Current behavior

Getting error when building for production (AOT enabled) with a certain pattern of imports/exports (see below). The error reported is:

ERROR in Illegal state: symbol without members expected, but got {"filePath":"snip/test/ng/aottest/src/app/shared/role-co
nstants.ts","name":"RoleConstants","members":["USER"]}.

ERROR in ./src/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in 'snip\test\ng\aottest\src'
 @ ./src/main.ts 4:0-74
 @ multi ./src/main.ts

Worked ok in 4.2.6, does not work in 4.3.0.

Expected behavior

ng build --prod should build correctly without rising the error.

Minimal reproduction of the problem with instructions

download symbol-without-members-error-test-a.zip npm install ng build --prod

The project contain a newly generated project (with ng new) with a number of files added to reproduce the error: shared/const.ts - exports a constant field shared/index.ts - exports consts above intermediate.ts - imports consts exports aggregated data index.ts - exports intermediate above module.ts - is calling RouterModule.forRoot([...intermediate] with intermediate imported from above.

If import { Consts } from './shared'; is changed to import { Consts } from './shared/consts'; in intermediate.ts the problem does not manifest anymore.

What is the motivation / use case for changing the behavior?

n/a

Environment


Angular version: 4.3.0
(worked ok in 4.2.6.)

For Tooling issues:
- Node version: v7.10.0
- Platform: Windows

manekinekko commented 7 years ago

@aleris I can't reproduce this issue. See screenshot below. What version of the CLI are you using? Can you update the CLI to 1.3.0-beta.1 and test against it plz?

image

deepu105 commented 7 years ago

We were using 1.2.1 in JHipster

deepu105 commented 7 years ago

I made few tests with this sample With Global CLI 1.2.1 and local 1.0.0 image With global and local CLI 1.2.1 image With local CLI 1.3.0-beta.1 image With global and local CLI 1.3.0-beta.1 image

Could it be possible that you have a different angular version linked or something?

aleris commented 7 years ago
ng -v
@angular/cli: 1.0.0
node: 7.10.0
os: win32 x64
@angular/common: 4.3.0
@angular/compiler: 4.3.0
@angular/core: 4.3.0
@angular/forms: 4.3.0
@angular/http: 4.3.0
@angular/platform-browser: 4.3.0
@angular/platform-browser-dynamic: 4.3.0
@angular/router: 4.3.0
@angular/cli: 1.0.0
@angular/compiler-cli: 4.3.0

After: npm install @angular/cli@1.3.0-beta.1

a

Same with 1.2.1 (@latest)

cjamaldine commented 7 years ago

hello, same error with 4.3.0, but it works with 4.2.3

@angular/cli: 1.1.2

tmakin commented 7 years ago

I'm also getting this on an enum export when using Angular 4.3.0 on CLI 1.2.1:

ERROR in Illegal state: symbol without members expected, but got {"filePath":"snip/src/app/core/models/index.ts","name":"Role","members":["Advisor"]}.

Downgrade to 4.2.6 fixes it

janousek commented 7 years ago

The error rises because of the commit https://github.com/angular/angular/commit/ddb766e456f4d629ffe344d1178476c8c8657375 from @chuckjaz

Concretely because of the new condition references > 0 in this if:

                // Stop simplification at builtin symbols or if we are in a reference context
                if (expression === self.injectionToken || expression === self.opaqueToken ||
                    self.conversionMap.has(expression) || references > 0) {
                    return expression;
                }
rimlin commented 7 years ago

+1 this error with enums like:

export enum MyEnum {
  val1 = <any>"val1",
  val2 = <any>"val2"
}
cdllqos commented 7 years ago

Same error as this, I just new a project and exec 'ng build --prod', and then the error comes :). By the way, I install npm package by cnpm image

image

montella1507 commented 7 years ago

@chuckjaz can you give us some advice, please?

florinr1 commented 7 years ago

I have the same error after upgrading angular from 4.1.3 to 4.3.1 and CLI from 1.1.0 to 1.2.3. export enum ModDeschidere { CREATE = 0, VIEW = 1, EDIT = 2 }

ERROR in Illegal state: symbol without members expected, but got {"filePath":"src/app/core/modDeschidere.ts","name":"ModDeschidere","members":["CREATE"]}.

I don't know what to do / test.

janousek commented 7 years ago

For everyone who needs temporary fix for this error. Just manually modify this file:

node_modules\@angular\compiler\bundles\compiler.umd.js

Find this part of code:

                // Stop simplification at builtin symbols or if we are in a reference context
                if (expression === self.injectionToken || expression === self.opaqueToken ||
                    self.conversionMap.has(expression) || references > 0) {
                    return expression;
                }

And modify it to look like this:

                // Stop simplification at builtin symbols or if we are in a reference context
                if (expression === self.injectionToken || expression === self.opaqueToken ||
                    self.conversionMap.has(expression)) {
                    return expression;
                }

Everything will work.

montella1507 commented 7 years ago

@janousek unfortunately it is not possible (it is dangerous) in CI environment when you want to build "clean build". So i would rather suggest temporary downgrade to older angular as temporary solution.

erlloyd commented 7 years ago

I still get the error even after downgrading my @angular packages to 4.2.6

screenshot 2017-07-29 22 29 04

And @janousek I confirmed the code you pointed out is rolled back. Does anyone have any updates / ideas on this?

jesussobrino commented 7 years ago

I tried Angular 4.3.2 and this bug it's still been reproduced.

Building with Angular 4.3.2 AoT:

Error: Illegal state: symbol without members expected, but got {"filePath":"/my-model.model.ts","name":"ModelCode","members":["ModelData"]}.

Building with Angular 4.3.2 without AoT:

[at-loader] Ok, 6.462 sec.

After downgrading to Angular 4.2.6 with or without AoT:

[at-loader] Ok, 10.517 sec.

I don't understand why the angular team doesn't care about this, because it's impossible to use the latest AoT Angular version in any CI environment.

michal-filip commented 7 years ago

Would anyone have a 4.3.x fork with the workaround in compiler.umd.js so that we don't have to downgrade? But I'm still hoping for a fix or at least some suggested fix instruction from @chuckjaz .

OysteinAmundsen commented 7 years ago

Still an issue with 4.3.3.

rafaelss95 commented 7 years ago

I'm facing the same problem having an enum like this:

export enum Role {
  User = 'user',
  Admin = 'admin'
}

ERROR in Illegal state: symbol without members expected, but got {"filePath":"/filePath/enums/role.enum.ts","name":"Role","members":["User"]}.

Environment:

@angular/cli: 1.2.7
node: 8.1.1
os: linux x64
@angular/animations: 4.3.3
@angular/cdk: 2.0.0-beta.8
@angular/common: 4.3.3
@angular/compiler: 4.3.3
@angular/core: 4.3.3
@angular/forms: 4.3.3
@angular/http: 4.3.3
@angular/material: 2.0.0-beta.8
@angular/platform-browser: 4.3.3
@angular/platform-browser-dynamic: 4.3.3
@angular/platform-server: 4.3.3
@angular/router: 4.3.3
@angular/cli: 1.2.7
@angular/compiler-cli: 4.3.3
@angular/language-service: 4.3.3
typescript: 2.4.2

Reverting the Angular version to 4.2.6 isn't an option, because I'm already using the new HttpClient API (which one was added in 4.3.0).

@alxhub @chuckjaz can you check this please? IMHO, it's a real bug and should have higher priority.

Vladimex commented 7 years ago

I have the same problem with 4.3.3. When it will be fixed?

mindsers commented 7 years ago

+1 @rafaelss95

We have the same problem and reverting is not an option: we can't modify the application's code base.

michal-filip commented 7 years ago

The simplest way for us was to fix the compiler tarball (based on fix suggested by @janousek) and put it next to our project, then lock versions of all angular modules to 4.3.3 and link @angular/compiler to the local tarball. Package.json then looks like this:

"dependencies": {
        "@angular/common": "4.3.3",
        "@angular/compiler": "../dependency-overrides/compiler-4.3.3-fix.tgz",
        "@angular/compiler-cli": "4.3.3",

zipped tarball: compiler-4.3.3-fix.tgz.zip After this, we no longer get the issue during AOT builds.

Hopefully someone more familiar with the compiler will be able to create a proper fix PR soon, it must be blocking lots of teams from upgrading.

OysteinAmundsen commented 7 years ago

4.3.4 AOT build yields:

ERROR in Illegal state: symbol without members expected, but got {"filePath":"D:/dev/gymsystems/client/app/services/model/IUser.ts","name":"Role","members":["Club"]}.
ERROR in ./client/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in 'D:\dev\gymsystems\client'
resolve './$$_gendir/app/app.module.ngfactory' in 'D:\dev\gymsystems\client'
  using description file: D:\dev\gymsystems\package.json (relative path: ./client)
    Field 'browser' doesn't contain a valid alias configuration
  after using description file: D:\dev\gymsystems\package.json (relative path: ./client)
    using description file: D:\dev\gymsystems\package.json (relative path: ./client/$$_gendir/app/app.module.ngfactory)
      no extension
        Field 'browser' doesn't contain a valid alias configuration
        D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory doesn't exist
      .ts
        Field 'browser' doesn't contain a valid alias configuration
        D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory.ts doesn't exist
      .js
        Field 'browser' doesn't contain a valid alias configuration
        D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory.js doesn't exist
      as directory
        D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory doesn't exist
[D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory]
[D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory.ts]
[D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory.js]
[D:\dev\gymsystems\client\$$_gendir\app\app.module.ngfactory]
 @ ./client/main.ts 3:0-74
 @ multi ./client/main.ts
error Command failed with exit code 1.

I've found that I can actually use every part of 4.3.4 except @angular/compiler. That still needs to be 4.2.6 in order to workaround this issue.

montella1507 commented 7 years ago

Almost a month with this very important bug without any author reaction :-(

yoricktran commented 7 years ago

Running without the --prod flag at the moment, but could you please fix this until I go into production? :3

aldo-roman commented 7 years ago

Running with --prod but without --aot worked for me:

ng build --prod --aot=false

mindsers commented 7 years ago

@aldo-roman --aot functionality is precisely what we need here...

aldo-roman commented 7 years ago

@Mindsers sorry, I meant, "I can build by disabling just AOT, and not all prod flag"

I do need AOT, too.

chuckjaz commented 7 years ago

If the enum reference is inside a provider useValue or route's data properties, you can work around this by introducing an intermediate exported variable that the template compiler can use instead of inlining the expression.

coryrylan commented 7 years ago

Running into this bug as well. This issue looks like it might be related. We are following the similar pattern of using a enum in the route config. https://github.com/angular/angular/issues/16321

DincaRoberto commented 7 years ago

@chuckjaz Is it possible to get an example of the work around you mentioned in your comment?

michal-filip commented 7 years ago

@DincaRoberto In my case the following kind of change helped (thanks @chuckjaz):

+ export const UiFlag_CONTROL_BOARD_VISIBLE = UiFlag.CONTROL_BOARD_VISIBLE;
const routes: Routes = [
    // ...
   {
         path: 'control-board',
         canActivate: [AuthGuard, FlagGuard],
         data: {
-            flag: UiFlag.CONTROL_BOARD_VISIBLE
+            flag: UiFlag_CONTROL_BOARD_VISIBLE
         }
         // ...
     }
];
chuckjaz commented 7 years ago

@DincaRoberto Something like example provided @michal-filip is what I was referring to.

Vladimex commented 7 years ago

Problem still exists on 4.3.5 when I try to execute: npm run ionic:build --aot

ionic-app-script task: "build"
Error: Illegal state: symbol without members expected, but got {"filePath":".../src/components/name-item/name-item.ts","name":"NameItem","members":["loader"]}.

Any ideas how to fix or when it will be fixed? Without AOT ionic app cannot be published...

chuckjaz commented 7 years ago

The work-around described above should work for this.

piernik commented 7 years ago

@chuckjaz michal-filip's solution didn't work for me.

trotyl commented 7 years ago

Should it be fixed by https://github.com/angular/angular/pull/18905?

chuckjaz commented 7 years ago

@trotyl Yes. In 5 the compiler will "lower" these expressions into exported variables automatically avoiding this issue entirely.

@piernik What exactly did you try?

piernik commented 7 years ago

I updated angular to 5.0.0-beta.5 and cli to 1.3.2

In my config.module I import my own SchematerModule which is responsible for reactive forms. In it I define validators and assing static methods:

SchematerFieldsModule.forRoot({
    //config
    validators:
        {
            unikalnyTytulKrainy: {
                method: CustomValidators.unikalnyTytulKrainy,
                async: true,
                message: 'Taki tytuł już istnieje'
            },
            unikalnyTytulAtrakcje: {
                method: CustomValidators.unikalnyTytulAtrakcji,
                async: true,
                message: 'Taki tytuł już istnieje'
            },
        }
}),

That was my inital code. I changed it to:

export const CustomValidators_unikalnyTytulKrainy = CustomValidators.unikalnyTytulKrainy;
export const CustomValidators_unikalnyTytulAtrakcji = CustomValidators.unikalnyTytulAtrakcji;

...
method: CustomValidators_unikalnyTytulKrainy,
method: CustomValidators_unikalnyTytulAtrakcji,

In both cases the same error: ERROR in Illegal state: symbol without members expected

When I comment in validators part compiler works.

Here are my static methods

export class CustomValidators {
    static unikalnyTytulAtrakcji(fieldControl: FormControl): Observable<any> | Promise<any> {
        const apiService = (this as any).injector.get(ApiService);
        return CustomValidators.unikalnyTytul(fieldControl, 'atrakcje', apiService, this);
    }

    static unikalnyTytulKrainy(fieldControl: FormControl): Observable<any> | Promise<any> {
        const apiService = (this as any).injector.get(ApiService);
        return CustomValidators.unikalnyTytul(fieldControl, 'krainy', apiService, this);
    }

    static unikalnyTytul(fieldControl: FormControl, obiekt: string, apiService: ApiService, self: any): Observable<any> | Promise<any> {
        let id;
        if (fieldControl.root && fieldControl.root.value) {
            const schematerConfig: SchematerObjectsConfigService = self.injector.get(SchematerObjectsConfigService);
            id = fieldControl.root.value[schematerConfig.getObject(obiekt).primaryField];
        }
        return apiService.get('walidacja/tytul-' + obiekt, {tytul: fieldControl.value, bezId: id})
            .map(resp => {
                if (resp.valid) {
                    return null;
                } else {
                    return {unikalnyTytulAtrakcje: true};
                }
            });
    }
}
chuckjaz commented 7 years ago

The work around won't work in this case.

Currently we only treat the fields useValue, useFactory, and data as special. We are planning on adding useClass and animations.

Starting in 5.0.0-beta.6 the compiler will automatically introduce exported variables (in the generated code, not the .d.ts file) to allow the factory to have access to these values.

Given that none of this will help your example, we are going to 1) fix references to enums (this issue) for 5.0.0 final, and 2) investigate if the rewriting should be more general because it would still fail if you used an unrecognized call in this code which also should be allowed.

piernik commented 7 years ago

@chuckjaz Thanks for response.

Can You give me a working solution? Example, article or something?

nerumo commented 7 years ago

tl;dr; I resolved my issue by directly re export the file in the root index.ts instead of the index.ts from the subdir where the file lives.

OysteinAmundsen commented 7 years ago

In my case this error happens on a plain enum. Not sure if the workaround explained above is applicable, or even how I would go about implementing this workaround in my particular case...

export enum Role {
  Admin = 99, Organizer = 90, Secretariat = 80, Club = 50, User = 10
}

export interface IUser  {
  id: number;
  name: string;
  email: string;
  password: string;
  role?: Role;
}

Compiled using --prod flag in angular-cli:

ERROR in Error: Illegal state: symbol without members expected, but got {"filePath":"./client/app/model/IUser.ts","name":"Role","members":["Organizer"]}.

With a dependency to:

"@angular/compiler": "4.2.6",

This compiles fine. > 4.2.6, not so much.

jdrake3 commented 7 years ago

Is this the same as 6443 ?

Sliverb commented 7 years ago

For those that want a workaround till angular 5 rolls around (or this gets fixed). I created a repo with @janousek fix here - https://github.com/Sliverb/angular-compiler.git

I have automated builds set up and this workaround allows things to stay automated till a fix is out

Usage: In package.json use the src above for the compiler. "@angular/compiler": "git+https://github.com/Sliverb/angular-compiler.git",

I'm still trying to understand the reason behind the change and what it does, so if anyone knows. Pls share so we can update our code accordingly.

Thanks guys for leading to this workaround

junglebarry commented 7 years ago

Hi,

I’m vaguely aware that Angular 4 is going to get LTS maintenance. However, the answer for this issue seems to be “wait for v5”.

Are there plans to fix this issue for v4, because if not, many people using standard typescript language features seem like they’ll be unable to access the LTS patches past 4.2.6.

Apologies if I’ve completely misunderstood the advice and workarounds.

Thanks in advance!

NateWarner commented 7 years ago

Just updated to release 4.4.4, which according to the changelog included the fix for this, and the issue is still present when using an enum on a route.

Vladimex commented 7 years ago

Updated to Angular 4.4.4 Error is still there: "Error: Illegal state: symbol without members expected, but got..."

OysteinAmundsen commented 7 years ago

4.4.4 Works on my environment (windows and ubuntu in docker), enums and all!

Me === Happy!

chuckjaz commented 7 years ago

@NateWarner It turns out my fix was incomplete. I fixed some, but not all, of the cases.

If you replace line ~25021 in compiler.umd.js that looks like:

var /** @type {?} */ selectTarget = simplify(expression['expression']);

with:

var /** @type {?} */ selectTarget = simplifyInContext(context, expression['expression'], depth, 0);

It should fix the case you are running into.

chuckjaz commented 7 years ago

@NateWarner Can you verify that the fix above resolves your issue. If it does I will try to get this into 4.4.5.