8

I can't build prod version of my angular app.

And have only this message in IDE console:

ERROR in Cannot assign to a reference or variable!

So I can build only if add these options:

--aot=false --buildOptimizer=false

But, even with these options app fails after deploy with this message in browser console:

ERROR TypeError: Cannot read property 'init' of undefined

which can be fixed by adding one more option:

--optimization=false 

When I try to build with

npm run ng build -- --prod

I have a log file with some information:

0 info it worked if it ends with ok
1 verbose cli [ 'C:\\Backend\\nodejs\\node.exe',
1 verbose cli   'C:\\Users\\USER_NAME\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli   'run',
1 verbose cli   'ng',
1 verbose cli   'build',
1 verbose cli   '--',
1 verbose cli   '--prod' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'preng', 'ng', 'postng' ]
5 info lifecycle [email protected]~preng: [email protected]
6 info lifecycle [email protected]~ng: [email protected]
7 verbose lifecycle [email protected]~ng: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]~ng: PATH: C:\Users\USER_NAME\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin;C:\DEV\WebStormProjects\dont-play-with-gp-web\node_modules\.bin;C:\DEV\WebStormProjects\dont-play-with-gp-web\node_modules\.bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Git\cmd;C:\Backend\IntelliJ IDEA 2018.3.5\jre64;C:\Backend\PostgreSQL\10\bin;C:\Backend\nodejs;C:\Backend\WinSCP\;C:\Android\sdk\platform-tools;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Users\USER_NAME\AppData\Local\Microsoft\WindowsApps;
9 verbose lifecycle [email protected]~ng: CWD: C:\DEV\WebStormProjects\dont-play-with-gp-web
10 silly lifecycle [email protected]~ng: Args: [ '/d /s /c', 'ng "build" "--prod"' ]
11 silly lifecycle [email protected]~ng: Returned: code: 1  signal: null
12 info lifecycle [email protected]~ng: Failed to exec ng script
13 verbose stack Error: [email protected] ng: `ng "build" "--prod"`
13 verbose stack Exit status 1
13 verbose stack     at EventEmitter.<anonymous> (C:\Users\USER_NAME\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\index.js:326:16)
13 verbose stack     at EventEmitter.emit (events.js:189:13)
13 verbose stack     at ChildProcess.<anonymous> (C:\Users\USER_NAME\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
13 verbose stack     at ChildProcess.emit (events.js:189:13)
13 verbose stack     at maybeClose (internal/child_process.js:970:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:259:5)
14 verbose pkgid [email protected]
15 verbose cwd C:\DEV\WebStormProjects\dont-play-with-gp-web
16 verbose Windows_NT 10.0.17134
17 verbose argv "C:\\Backend\\nodejs\\node.exe" "C:\\Users\\USER_NAME\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "run" "ng" "build" "--" "--prod"
18 verbose node v10.15.3
19 verbose npm  v6.10.2
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] ng: `ng "build" "--prod"`
22 error Exit status 1
23 error Failed at the [email protected] ng script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

I tried to update everything, but it doesn't help.

Here is result of ng version:

Angular CLI: 8.3.4
Node: 10.15.3
OS: win32 x64
Angular: 8.2.6
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.4
@angular-devkit/build-angular     0.803.4
@angular-devkit/build-optimizer   0.803.4
@angular-devkit/build-webpack     0.803.4
@angular-devkit/core              8.3.4
@angular-devkit/schematics        8.3.4
@angular/cdk                      8.2.0
@angular/cli                      8.3.4
@angular/flex-layout              8.0.0-beta.27
@angular/material                 8.2.0
@ngtools/webpack                  8.3.4
@schematics/angular               8.3.4
@schematics/update                0.803.4
rxjs                              6.5.3
typescript                        3.5.3
webpack                           4.39.2

And my package.json:

{
  "name": "dont-play-with-gp-web",
  "version": "0.0.2",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^8.2.6",
    "@angular/cdk": "^8.2.0",
    "@angular/common": "~8.2.6",
    "@angular/compiler": "~8.2.6",
    "@angular/core": "~8.2.6",
    "@angular/flex-layout": "8.0.0-beta.27",
    "@angular/forms": "~8.2.6",
    "@angular/material": "^8.2.0",
    "@angular/platform-browser": "~8.2.6",
    "@angular/platform-browser-dynamic": "~8.2.6",
    "@angular/router": "~8.2.6",
    "angular-markdown-editor": "^2.0.2",
    "hammerjs": "^2.0.8",
    "jquery": "^3.4.1",
    "ngx-infinite-scroll": "^8.0.0",
    "ngx-markdown": "^8.1.0",
    "ngx-material-file-input": "^2.0.0",
    "rxjs": "~6.5.3",
    "tslib": "^1.9.0",
    "zone.js": "^0.9.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.803.4",
    "@angular/cli": "~8.3.4",
    "@angular/compiler-cli": "~8.2.6",
    "@angular/language-service": "~8.2.6",
    "@types/jasmine": "~3.4.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/jquery": "^3.3.31",
    "@types/node": "~12.7.5",
    "codelyzer": "^5.0.0",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "~5.4.0",
    "ts-node": "~8.4.1",
    "tslint": "~5.20.0",
    "typescript": "^3.5.3"
  }
}

So, what can I do in this case? How to find a reason for error and how to fix it?

If it can help - there is my source code:

https://bitbucket.org/mohaxspb/gp-web/commits/tag/ATTEMPT_TO_FIX_PROD_BUILD_WITH_DEPS_UPDATE


Same question on ru.stackoverflow: https://ru.stackoverflow.com/questions/1025395


SOVLED:

At last I have error reason (SO user https://stackoverflow.com/users/10123947/shadow found it): there were attempt to change value of variable in template, defined in template with help of self-made directive.

Problem here is in poor error message. Mentioned user received details only via debugging compiler (as I understand). There are some details (in Russian): https://ru.stackoverflow.com/a/1025417/17609

UPDATE:

I add issues and PRs to angular repository to fix it.

  1. No details in error message: issue, PR
  2. Assigning value to template variable crashes prod build: issue, PR

4 Answers 4

26

It happened that most exceptions from the AST parser are a headache. Just because they don't carry anything useful, except for just a message:

ERROR in Cannot assign to a reference or variable!

Oh really?

For example, the linker (ViewBuilder) always writes the place where it cannot build template expressions.

Googling is probably one of the solutions. But the whole circle will be closed on the fact that most answers will offer to check the ngModel directive usage in template.


The second option is a little bit hardcode. It’s worth getting into the compiler itself and debug. Angular uses node_modules/@angular/compiler/bundles/compiler.umd.js during compilation.

Let's open this file and try to search the text Cannot assign to a reference or variable!. We will find the _AstToIrVisitor class and the visitPropertyWrite method. There is such a line of code

// Otherwise it's an error.
throw new Error('Cannot assign to a reference or variable!');

The exception is thrown without any information at all 🤨

Let's add the console.log(ast) before the exception, where ast is the parameter of the visitPropertyWrite function. The parser will log an instance of the PropertyWrite class to the console:

PropertyWrite {
  span: ParseSpan { start: 0, end: 73 },
  receiver: ImplicitReceiver { span: ParseSpan { start: 0, end: 0 } },
  name: 'translation',
  value: MethodCall {
    span: ParseSpan { start: 14, end: 73 },
    receiver: ImplicitReceiver { span: [ParseSpan] },
    name: 'getTranslationForLanguageFromArticle',
    args: [ [PropertyRead], [PropertyRead] ]
  }
}

We came to the conclution that we have to understand that relationship between the translation property and the getTranslationForLanguageFromArticle method call. As I attempted to clone your example from Bitbucket I looked for the "getTranslationForLanguageFromArticle" usage and found this line in the feed.component.html:

(change)="translation = getTranslationForLanguageFromArticle($event.value, article)"

This is what the parser cannot understand as translation is not a class property. It's a local ng-template variable accessed implicitly in the *ngVar directive.

I would create some method like changeTranslation inside the component and do manipulations with article.translations[indexOfCorrectArticleTranslation(article)] there.

At least you know which way to go :)

Sign up to request clarification or add additional context in comments.

4 Comments

I found a way to use my directive and do not ruin prod build. But this needs to edit compiler script here
There is check for type of expression in template if (localExpr instanceof ReadPropExpr) and, if add one more condition || localExpr instanceof ReadVarExpr) everything is OK (prod build succeeded, so as deploy and run in browser). I'll try tomorrow to create pull request to compiler with example. Also there is a way to provide more info in error by adding JSON.stringify(ast) to error message.
This helped us to find some binding mistake, thank you very much for the detailed explanation!
The second options worked well for me. In my case, the problem was a two-way data bind [(property)] without the propertyChange output in the child component.
3

If I may add... I got this error, when I named the template-control the same as a binding property of my class. Like this:

<input type="password" class="form-control" name="passwordConfirmation" #passwordConfirmation="ngModel" [(ngModel)]="passwordConfirmation"/>

"passwordConfirmation" is the name of the control in the template AND the name of the property/variable of the component class. This seems to be confusing for the compiler as it tries to bind to the template variable instead of the class property.

Comments

2

Looks like one of the names of the variable that was giving problem, it's really hard to assume which one is giving the problem and time consuming the debug this for anybody here. I suggest you check all ngIf, ngModel, ngFor, etc... most likely you're trying to use the same name of the variable at someplace in your project.

4 Comments

Thanks for suggestion. I'll try to find something like that. Now I try to remove all component and it helps - prod build succeeded. So I'll try to add components until they break build.
At last I have error reason (SO user stackoverflow.com/users/10123947/shadow found it): there were attempt to change value of variable in template, defined in template with help of self-made directive. Problem here is in poor error message. Mentioned user received details only via debugging compiler (as I understand). There are some details (in Russian): ru.stackoverflow.com/a/1025417/17609
yes, as said I suggest to you just commented out the sections which have ngIf, ngModel, ngFor then try to compile it's a tedious process that reason I don't think anybody can help you here.
Yeah, there are a lot of ng in templates so it's hard to find one, that throws error. But in my case error was in (change). I use self-made directive, which allows to define variable in template and in that (change) I tried to change its value. Something like (change)= "myTemplateVariable = someValue"
0

In my case [(ngValue)] was use instead of [ngValue]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.